|
1 Index: net-snmp/agent/mibgroup/kernel_sunos5.h |
|
2 =================================================================== |
|
3 --- net-snmp/agent/mibgroup/kernel_sunos5.h (revision 16735) |
|
4 +++ net-snmp/agent/mibgroup/kernel_sunos5.h (revision 16736) |
|
5 @@ -193,6 +193,8 @@ |
|
6 int getKstatString(const char *statname, const char *varname, |
|
7 char *value, size_t value_len); |
|
8 |
|
9 + int solaris2_if_nametoindex(const char *, int); |
|
10 + |
|
11 #ifdef _STDC_COMPAT |
|
12 #ifdef __cplusplus |
|
13 } |
|
14 Index: net-snmp/agent/mibgroup/if-mib/data_access/interface_solaris2.c |
|
15 =================================================================== |
|
16 --- net-snmp/agent/mibgroup/if-mib/data_access/interface_solaris2.c (revision 16735) |
|
17 +++ net-snmp/agent/mibgroup/if-mib/data_access/interface_solaris2.c (revision 16736) |
|
18 @@ -14,6 +14,7 @@ |
|
19 #include <sys/ioctl.h> |
|
20 #include <sys/sockio.h> |
|
21 #include <strings.h> |
|
22 +#include <string.h> |
|
23 |
|
24 static int _set_ip_flags_v4(netsnmp_interface_entry *, mib2_ifEntry_t *); |
|
25 static int _match_ifname_v4addr(void *ifname, void *ipaddr); |
|
26 @@ -43,25 +44,7 @@ |
|
27 #if defined(HAVE_IF_NAMETOINDEX) |
|
28 return if_nametoindex(name); |
|
29 #else /* use GIFINDEX */ |
|
30 - int sd; |
|
31 - struct ifreq ifr; |
|
32 - |
|
33 - if (name == 0) { |
|
34 - return (0); |
|
35 - } |
|
36 - |
|
37 - if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { |
|
38 - return (0); |
|
39 - } |
|
40 - |
|
41 - strncpy(ifr.ifr_name, name, IFNAMSIZ); |
|
42 - if (ioctl(sd, SIOCGIFINDEX, (char *) &ifr) < 0) { |
|
43 - close(sd); |
|
44 - return (0); |
|
45 - } |
|
46 - |
|
47 - close(sd); |
|
48 - return (ifr.ifr_index); |
|
49 + return solaris2_if_nametoindex(name, strlen(name)); |
|
50 #endif /* defined(HAVE_IF_NAMETOINDEX) */ |
|
51 } |
|
52 |
|
53 Index: net-snmp/agent/mibgroup/mibII/interfaces.c |
|
54 =================================================================== |
|
55 --- net-snmp/agent/mibgroup/mibII/interfaces.c (revision 16735) |
|
56 +++ net-snmp/agent/mibgroup/mibII/interfaces.c (revision 16736) |
|
57 @@ -2245,71 +2245,7 @@ |
|
58 int |
|
59 Interface_Index_By_Name(char *Name, int Len) |
|
60 { |
|
61 - int i, sd, lastlen = 0, interfaces = 0; |
|
62 - struct ifconf ifc; |
|
63 - struct ifreq *ifrp = NULL; |
|
64 - char *buf = NULL; |
|
65 - |
|
66 - if (Name == 0) { |
|
67 - return 0; |
|
68 - } |
|
69 - if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { |
|
70 - return 0; |
|
71 - } |
|
72 - |
|
73 - /* |
|
74 - * Cope with lots of interfaces and brokenness of ioctl SIOCGIFCONF |
|
75 - * on some platforms; see W. R. Stevens, ``Unix Network Programming |
|
76 - * Volume I'', p.435. |
|
77 - */ |
|
78 - |
|
79 - for (i = 8;; i += 8) { |
|
80 - buf = calloc(i, sizeof(struct ifreq)); |
|
81 - if (buf == NULL) { |
|
82 - close(sd); |
|
83 - return 0; |
|
84 - } |
|
85 - ifc.ifc_len = i * sizeof(struct ifreq); |
|
86 - ifc.ifc_buf = (caddr_t) buf; |
|
87 - |
|
88 - if (ioctl(sd, SIOCGIFCONF, (char *) &ifc) < 0) { |
|
89 - if (errno != EINVAL || lastlen != 0) { |
|
90 - /* |
|
91 - * Something has gone genuinely wrong. |
|
92 - */ |
|
93 - free(buf); |
|
94 - close(sd); |
|
95 - return 0; |
|
96 - } |
|
97 - /* |
|
98 - * Otherwise, it could just be that the buffer is too small. |
|
99 - */ |
|
100 - } else { |
|
101 - if (ifc.ifc_len == lastlen) { |
|
102 - /* |
|
103 - * The length is the same as the last time; we're done. |
|
104 - */ |
|
105 - break; |
|
106 - } |
|
107 - lastlen = ifc.ifc_len; |
|
108 - } |
|
109 - free(buf); |
|
110 - } |
|
111 - |
|
112 - ifrp = ifc.ifc_req; |
|
113 - interfaces = (ifc.ifc_len / sizeof(struct ifreq)) + 1; |
|
114 - |
|
115 - for (i = 1; i < interfaces; i++, ifrp++) { |
|
116 - if (strncmp(ifrp->ifr_name, Name, Len) == 0) { |
|
117 - free(buf); |
|
118 - close(sd); |
|
119 - return i; |
|
120 - } |
|
121 - } |
|
122 - |
|
123 - free(buf); |
|
124 - close(sd); |
|
125 - return 0; |
|
126 + return (solaris2_if_nametoindex(Name, Len)); |
|
127 } |
|
128 |
|
129 #endif /* solaris2 */ |
|
130 Index: net-snmp/agent/mibgroup/kernel_sunos5.c |
|
131 =================================================================== |
|
132 --- net-snmp/agent/mibgroup/kernel_sunos5.c (revision 16735) |
|
133 +++ net-snmp/agent/mibgroup/kernel_sunos5.c (revision 16736) |
|
134 @@ -169,11 +169,14 @@ |
|
135 getif(mib2_ifEntry_t *ifbuf, size_t size, req_e req_type, mib2_ifEntry_t *resp, |
|
136 size_t *length, int (*comp)(void *, void *), void *arg); |
|
137 static void |
|
138 -set_if_info(mib2_ifEntry_t *ifp, unsigned index, char *name, uint64_t flags,int mtu); |
|
139 +set_if_info(mib2_ifEntry_t *ifp, unsigned index, char *name, uint64_t flags, |
|
140 + int mtu); |
|
141 static int get_if_stats(mib2_ifEntry_t *ifp); |
|
142 |
|
143 -static int get_phys_address(mib2_ifEntry_t *ifp); |
|
144 -static int _dlpi_phys_address(int fd, char *paddr, int maxlen, int *paddrlen); |
|
145 +static int _dlpi_open(const char *devname); |
|
146 +static int _dlpi_get_phys_address(int fd, char *paddr, int maxlen, |
|
147 + int *paddrlen); |
|
148 +static int _dlpi_get_iftype(int fd, unsigned int *iftype); |
|
149 static int _dlpi_attach(int fd, int ppa); |
|
150 static int _dlpi_parse_devname(char *devname, int *ppap); |
|
151 |
|
152 @@ -1047,7 +1050,7 @@ |
|
153 mib2_ifEntry_t *resp, size_t *length, int (*comp)(void *, void *), |
|
154 void *arg) |
|
155 { |
|
156 - int i, ret; |
|
157 + int fd, i, ret; |
|
158 int ifsd, ifsd6 = -1; |
|
159 struct lifreq lifreq, *lifrp; |
|
160 mib2_ifEntry_t *ifp; |
|
161 @@ -1109,6 +1112,15 @@ |
|
162 |
|
163 memset(ifp, 0, sizeof(mib2_ifEntry_t)); |
|
164 |
|
165 + if ((fd = _dlpi_open(ifnp->if_name)) != -1) { |
|
166 + /* Could open DLPI... now try to grab some info */ |
|
167 + (void) _dlpi_get_phys_address(fd, ifp->ifPhysAddress.o_bytes, |
|
168 + sizeof(ifp->ifPhysAddress.o_bytes), |
|
169 + &ifp->ifPhysAddress.o_length); |
|
170 + (void) _dlpi_get_iftype(fd, &ifp->ifType); |
|
171 + close(fd); |
|
172 + } |
|
173 + |
|
174 set_if_info(ifp, ifnp->if_index, ifnp->if_name, if_flags, |
|
175 lifrp->lifr_metric); |
|
176 |
|
177 @@ -1117,9 +1129,6 @@ |
|
178 continue; |
|
179 } |
|
180 |
|
181 - /* try to obtain the physical address */ |
|
182 - (void) get_phys_address(ifp); |
|
183 - |
|
184 /* |
|
185 * Once we reach here we know that all went well, so move to |
|
186 * the next ifEntry. |
|
187 @@ -1294,8 +1303,11 @@ |
|
188 #endif /*defined(HAVE_IF_NAMEINDEX)&&defined(NETSNMP_INCLUDE_IFTABLE_REWRITES)*/ |
|
189 |
|
190 static void |
|
191 -set_if_info(mib2_ifEntry_t *ifp, unsigned index, char *name, uint64_t flags, int mtu) |
|
192 +set_if_info(mib2_ifEntry_t *ifp, unsigned index, char *name, uint64_t flags, |
|
193 + int mtu) |
|
194 { |
|
195 + boolean_t havespeed = B_FALSE; |
|
196 + |
|
197 /* |
|
198 * Set basic information |
|
199 */ |
|
200 @@ -1307,101 +1319,122 @@ |
|
201 ifp->ifLastChange = 0; /* Who knows ... */ |
|
202 ifp->flags = flags; |
|
203 ifp->ifMtu = mtu; |
|
204 + ifp->ifSpeed = 0; |
|
205 |
|
206 - /* make ifOperStatus depend on link status if available */ |
|
207 - if (ifp->ifAdminStatus == 1) { |
|
208 - int i_tmp; |
|
209 - /* only UPed interfaces get correct link status - if any */ |
|
210 - if (getKstatInt(NULL, name,"link_up",&i_tmp) == 0) { |
|
211 - ifp->ifOperStatus = i_tmp ? 1 : 2; |
|
212 - } |
|
213 - } |
|
214 - |
|
215 /* |
|
216 - * Set link Type and Speed |
|
217 + * Get link speed |
|
218 */ |
|
219 - ifp->ifType = 1; |
|
220 - ifp->ifSpeed = 0; |
|
221 - |
|
222 - if ((getKstatInt(NULL, name, "ifspeed", &ifp->ifSpeed) == 0) && |
|
223 - (ifp->ifSpeed != 0)) { |
|
224 + if ((getKstatInt(NULL, name, "ifspeed", &ifp->ifSpeed) == 0)) { |
|
225 /* |
|
226 * check for SunOS patch with half implemented ifSpeed |
|
227 */ |
|
228 - if (ifp->ifSpeed < 10000) { |
|
229 + if (ifp->ifSpeed > 0 && ifp->ifSpeed < 10000) { |
|
230 ifp->ifSpeed *= 1000000; |
|
231 } |
|
232 + havespeed = B_TRUE; |
|
233 } else if (getKstatInt(NULL, name, "ifSpeed", &ifp->ifSpeed) == 0) { |
|
234 /* |
|
235 * this is good |
|
236 */ |
|
237 + havespeed = B_TRUE; |
|
238 } |
|
239 |
|
240 - switch (name[0]) { |
|
241 - case 'a': /* ath (802.11) */ |
|
242 - if (name[1] == 't' && name[2] == 'h') |
|
243 - ifp->ifType = 71; |
|
244 - break; |
|
245 - case 'l': /* le / lo / lane (ATM LAN Emulation) */ |
|
246 - if (name[1] == 'o') { |
|
247 - if (!ifp->ifSpeed) |
|
248 - ifp->ifSpeed = 127000000; |
|
249 - ifp->ifType = 24; |
|
250 - } else if (name[1] == 'e') { |
|
251 - if (!ifp->ifSpeed) |
|
252 - ifp->ifSpeed = 10000000; |
|
253 - ifp->ifType = 6; |
|
254 - } else if (name[1] == 'a') { |
|
255 - if (!ifp->ifSpeed) |
|
256 - ifp->ifSpeed = 155000000; |
|
257 - ifp->ifType = 37; |
|
258 - } |
|
259 - break; |
|
260 + /* make ifOperStatus depend on link status if available */ |
|
261 + if (ifp->ifAdminStatus == 1) { |
|
262 + int i_tmp; |
|
263 + /* only UPed interfaces get correct link status - if any */ |
|
264 + if (getKstatInt(NULL, name,"link_up",&i_tmp) == 0) { |
|
265 + ifp->ifOperStatus = i_tmp ? 1 : 2; |
|
266 +#ifdef IFF_FAILED |
|
267 + } else if (flags & IFF_FAILED) { |
|
268 + /* |
|
269 + * If IPMP is used, and if the daemon marks the interface |
|
270 + * as 'failed', then we know for sure something is amiss. |
|
271 + */ |
|
272 + ifp->ifOperStatus = 2; |
|
273 +#endif |
|
274 + } else if (havespeed == B_TRUE && ifp->ifSpeed == 0) { |
|
275 + /* Heuristic */ |
|
276 + ifp->ifOperStatus = 2; |
|
277 + } |
|
278 + } |
|
279 |
|
280 - case 'g': /* ge (gigabit ethernet card) */ |
|
281 - case 'c': /* ce (Cassini Gigabit-Ethernet (PCI) */ |
|
282 - if (!ifp->ifSpeed) |
|
283 - ifp->ifSpeed = 1000000000; |
|
284 - ifp->ifType = 6; |
|
285 - break; |
|
286 - |
|
287 - case 'h': /* hme (SBus card) */ |
|
288 - case 'e': /* eri (PCI card) */ |
|
289 - case 'b': /* be */ |
|
290 - case 'd': /* dmfe -- found on netra X1 */ |
|
291 - if (!ifp->ifSpeed) |
|
292 - ifp->ifSpeed = 100000000; |
|
293 - ifp->ifType = 6; |
|
294 - break; |
|
295 - |
|
296 - case 'f': /* fa (Fore ATM) */ |
|
297 - if (!ifp->ifSpeed) |
|
298 - ifp->ifSpeed = 155000000; |
|
299 - ifp->ifType = 37; |
|
300 - break; |
|
301 - |
|
302 - case 'q': /* qe (QuadEther)/qa (Fore ATM)/qfe (QuadFastEther) */ |
|
303 - if (name[1] == 'a') { |
|
304 - if (!ifp->ifSpeed) |
|
305 - ifp->ifSpeed = 155000000; |
|
306 - ifp->ifType = 37; |
|
307 - } else if (name[1] == 'e') { |
|
308 + /* |
|
309 + * Set link Type and Speed (if it could not be determined from kstat) |
|
310 + */ |
|
311 + if (ifp->ifType == 24) { |
|
312 + ifp->ifSpeed = 127000000; |
|
313 + } else if (ifp->ifType == 1 || ifp->ifType == 0) { |
|
314 + /* |
|
315 + * Could not get the type from DLPI, so lets fall back to the hardcoded |
|
316 + * values. |
|
317 + */ |
|
318 + switch (name[0]) { |
|
319 + case 'a': /* ath (802.11) */ |
|
320 + if (name[1] == 't' && name[2] == 'h') |
|
321 + ifp->ifType = 71; |
|
322 + break; |
|
323 + case 'l': /* le / lo / lane (ATM LAN Emulation) */ |
|
324 + if (name[1] == 'o') { |
|
325 if (!ifp->ifSpeed) |
|
326 + ifp->ifSpeed = 127000000; |
|
327 + ifp->ifType = 24; |
|
328 + } else if (name[1] == 'e') { |
|
329 + if (!ifp->ifSpeed) |
|
330 ifp->ifSpeed = 10000000; |
|
331 ifp->ifType = 6; |
|
332 - } else if (name[1] == 'f') { |
|
333 + } else if (name[1] == 'a') { |
|
334 if (!ifp->ifSpeed) |
|
335 - ifp->ifSpeed = 100000000; |
|
336 + ifp->ifSpeed = 155000000; |
|
337 + ifp->ifType = 37; |
|
338 + } |
|
339 + break; |
|
340 + |
|
341 + case 'g': /* ge (gigabit ethernet card) */ |
|
342 + case 'c': /* ce (Cassini Gigabit-Ethernet (PCI) */ |
|
343 + if (!ifp->ifSpeed) |
|
344 + ifp->ifSpeed = 1000000000; |
|
345 ifp->ifType = 6; |
|
346 + break; |
|
347 + |
|
348 + case 'h': /* hme (SBus card) */ |
|
349 + case 'e': /* eri (PCI card) */ |
|
350 + case 'b': /* be */ |
|
351 + case 'd': /* dmfe -- found on netra X1 */ |
|
352 + if (!ifp->ifSpeed) |
|
353 + ifp->ifSpeed = 100000000; |
|
354 + ifp->ifType = 6; |
|
355 + break; |
|
356 + |
|
357 + case 'f': /* fa (Fore ATM) */ |
|
358 + if (!ifp->ifSpeed) |
|
359 + ifp->ifSpeed = 155000000; |
|
360 + ifp->ifType = 37; |
|
361 + break; |
|
362 + |
|
363 + case 'q': /* qe (QuadEther)/qa (Fore ATM)/qfe (QuadFastEther) */ |
|
364 + if (name[1] == 'a') { |
|
365 + if (!ifp->ifSpeed) |
|
366 + ifp->ifSpeed = 155000000; |
|
367 + ifp->ifType = 37; |
|
368 + } else if (name[1] == 'e') { |
|
369 + if (!ifp->ifSpeed) |
|
370 + ifp->ifSpeed = 10000000; |
|
371 + ifp->ifType = 6; |
|
372 + } else if (name[1] == 'f') { |
|
373 + if (!ifp->ifSpeed) |
|
374 + ifp->ifSpeed = 100000000; |
|
375 + ifp->ifType = 6; |
|
376 + } |
|
377 + break; |
|
378 + |
|
379 + case 'i': /* ibd (Infiniband)/ip.tun (IP tunnel) */ |
|
380 + if (name[1] == 'b') |
|
381 + ifp->ifType = 199; |
|
382 + else if (name[1] == 'p') |
|
383 + ifp->ifType = 131; |
|
384 + break; |
|
385 } |
|
386 - break; |
|
387 - |
|
388 - case 'i': /* ibd (Infiniband)/ip.tun (IP tunnel) */ |
|
389 - if (name[1] == 'b') |
|
390 - ifp->ifType = 199; |
|
391 - else if (name[1] == 'p') |
|
392 - ifp->ifType = 131; |
|
393 - break; |
|
394 } |
|
395 } |
|
396 |
|
397 @@ -1491,68 +1524,69 @@ |
|
398 } |
|
399 |
|
400 /* |
|
401 - * Obtain the physical address using DLPI. Pieces of this code is directly |
|
402 - * taken from libdlpi, which unfortunately is not yet commonly available. |
|
403 + * Open a DLPI device. |
|
404 + * |
|
405 + * On success the file descriptor is returned. |
|
406 + * On error -1 is returned. |
|
407 */ |
|
408 - |
|
409 -static int |
|
410 -get_phys_address(mib2_ifEntry_t *ifp) |
|
411 +static int |
|
412 +_dlpi_open(const char *devname) |
|
413 { |
|
414 - char *devstr; |
|
415 - int fd; |
|
416 - int ppa = -1; |
|
417 - int rc = -1; |
|
418 + char *devstr; |
|
419 + int fd = -1; |
|
420 + int ppa = -1; |
|
421 |
|
422 - DEBUGMSGTL(("kernel_sunos5", "get_phys_address called\n")); |
|
423 + DEBUGMSGTL(("kernel_sunos5", "_dlpi_open called\n")); |
|
424 |
|
425 - if ((devstr = malloc(5 + ifp->ifDescr.o_length + 1)) == NULL) |
|
426 + if (devname == NULL) |
|
427 return (-1); |
|
428 - (void) sprintf(devstr, "/dev/%s", ifp->ifDescr.o_bytes); |
|
429 + |
|
430 + if ((devstr = malloc(5 + strlen(devname) + 1)) == NULL) |
|
431 + return (-1); |
|
432 + (void) sprintf(devstr, "/dev/%s", devname); |
|
433 DEBUGMSGTL(("kernel_sunos5:dlpi", "devstr(%s)\n", devstr)); |
|
434 /* |
|
435 * First try opening the device using style 1, if the device does not |
|
436 * exist we try style 2. Modules will not be pushed, so something like |
|
437 * ip tunnels will not work. |
|
438 */ |
|
439 - if ((fd = open(devstr, O_RDWR | O_NONBLOCK)) != -1) { |
|
440 - DEBUGMSGTL(("kernel_sunos5:dlpi", "style1 open(%s)\n", devstr)); |
|
441 - rc = _dlpi_phys_address(fd, ifp->ifPhysAddress.o_bytes, |
|
442 - sizeof(ifp->ifPhysAddress.o_bytes), |
|
443 - &ifp->ifPhysAddress.o_length); |
|
444 - } else if (_dlpi_parse_devname(devstr, &ppa) == 0) { |
|
445 - DEBUGMSGTL(("kernel_sunos5:dlpi", "style2 parse: %s, %d\n", |
|
446 - devstr, ppa)); |
|
447 - /* try style 2 */ |
|
448 - if ((fd = open(devstr, O_RDWR | O_NONBLOCK)) != -1) { |
|
449 - DEBUGMSGTL(("kernel_sunos5:dlpi", "style2 open(%s)\n", devstr)); |
|
450 - if (_dlpi_attach(fd, ppa) == 0) { |
|
451 - DEBUGMSGTL(("kernel_sunos5:dlpi", "attached\n")); |
|
452 - rc = _dlpi_phys_address(fd, ifp->ifPhysAddress.o_bytes, |
|
453 - sizeof(ifp->ifPhysAddress.o_bytes), |
|
454 - &ifp->ifPhysAddress.o_length); |
|
455 - } |
|
456 - } |
|
457 - } |
|
458 + |
|
459 + DEBUGMSGTL(("kernel_sunos5:dlpi", "style1 open(%s)\n", devstr)); |
|
460 + if ((fd = open(devstr, O_RDWR | O_NONBLOCK)) < 0) { |
|
461 + DEBUGMSGTL(("kernel_sunos5:dlpi", "style1 open failed\n")); |
|
462 + if (_dlpi_parse_devname(devstr, &ppa) == 0) { |
|
463 + DEBUGMSGTL(("kernel_sunos5:dlpi", "style2 parse: %s, %d\n", |
|
464 + devstr, ppa)); |
|
465 + /* try style 2 */ |
|
466 + DEBUGMSGTL(("kernel_sunos5:dlpi", "style2 open(%s)\n", devstr)); |
|
467 |
|
468 - free(devstr); |
|
469 - if (fd != -1) |
|
470 - close(fd); |
|
471 + if ((fd = open(devstr, O_RDWR | O_NONBLOCK)) != -1) { |
|
472 + if (_dlpi_attach(fd, ppa) == 0) { |
|
473 + DEBUGMSGTL(("kernel_sunos5:dlpi", "attached\n")); |
|
474 + } else { |
|
475 + DEBUGMSGTL(("kernel_sunos5:dlpi", "attached failed\n")); |
|
476 + close(fd); |
|
477 + fd = -1; |
|
478 + } |
|
479 + } else { |
|
480 + DEBUGMSGTL(("kernel_sunos5:dlpi", "style2 open failed\n")); |
|
481 + } |
|
482 + } |
|
483 + } else { |
|
484 + DEBUGMSGTL(("kernel_sunos5:dlpi", "style1 open succeeded\n")); |
|
485 + } |
|
486 |
|
487 - if (rc == 0) { |
|
488 - /* successful */ |
|
489 - DEBUGMSGTL(("kernel_sunos5:dlpi", "got phys addr using DLPI\n")); |
|
490 - return (0); |
|
491 - } else { |
|
492 - DEBUGMSGTL(("kernel_sunos5:dlpi", "unable to get phys address\n")); |
|
493 - return (-1); |
|
494 - } |
|
495 + /* clean up */ |
|
496 + free(devstr); |
|
497 + |
|
498 + return (fd); |
|
499 } |
|
500 |
|
501 /* |
|
502 - * |
|
503 + * Obtain the physical address of the interface using DLPI |
|
504 */ |
|
505 static int |
|
506 -_dlpi_phys_address(int fd, char *addr, int maxlen, int *addrlen) |
|
507 +_dlpi_get_phys_address(int fd, char *addr, int maxlen, int *addrlen) |
|
508 { |
|
509 dl_phys_addr_req_t paddr_req; |
|
510 union DL_primitives *dlp; |
|
511 @@ -1560,6 +1594,8 @@ |
|
512 char buf[MAX(DL_PHYS_ADDR_ACK_SIZE+64, DL_ERROR_ACK_SIZE)]; |
|
513 int flag = 0; |
|
514 |
|
515 + DEBUGMSGTL(("kernel_sunos5:dlpi", "_dlpi_get_phys_address\n")); |
|
516 + |
|
517 paddr_req.dl_primitive = DL_PHYS_ADDR_REQ; |
|
518 paddr_req.dl_addr_type = DL_CURR_PHYS_ADDR; |
|
519 ctlbuf.buf = (char *)&paddr_req; |
|
520 @@ -1570,7 +1606,7 @@ |
|
521 ctlbuf.maxlen = sizeof(buf); |
|
522 ctlbuf.len = 0; |
|
523 ctlbuf.buf = buf; |
|
524 - if (getmsg(fd, &ctlbuf, NULL, &flag) != 0) |
|
525 + if (getmsg(fd, &ctlbuf, NULL, &flag) < 0) |
|
526 return (-1); |
|
527 |
|
528 if (ctlbuf.len < sizeof(uint32_t)) |
|
529 @@ -1580,6 +1616,7 @@ |
|
530 case DL_PHYS_ADDR_ACK: { |
|
531 dl_phys_addr_ack_t *phyp = (dl_phys_addr_ack_t *)buf; |
|
532 |
|
533 + DEBUGMSGTL(("kernel_sunos5:dlpi", "got ACK\n")); |
|
534 if (ctlbuf.len < DL_PHYS_ADDR_ACK_SIZE || phyp->dl_addr_length > maxlen) |
|
535 return (-1); |
|
536 (void) memcpy(addr, buf+phyp->dl_addr_offset, phyp->dl_addr_length); |
|
537 @@ -1589,16 +1626,137 @@ |
|
538 case DL_ERROR_ACK: { |
|
539 dl_error_ack_t *errp = (dl_error_ack_t *)buf; |
|
540 |
|
541 + DEBUGMSGTL(("kernel_sunos5:dlpi", "got ERROR ACK\n")); |
|
542 if (ctlbuf.len < DL_ERROR_ACK_SIZE) |
|
543 return (-1); |
|
544 return (errp->dl_errno); |
|
545 } |
|
546 default: |
|
547 + DEBUGMSGTL(("kernel_sunos5:dlpi", "got type: %x\n", dlp->dl_primitive)); |
|
548 return (-1); |
|
549 } |
|
550 } |
|
551 |
|
552 +/* |
|
553 + * Query the interface about it's type. |
|
554 + */ |
|
555 static int |
|
556 +_dlpi_get_iftype(int fd, unsigned int *iftype) |
|
557 +{ |
|
558 + dl_info_req_t info_req; |
|
559 + union DL_primitives *dlp; |
|
560 + struct strbuf ctlbuf; |
|
561 + char buf[MAX(DL_INFO_ACK_SIZE, DL_ERROR_ACK_SIZE)]; |
|
562 + int flag = 0; |
|
563 + |
|
564 + DEBUGMSGTL(("kernel_sunos5:dlpi", "_dlpi_get_iftype\n")); |
|
565 + |
|
566 + info_req.dl_primitive = DL_INFO_REQ; |
|
567 + ctlbuf.buf = (char *)&info_req; |
|
568 + ctlbuf.len = DL_INFO_REQ_SIZE; |
|
569 + if (putmsg(fd, &ctlbuf, NULL, 0) < 0) { |
|
570 + DEBUGMSGTL(("kernel_sunos5:dlpi", "putmsg failed: %d\nn", errno)); |
|
571 + return (-1); |
|
572 + } |
|
573 + |
|
574 + ctlbuf.maxlen = sizeof(buf); |
|
575 + ctlbuf.len = 0; |
|
576 + ctlbuf.buf = buf; |
|
577 + if (getmsg(fd, &ctlbuf, NULL, &flag) < 0) { |
|
578 + DEBUGMSGTL(("kernel_sunos5:dlpi", "getmsg failed: %d\n", errno)); |
|
579 + return (-1); |
|
580 + } |
|
581 + |
|
582 + if (ctlbuf.len < sizeof(uint32_t)) |
|
583 + return (-1); |
|
584 + dlp = (union DL_primitives *)buf; |
|
585 + switch (dlp->dl_primitive) { |
|
586 + case DL_INFO_ACK: { |
|
587 + dl_info_ack_t *info = (dl_info_ack_t *)buf; |
|
588 + |
|
589 + if (ctlbuf.len < DL_INFO_ACK_SIZE) |
|
590 + return (-1); |
|
591 + |
|
592 + DEBUGMSGTL(("kernel_sunos5:dlpi", "dl_mac_type: %x\n", |
|
593 + info->dl_mac_type)); |
|
594 + switch (info->dl_mac_type) { |
|
595 + case DL_CSMACD: |
|
596 + case DL_ETHER: |
|
597 + case DL_ETH_CSMA: |
|
598 + *iftype = 6; |
|
599 + break; |
|
600 + case DL_TPB: /* Token Passing Bus */ |
|
601 + *iftype = 8; |
|
602 + break; |
|
603 + case DL_TPR: /* Token Passing Ring */ |
|
604 + *iftype = 9; |
|
605 + break; |
|
606 + case DL_HDLC: |
|
607 + *iftype = 118; |
|
608 + break; |
|
609 + case DL_FDDI: |
|
610 + *iftype = 15; |
|
611 + break; |
|
612 + case DL_FC: /* Fibre channel */ |
|
613 + *iftype = 56; |
|
614 + break; |
|
615 + case DL_ATM: |
|
616 + *iftype = 37; |
|
617 + break; |
|
618 + case DL_X25: |
|
619 + case DL_ISDN: |
|
620 + *iftype = 63; |
|
621 + break; |
|
622 + case DL_HIPPI: |
|
623 + *iftype = 47; |
|
624 + break; |
|
625 +#ifdef DL_IB |
|
626 + case DL_IB: |
|
627 + *iftype = 199; |
|
628 + break; |
|
629 +#endif |
|
630 + case DL_FRAME: /* Frame Relay */ |
|
631 + *iftype = 32; |
|
632 + break; |
|
633 + case DL_LOOP: |
|
634 + *iftype = 24; |
|
635 + break; |
|
636 +#ifdef DL_WIFI |
|
637 + case DL_WIFI: |
|
638 + *iftype = 71; |
|
639 + break; |
|
640 +#endif |
|
641 +#ifdef DL_IPV4 /* then IPv6 is also defined */ |
|
642 + case DL_IPV4: /* IPv4 Tunnel */ |
|
643 + case DL_IPV6: /* IPv6 Tunnel */ |
|
644 + *iftype = 131; |
|
645 + break; |
|
646 +#endif |
|
647 + default: |
|
648 + *iftype = 1; /* Other */ |
|
649 + break; |
|
650 + } |
|
651 + |
|
652 + return (0); |
|
653 + } |
|
654 + case DL_ERROR_ACK: { |
|
655 + dl_error_ack_t *errp = (dl_error_ack_t *)buf; |
|
656 + |
|
657 + DEBUGMSGTL(("kernel_sunos5:dlpi", |
|
658 + "got DL_ERROR_ACK: dlpi %d, error %d\n", errp->dl_errno, |
|
659 + errp->dl_unix_errno)); |
|
660 + |
|
661 + if (ctlbuf.len < DL_ERROR_ACK_SIZE) |
|
662 + return (-1); |
|
663 + return (errp->dl_errno); |
|
664 + } |
|
665 + default: |
|
666 + DEBUGMSGTL(("kernel_sunos5:dlpi", "got type %x\n", dlp->dl_primitive)); |
|
667 + return (-1); |
|
668 + } |
|
669 +} |
|
670 + |
|
671 +static int |
|
672 _dlpi_attach(int fd, int ppa) |
|
673 { |
|
674 dl_attach_req_t attach_req; |
|
675 @@ -1680,8 +1838,83 @@ |
|
676 } else { |
|
677 return 1; |
|
678 } |
|
679 -} |
|
680 +} |
|
681 |
|
682 +/* |
|
683 + * Try to determine the index of a particular interface. If mfd-rewrites is |
|
684 + * specified, then this function would only be used when the system does not |
|
685 + * have if_nametoindex(3SOCKET). |
|
686 + */ |
|
687 +int |
|
688 +solaris2_if_nametoindex(const char *Name, int Len) |
|
689 +{ |
|
690 + int i, sd, lastlen = 0, interfaces = 0; |
|
691 + struct ifconf ifc; |
|
692 + struct ifreq *ifrp = NULL; |
|
693 + char *buf = NULL; |
|
694 + |
|
695 + if (Name == 0) { |
|
696 + return 0; |
|
697 + } |
|
698 + if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { |
|
699 + return 0; |
|
700 + } |
|
701 + |
|
702 + /* |
|
703 + * Cope with lots of interfaces and brokenness of ioctl SIOCGIFCONF |
|
704 + * on some platforms; see W. R. Stevens, ``Unix Network Programming |
|
705 + * Volume I'', p.435. |
|
706 + */ |
|
707 + |
|
708 + for (i = 8;; i += 8) { |
|
709 + buf = calloc(i, sizeof(struct ifreq)); |
|
710 + if (buf == NULL) { |
|
711 + close(sd); |
|
712 + return 0; |
|
713 + } |
|
714 + ifc.ifc_len = i * sizeof(struct ifreq); |
|
715 + ifc.ifc_buf = (caddr_t) buf; |
|
716 + |
|
717 + if (ioctl(sd, SIOCGIFCONF, (char *) &ifc) < 0) { |
|
718 + if (errno != EINVAL || lastlen != 0) { |
|
719 + /* |
|
720 + * Something has gone genuinely wrong. |
|
721 + */ |
|
722 + free(buf); |
|
723 + close(sd); |
|
724 + return 0; |
|
725 + } |
|
726 + /* |
|
727 + * Otherwise, it could just be that the buffer is too small. |
|
728 + */ |
|
729 + } else { |
|
730 + if (ifc.ifc_len == lastlen) { |
|
731 + /* |
|
732 + * The length is the same as the last time; we're done. |
|
733 + */ |
|
734 + break; |
|
735 + } |
|
736 + lastlen = ifc.ifc_len; |
|
737 + } |
|
738 + free(buf); |
|
739 + } |
|
740 + |
|
741 + ifrp = ifc.ifc_req; |
|
742 + interfaces = (ifc.ifc_len / sizeof(struct ifreq)) + 1; |
|
743 + |
|
744 + for (i = 1; i < interfaces; i++, ifrp++) { |
|
745 + if (strncmp(ifrp->ifr_name, Name, Len) == 0) { |
|
746 + free(buf); |
|
747 + close(sd); |
|
748 + return i; |
|
749 + } |
|
750 + } |
|
751 + |
|
752 + free(buf); |
|
753 + close(sd); |
|
754 + return 0; |
|
755 +} |
|
756 + |
|
757 #ifdef _STDC_COMPAT |
|
758 #ifdef __cplusplus |
|
759 } |