| @@ -1,305 +1,305 @@ | | | @@ -1,305 +1,305 @@ |
1 | /* $NetBSD: pf-linux2.c,v 1.1 2016/06/08 01:11:49 christos Exp $ */ | | 1 | /* $NetBSD: pf-linux2.c,v 1.2 2020/10/27 17:07:14 abs Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * General Purpose AppleTalk Packet Filter Interface | | 4 | * General Purpose AppleTalk Packet Filter Interface |
5 | * | | 5 | * |
6 | * Copyright (c) 1992-1995, The University of Melbourne. | | 6 | * Copyright (c) 1992-1995, The University of Melbourne. |
7 | * All Rights Reserved. Permission to redistribute or | | 7 | * All Rights Reserved. Permission to redistribute or |
8 | * use any part of this software for any purpose must | | 8 | * use any part of this software for any purpose must |
9 | * be obtained in writing from the copyright owner. | | 9 | * be obtained in writing from the copyright owner. |
10 | * | | 10 | * |
11 | * This software is supplied "as is" without express | | 11 | * This software is supplied "as is" without express |
12 | * or implied warranty. | | 12 | * or implied warranty. |
13 | * | | 13 | * |
14 | * djh@munnari.OZ.AU | | 14 | * djh@munnari.OZ.AU |
15 | * | | 15 | * |
16 | * Supports: | | 16 | * Supports: |
17 | * Linux SOCK_PACKET | | 17 | * Linux SOCK_PACKET |
18 | * | | 18 | * |
19 | * | | 19 | * |
20 | * Modified for use with the linux-mopd port by Karl Maftoum | | 20 | * Modified for use with the linux-mopd port by Karl Maftoum |
21 | * u963870@student.canberra.edu.au | | 21 | * u963870@student.canberra.edu.au |
22 | * | | 22 | * |
23 | */ | | 23 | */ |
24 | | | 24 | |
25 | #include "port.h" | | 25 | #include "port.h" |
26 | __RCSID("$NetBSD: pf-linux2.c,v 1.1 2016/06/08 01:11:49 christos Exp $"); | | 26 | __RCSID("$NetBSD: pf-linux2.c,v 1.2 2020/10/27 17:07:14 abs Exp $"); |
27 | | | 27 | |
28 | /* | | 28 | /* |
29 | * include header files | | 29 | * include header files |
30 | * | | 30 | * |
31 | */ | | 31 | */ |
32 | | | 32 | |
33 | #include <stdio.h> | | 33 | #include <stdio.h> |
34 | #include <fcntl.h> | | 34 | #include <fcntl.h> |
35 | #include <unistd.h> | | 35 | #include <unistd.h> |
36 | #include <sys/types.h> | | 36 | #include <sys/types.h> |
37 | #include <sys/time.h> | | 37 | #include <sys/time.h> |
38 | #include <sys/ioctl.h> | | 38 | #include <sys/ioctl.h> |
39 | #include <sys/file.h> | | 39 | #include <sys/file.h> |
40 | #include <sys/socket.h> | | 40 | #include <sys/socket.h> |
41 | #include <net/if.h> | | 41 | #include <net/if.h> |
42 | #include <sys/errno.h> | | 42 | #include <sys/errno.h> |
43 | #include <linux/if_ether.h> | | 43 | #include <linux/if_ether.h> |
44 | #include <netdb.h> | | 44 | #include <netdb.h> |
45 | #include <ctype.h> | | 45 | #include <ctype.h> |
46 | #include <string.h> | | 46 | #include <string.h> |
47 | | | 47 | |
48 | #define MOPDEF_SUPRESS_EXTERN | | 48 | #define MOPDEF_SUPRESS_EXTERN |
49 | #include "mopdef.h" | | 49 | #include "mopdef.h" |
50 | | | 50 | |
51 | /* | | 51 | /* |
52 | * definitions | | 52 | * definitions |
53 | * | | 53 | * |
54 | */ | | 54 | */ |
55 | | | 55 | |
56 | #define READBUFSIZ 4096 | | 56 | #define READBUFSIZ 4096 |
57 | #define NUMRDS 32 | | 57 | #define NUMRDS 32 |
58 | | | 58 | |
59 | struct RDS { | | 59 | struct RDS { |
60 | u_short dataLen; | | 60 | u_short dataLen; |
61 | u_char *dataPtr; | | 61 | u_char *dataPtr; |
62 | }; | | 62 | }; |
63 | | | 63 | |
64 | /* | | 64 | /* |
65 | * variables | | 65 | * variables |
66 | * | | 66 | * |
67 | */ | | 67 | */ |
68 | | | 68 | |
69 | struct socklist { | | 69 | struct socklist { |
70 | int iflen; | | 70 | int iflen; |
71 | struct sockaddr sa; | | 71 | struct sockaddr sa; |
72 | } socklist[32]; | | 72 | } socklist[32]; |
73 | | | 73 | |
74 | struct ifreq ifr; | | 74 | struct ifreq ifr; |
75 | extern int errno; | | 75 | extern int errno; |
76 | extern int promisc; | | 76 | extern int promisc; |
77 | | | 77 | |
78 | struct RDS RDS[NUMRDS]; | | 78 | struct RDS RDS[NUMRDS]; |
79 | static int setup_pf(int, int, u_short); | | 79 | static int setup_pf(int, int, u_short); |
80 | | | 80 | |
81 | /* | | 81 | /* |
82 | * Open and initialize packet filter | | 82 | * Open and initialize packet filter |
83 | * for a particular protocol type. | | 83 | * for a particular protocol type. |
84 | * | | 84 | * |
85 | */ | | 85 | */ |
86 | | | 86 | |
87 | | | 87 | |
88 | int | | 88 | int |
89 | pfInit(char *interface, u_short protocol, int typ, int mode) | | 89 | pfInit(char *interface, int mode, u_short protocol, int typ) |
90 | { | | 90 | { |
91 | int s; | | 91 | int s; |
92 | int ioarg; | | 92 | int ioarg; |
93 | char device[64]; | | 93 | char device[64]; |
94 | unsigned long if_flags; | | 94 | unsigned long if_flags; |
95 | | | 95 | |
96 | | | 96 | |
97 | { u_short prot; | | 97 | { u_short prot; |
98 | | | 98 | |
99 | prot = ((typ == TRANS_8023) ? htons(ETH_P_802_2) : htons(protocol)); | | 99 | prot = ((typ == TRANS_8023) ? htons(ETH_P_802_2) : htons(protocol)); |
100 | if ((s = socket(AF_INET, SOCK_PACKET, prot)) < 0) { | | 100 | if ((s = socket(AF_INET, SOCK_PACKET, prot)) < 0) { |
101 | perror(interface); | | 101 | perror(interface); |
102 | return(-1); | | 102 | return(-1); |
103 | } | | 103 | } |
104 | if (s >= 32) { | | 104 | if (s >= 32) { |
105 | close(s); | | 105 | close(s); |
106 | return(-1); | | 106 | return(-1); |
107 | } | | 107 | } |
108 | } | | 108 | } |
109 | | | 109 | |
110 | /* | | 110 | /* |
111 | * set filter for protocol and type (IPTalk, Phase 1/2) | | 111 | * set filter for protocol and type (IPTalk, Phase 1/2) |
112 | * | | 112 | * |
113 | */ | | 113 | */ |
114 | | | 114 | |
115 | if (setup_pf(s, protocol, typ) < 0) | | 115 | if (setup_pf(s, protocol, typ) < 0) |
116 | return(-1); | | 116 | return(-1); |
117 | | | 117 | |
118 | /* | | 118 | /* |
119 | * set options, bind to underlying interface | | 119 | * set options, bind to underlying interface |
120 | * | | 120 | * |
121 | */ | | 121 | */ |
122 | | | 122 | |
123 | strncpy(ifr.ifr_name, interface, sizeof(ifr.ifr_name)); | | 123 | strncpy(ifr.ifr_name, interface, sizeof(ifr.ifr_name)); |
124 | | | 124 | |
125 | /* record socket interface name and length */ | | 125 | /* record socket interface name and length */ |
126 | strncpy(socklist[s].sa.sa_data, interface, sizeof(socklist[s].sa.sa_data)); | | 126 | strncpy(socklist[s].sa.sa_data, interface, sizeof(socklist[s].sa.sa_data)); |
127 | socklist[s].iflen = strlen(interface); | | 127 | socklist[s].iflen = strlen(interface); |
128 | | | 128 | |
129 | return(s); | | 129 | return(s); |
130 | } | | 130 | } |
131 | | | 131 | |
132 | /* | | 132 | /* |
133 | * establish protocol filter | | 133 | * establish protocol filter |
134 | * | | 134 | * |
135 | */ | | 135 | */ |
136 | | | 136 | |
137 | static int | | 137 | static int |
138 | setup_pf(int s, int typ, u_short prot) | | 138 | setup_pf(int s, int typ, u_short prot) |
139 | { | | 139 | { |
140 | int ioarg; | | 140 | int ioarg; |
141 | u_short offset; | | 141 | u_short offset; |
142 | return(0); | | 142 | return(0); |
143 | } | | 143 | } |
144 | | | 144 | |
145 | /* | | 145 | /* |
146 | * get the interface ethernet address | | 146 | * get the interface ethernet address |
147 | * | | 147 | * |
148 | */ | | 148 | */ |
149 | | | 149 | |
150 | int | | 150 | int |
151 | pfEthAddr(int s, char *interface, u_char *addr) | | 151 | pfEthAddr(int s, char *interface, u_char *addr) |
152 | { | | 152 | { |
153 | strncpy(ifr.ifr_name, interface, sizeof (ifr.ifr_name) -1); | | 153 | strncpy(ifr.ifr_name, interface, sizeof (ifr.ifr_name) -1); |
154 | ifr.ifr_name[sizeof(ifr.ifr_name)] = 0; | | 154 | ifr.ifr_name[sizeof(ifr.ifr_name)] = 0; |
155 | ifr.ifr_addr.sa_family = AF_INET; | | 155 | ifr.ifr_addr.sa_family = AF_INET; |
156 | if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) { | | 156 | if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) { |
157 | perror("SIOCGIFHWADDR"); | | 157 | perror("SIOCGIFHWADDR"); |
158 | return(-1); | | 158 | return(-1); |
159 | } | | 159 | } |
160 | memcpy((char *)addr, ifr.ifr_hwaddr.sa_data, 6); | | 160 | memcpy((char *)addr, ifr.ifr_hwaddr.sa_data, 6); |
161 | return(0); | | 161 | return(0); |
162 | } | | 162 | } |
163 | | | 163 | |
164 | /* | | 164 | /* |
165 | * add a multicast address to the interface | | 165 | * add a multicast address to the interface |
166 | * | | 166 | * |
167 | */ | | 167 | */ |
168 | | | 168 | |
169 | int | | 169 | int |
170 | pfAddMulti(int s, char *interface, u_char *addr) | | 170 | pfAddMulti(int s, char *interface, u_char *addr) |
171 | { | | 171 | { |
172 | int sock; | | 172 | int sock; |
173 | | | 173 | |
174 | strncpy(ifr.ifr_name, interface, sizeof (ifr.ifr_name) - 1); | | 174 | strncpy(ifr.ifr_name, interface, sizeof (ifr.ifr_name) - 1); |
175 | ifr.ifr_name[sizeof(ifr.ifr_name)] = 0; | | 175 | ifr.ifr_name[sizeof(ifr.ifr_name)] = 0; |
176 | | | 176 | |
177 | ifr.ifr_addr.sa_family = AF_UNSPEC; | | 177 | ifr.ifr_addr.sa_family = AF_UNSPEC; |
178 | bcopy((char *)addr, ifr.ifr_addr.sa_data, 6); | | 178 | bcopy((char *)addr, ifr.ifr_addr.sa_data, 6); |
179 | | | 179 | |
180 | /* | | 180 | /* |
181 | * open a socket, temporarily, to use for SIOC* ioctls | | 181 | * open a socket, temporarily, to use for SIOC* ioctls |
182 | * | | 182 | * |
183 | */ | | 183 | */ |
184 | if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { | | 184 | if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { |
185 | perror("socket()"); | | 185 | perror("socket()"); |
186 | return(-1); | | 186 | return(-1); |
187 | } | | 187 | } |
188 | if (ioctl(sock, SIOCADDMULTI, (caddr_t)&ifr) < 0) { | | 188 | if (ioctl(sock, SIOCADDMULTI, (caddr_t)&ifr) < 0) { |
189 | perror("SIOCADDMULTI"); | | 189 | perror("SIOCADDMULTI"); |
190 | close(sock); | | 190 | close(sock); |
191 | return(-1); | | 191 | return(-1); |
192 | } | | 192 | } |
193 | close(sock); | | 193 | close(sock); |
194 | | | 194 | |
195 | return(0); | | 195 | return(0); |
196 | } | | 196 | } |
197 | | | 197 | |
198 | /* | | 198 | /* |
199 | * delete a multicast address from the interface | | 199 | * delete a multicast address from the interface |
200 | * | | 200 | * |
201 | */ | | 201 | */ |
202 | | | 202 | |
203 | int | | 203 | int |
204 | pfDelMulti(int s, char *interface, u_char *addr) | | 204 | pfDelMulti(int s, char *interface, u_char *addr) |
205 | { | | 205 | { |
206 | int sock; | | 206 | int sock; |
207 | | | 207 | |
208 | strncpy(ifr.ifr_name, interface, sizeof (ifr.ifr_name) - 1); | | 208 | strncpy(ifr.ifr_name, interface, sizeof (ifr.ifr_name) - 1); |
209 | ifr.ifr_name[sizeof(ifr.ifr_name)] = 0; | | 209 | ifr.ifr_name[sizeof(ifr.ifr_name)] = 0; |
210 | | | 210 | |
211 | ifr.ifr_addr.sa_family = AF_UNSPEC; | | 211 | ifr.ifr_addr.sa_family = AF_UNSPEC; |
212 | bcopy((char *)addr, ifr.ifr_addr.sa_data, 6); | | 212 | bcopy((char *)addr, ifr.ifr_addr.sa_data, 6); |
213 | | | 213 | |
214 | /* | | 214 | /* |
215 | * open a socket, temporarily, to use for SIOC* ioctls | | 215 | * open a socket, temporarily, to use for SIOC* ioctls |
216 | * | | 216 | * |
217 | */ | | 217 | */ |
218 | if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { | | 218 | if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { |
219 | perror("socket()"); | | 219 | perror("socket()"); |
220 | return(-1); | | 220 | return(-1); |
221 | } | | 221 | } |
222 | if (ioctl(sock, SIOCDELMULTI, (caddr_t)&ifr) < 0) { | | 222 | if (ioctl(sock, SIOCDELMULTI, (caddr_t)&ifr) < 0) { |
223 | perror("SIOCDELMULTI"); | | 223 | perror("SIOCDELMULTI"); |
224 | close(sock); | | 224 | close(sock); |
225 | return(-1); | | 225 | return(-1); |
226 | } | | 226 | } |
227 | close(sock); | | 227 | close(sock); |
228 | | | 228 | |
229 | return(0); | | 229 | return(0); |
230 | } | | 230 | } |
231 | | | 231 | |
232 | /* | | 232 | /* |
233 | * return 1 if ethernet interface capable of multiple opens | | 233 | * return 1 if ethernet interface capable of multiple opens |
234 | * | | 234 | * |
235 | */ | | 235 | */ |
236 | | | 236 | |
237 | int | | 237 | int |
238 | eth_mopen(int phase) | | 238 | eth_mopen(int phase) |
239 | { | | 239 | { |
240 | if (phase == 2) | | 240 | if (phase == 2) |
241 | return(0); | | 241 | return(0); |
242 | return(1); | | 242 | return(1); |
243 | } | | 243 | } |
244 | | | 244 | |
245 | /* | | 245 | /* |
246 | * read a packet | | 246 | * read a packet |
247 | * Read Data Structure describes packet(s) received | | 247 | * Read Data Structure describes packet(s) received |
248 | * | | 248 | * |
249 | */ | | 249 | */ |
250 | | | 250 | |
251 | | | 251 | |
252 | | | 252 | |
253 | | | 253 | |
254 | int | | 254 | int |
255 | pfRead(int fd, u_char *buf, int len) | | 255 | pfRead(int fd, u_char *buf, int len) |
256 | { | | 256 | { |
257 | int i, cc; | | 257 | int i, cc; |
258 | | | 258 | |
259 | int fromlen; | | 259 | int fromlen; |
260 | struct sockaddr sa; | | 260 | struct sockaddr sa; |
261 | | | 261 | |
262 | RDS[0].dataLen = 0; | | 262 | RDS[0].dataLen = 0; |
263 | fromlen = sizeof(struct sockaddr); | | 263 | fromlen = sizeof(struct sockaddr); |
264 | | | 264 | |
265 | if ((cc = recvfrom(fd, (char *)buf, len, 0, &sa, &fromlen)) <= 0) | | 265 | if ((cc = recvfrom(fd, (char *)buf, len, 0, &sa, &fromlen)) <= 0) |
266 | return(cc); | | 266 | return(cc); |
267 | | | 267 | |
268 | /* check if from right interface */ | | 268 | /* check if from right interface */ |
269 | for (i = socklist[fd].iflen-1; i >= 0; i--) | | 269 | for (i = socklist[fd].iflen-1; i >= 0; i--) |
270 | if (sa.sa_data[i] != socklist[fd].sa.sa_data[i]) | | 270 | if (sa.sa_data[i] != socklist[fd].sa.sa_data[i]) |
271 | return(0); | | 271 | return(0); |
272 | | | 272 | |
273 | RDS[0].dataLen = cc; | | 273 | RDS[0].dataLen = cc; |
274 | RDS[0].dataPtr = buf; | | 274 | RDS[0].dataPtr = buf; |
275 | RDS[1].dataLen = 0; | | 275 | RDS[1].dataLen = 0; |
276 | | | 276 | |
277 | return(cc); | | 277 | return(cc); |
278 | } | | 278 | } |
279 | | | 279 | |
280 | /* | | 280 | /* |
281 | * write a packet | | 281 | * write a packet |
282 | * | | 282 | * |
283 | */ | | 283 | */ |
284 | | | 284 | |
285 | int | | 285 | int |
286 | pfWrite(int fd, u_char *buf, int len) | | 286 | pfWrite(int fd, u_char *buf, int len) |
287 | { | | 287 | { |
288 | | | 288 | |
289 | if (sendto(fd, buf, len, 0, &socklist[fd].sa, sizeof(struct sockaddr)) == len) | | 289 | if (sendto(fd, buf, len, 0, &socklist[fd].sa, sizeof(struct sockaddr)) == len) |
290 | return(len); | | 290 | return(len); |
291 | | | 291 | |
292 | return(-1); | | 292 | return(-1); |
293 | } | | 293 | } |
294 | | | 294 | |
295 | /* | | 295 | /* |
296 | * Return information to device.c how to open device. | | 296 | * Return information to device.c how to open device. |
297 | * In this case the driver can handle both Ethernet type II and | | 297 | * In this case the driver can handle both Ethernet type II and |
298 | * IEEE 802.3 frames (SNAP) in a single pfOpen. | | 298 | * IEEE 802.3 frames (SNAP) in a single pfOpen. |
299 | */ | | 299 | */ |
300 | | | 300 | |
301 | int | | 301 | int |
302 | pfTrans(char *interface) | | 302 | pfTrans(char *interface) |
303 | { | | 303 | { |
304 | return TRANS_ETHER+TRANS_8023; | | 304 | return TRANS_ETHER+TRANS_8023; |
305 | } | | 305 | } |