]> git.pld-linux.org Git - packages/gated.git/blame - gated-3.5.9-krt_ifread_ioctl.c
- dropped pre-cvs changelog
[packages/gated.git] / gated-3.5.9-krt_ifread_ioctl.c
CommitLineData
f5da5f84
JR
1/*
2 * Public Release 3
3 *
4 * $Id$
5 */
6
7/*
8 * ------------------------------------------------------------------------
9 *
10 * Copyright (c) 1996, 1997 The Regents of the University of Michigan
11 * All Rights Reserved
12 *
13 * Royalty-free licenses to redistribute GateD Release
14 * 3 in whole or in part may be obtained by writing to:
15 *
16 * Merit GateDaemon Project
17 * 4251 Plymouth Road, Suite C
18 * Ann Arbor, MI 48105
19 *
20 * THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
21 * EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION WARRANTIES OF
22 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE REGENTS OF THE
23 * UNIVERSITY OF MICHIGAN AND MERIT DO NOT WARRANT THAT THE
24 * FUNCTIONS CONTAINED IN THE SOFTWARE WILL MEET LICENSEE'S REQUIREMENTS OR
25 * THAT OPERATION WILL BE UNINTERRUPTED OR ERROR FREE. The Regents of the
26 * University of Michigan and Merit shall not be liable for
27 * any special, indirect, incidental or consequential damages with respect
28 * to any claim by Licensee or any third party arising from use of the
29 * software. GateDaemon was originated and developed through release 3.0
30 * by Cornell University and its collaborators.
31 *
32 * Please forward bug fixes, enhancements and questions to the
33 * gated mailing list: gated-people@gated.merit.edu.
34 *
35 * ------------------------------------------------------------------------
36 *
37 * Copyright (c) 1990,1991,1992,1993,1994,1995 by Cornell University.
38 * All rights reserved.
39 *
40 * THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY
41 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
42 * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY
43 * AND FITNESS FOR A PARTICULAR PURPOSE.
44 *
45 * GateD is based on Kirton's EGP, UC Berkeley's routing
46 * daemon (routed), and DCN's HELLO routing Protocol.
47 * Development of GateD has been supported in part by the
48 * National Science Foundation.
49 *
50 * ------------------------------------------------------------------------
51 *
52 * Portions of this software may fall under the following
53 * copyrights:
54 *
55 * Copyright (c) 1988 Regents of the University of California.
56 * All rights reserved.
57 *
58 * Redistribution and use in source and binary forms are
59 * permitted provided that the above copyright notice and
60 * this paragraph are duplicated in all such forms and that
61 * any documentation, advertising materials, and other
62 * materials related to such distribution and use
63 * acknowledge that the software was developed by the
64 * University of California, Berkeley. The name of the
65 * University may not be used to endorse or promote
66 * products derived from this software without specific
67 * prior written permission. THIS SOFTWARE IS PROVIDED
68 * ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
69 * INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
70 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
71 */
72
73
74#define INCLUDE_IOCTL
75#define INCLUDE_IF
76#define INCLUDE_ISO_VAR
77#include "include.h"
78#ifdef PROTO_INET
79#include "inet.h"
80#endif /* PROTO_INET */
81#ifdef PROTO_ISO
82#include "iso.h"
83#endif /* PROTO_ISO */
84#include "krt.h"
85#include "krt_var.h"
86
87
88#if IFNAMSIZ > IFL_NAMELEN
89error - IFL_NAMELEN not compatible with IFNAMESIZ
90#endif
91
92/* Make some assumptions about interface MTU */
93static inline mtu_t
94krt_mtu __PF1(state, flag_t)
95{
96 switch (BIT_TEST(state, IFS_POINTOPOINT|IFS_LOOPBACK|IFS_BROADCAST)) {
97 case IFS_POINTOPOINT:
98 /* Compressed SLIP interfaces use 256, it can't really hurt to specify it */
99 /* too low. */
100 return 256;
101
102 case IFS_LOOPBACK:
103 /* Loopback interfaces use more */
104 return 1536;
105
106 case IFS_BROADCAST:
107 /* Assume an Ethernet */
108 return 1500;
109 }
110
111 /* A safe assumption? */
112 return 576;
113}
114
115
116int
117krt_ifread __PF1(save_task_state, flag_t)
118{
119 u_int indx = 0;
120 caddr_t limit;
121 struct ifreq *ifrp;
122 if_link *ifl = (if_link *) 0;
123#ifdef PROTO_ISO
124 static struct iso_ifreq iso_ifreq;
125 static struct ifreq *ifr = (struct ifreq *) &iso_ifreq;
126#else /* PROTO_ISO */
127 static struct ifreq ifreq;
128 static struct ifreq *ifr = &ifreq;
129#endif /* PROTO_ISO */
130 register task *tp = krt_task;
131 static int s_in = -1;
132#ifdef ISOPROTO_RAW
133 static int s_iso = -1;
134#endif /* ISOPROTO_RAW */
135
136 if (tp->task_socket < 0) {
137 return EBADF;
138 }
139
140 if (!task_send_buffer) {
141 /* We need a send buffer */
142
143 task_alloc_send(tp, task_pagesize);
144 }
145
146 do {
147 int rc;
148 size_t size;
149
150#if defined(USE_STREAMIO) && !defined(SUNOS5_0)
151 struct strioctl si;
152
153 si.ic_cmd = SIOCGIFCONF;
154 si.ic_timout = 0;
155 si.ic_len = task_send_buffer_len;
156 si.ic_dp = (caddr_t) task_send_buffer;
157
158 NON_INTR(rc, ioctl(tp->task_socket, I_STR, &si));
159
160 limit = si.ic_dp + (size = si.ic_len);
161
162#else /* defined(USE_STREAMIO) && !defined(SUNOS5_0) */
163 static struct ifconf ifconf_req;
164
165 ifconf_req.ifc_buf = (caddr_t) task_send_buffer;
166 ifconf_req.ifc_len = task_send_buffer_len;
167
168#if defined(SUNOS5_0) || defined(HPSTREAMS)
169 NON_INTR(rc, ioctl(tp->task_socket,
170 SIOCGIFCONF,
171 &ifconf_req));
172#else /* SUNOS5_0 || HPSTREAMS */
173 rc = task_ioctl(tp->task_socket,
174 (u_long) SIOCGIFCONF,
175 (void_t) &ifconf_req,
176 ifconf_req.ifc_len);
177#endif /* SUNOS5_0 || HPSTREAMS */
178
179 limit = ifconf_req.ifc_buf + (size = ifconf_req.ifc_len);
180
181#endif /* defined(USE_STREAMIO) && !defined(SUNOS5_0) */
182 if (rc != 0) {
183 /* Something is wrong */
184
185 if (errno == EFAULT) {
186 /* Hopefully this means that the buffer is not big enough */
187
188 continue;
189 }
190
191 trace_log_tp(tp,
192 0,
193 LOG_ERR,
194 ("krt_ifread: ioctl SIOCGIFCONF: %m"));
195 return errno;
196 } else if (size
197 && task_send_buffer_len - size > sizeof *ifr) {
198 /* It appears we have read the complete list */
199
200 break;
201 }
202 } while (task_alloc_send(tp, task_send_buffer_len << 1), TRUE) ;
203
204 trace_tp(tp,
205 TR_KRT_IFLIST,
206 TRC_NL_BEFORE,
207 ("krt_iflist: SIOCGIFCONF returns %u bytes",
208 limit - (caddr_t) task_send_buffer));
209
210 /* Tell the IF code that we are passing complete knowledge */
211 if_conf_open(tp, TRUE);
212
213#define ifr_size(x) ((unix_socksize(&(x)->ifr_addr) > sizeof((x)->ifr_addr)) ? \
214 sizeof(*(x)) + unix_socksize(&(x)->ifr_addr) - sizeof((x)->ifr_addr) : sizeof(*(x)))
215#define ifr_bump(x) ((struct ifreq *) ((void_t) ((caddr_t) (x) + ifr_size(x))))
216
217 for (ifrp = (struct ifreq *) task_send_buffer;
218 (caddr_t) ifrp < limit;
219 ifrp = ifr_bump(ifrp)) {
220 if_info ifi;
221 int s = -1;
222 u_long siocgifdstaddr = 0;
223#ifdef SIOCGIFNETMASK
224 u_long siocgifnetmask = 0;
225#endif /* SIOCGIFNETMASK */
226 u_long siocgifbrdaddr = 0;
227 char if_name[IFNAMSIZ+1];
228
229 if (TRACE_TP(tp, TR_KRT_IFLIST)) {
230 int size = unix_socksize(&ifrp->ifr_addr);
231 const char *cp = trace_value(task_domain_bits, ifrp->ifr_addr.sa_family);
232
233 tracef("krt_ifread: name %.*s length %u family %u",
234 IFNAMSIZ, ifrp->ifr_name,
235 size,
236 ifrp->ifr_addr.sa_family);
237 if (cp) {
238 tracef("(%s)",
239 cp);
240 }
241
242 switch (ifrp->ifr_addr.sa_family) {
243#ifdef PROTO_INET
244 case AF_INET:
245 {
246 struct sockaddr_in *sinp = (struct sockaddr_in *) ((void_t) &ifrp->ifr_addr);
247
248 tracef(" port %u addr %A",
249 ntohs(sinp->sin_port),
250 sockbuild_in(0, sinp->sin_addr.s_addr));
251 }
252 break;
253#endif /* PROTO_INET */
254
255#ifdef PROTO_ISO
256 case AF_ISO:
257 {
258 struct sockaddr_iso *siso = (struct sockaddr_iso *) &ifrp->ifr_addr;
259 byte *dp = (byte *) siso->siso_pad;
260
261 tracef(" addr %A",
262 siso->siso_addr.isoa_genaddr,
263 siso->siso_addr.isoa_len);
264
265 if (siso->siso_plen) {
266 tracef(" psel %A",
267 sockbuild_ll(0, dp, siso->siso_plen));
268 dp += siso->siso_plen;
269 }
270 if (siso->siso_slen) {
271 tracef(" ssel %A",
272 sockbuild_ll(0, dp, siso->siso_slen));
273 dp += siso->siso_slen;
274 }
275 if (siso->siso_tlen) {
276 tracef(" tsel %A",
277 sockbuild_ll(0, dp, siso->siso_tlen));
278 }
279 }
280 break;
281#endif /* PROTO_ISO */
282
283#ifdef SOCKADDR_DL
284 case AF_LINK:
285 {
286 struct sockaddr_dl *sdl = (struct sockaddr_dl *) &ifrp->ifr_addr;
287 byte *dp = (byte *) sdl->sdl_data;
288
289 tracef(" index %u type %u",
290 sdl->sdl_index,
291 sdl->sdl_type);
292 if (sdl->sdl_nlen) {
293 tracef(" name %.*s",
294 sdl->sdl_nlen, dp);
295 dp += sdl->sdl_nlen;
296 }
297 if (sdl->sdl_alen) {
298 tracef(" addr %A",
299 sockbuild_ll(0, dp, sdl->sdl_alen));
300 dp += sdl->sdl_alen;
301 }
302 if (sdl->sdl_slen) {
303 tracef(" selector %A",
304 sockbuild_ll(0, dp, sdl->sdl_slen));
305 }
306 }
307 break;
308#endif /* SOCKADDR_DL */
309
310 default:
311 tracef(" addr %A",
312 sockbuild_ll(0,
313 (byte *) ifrp->ifr_addr.sa_data,
314 (size_t) (size - ((byte *) ifrp->ifr_addr.sa_data - (byte *) &ifrp->ifr_addr))));
315 }
316 trace_only_tp(tp,
317 TRC_NL_BEFORE,
318 (NULL));
319 }
320
321 bzero((caddr_t) &ifi, sizeof (ifi));
322
323 bcopy(ifrp->ifr_name, if_name, IFNAMSIZ);
324 if_name[IFNAMSIZ] = (char) 0;
325#if defined(SUNOS5_0) || defined(HPSTREAMS)
326 {
327 register char *cp = index(if_name, ':');
328
329 /* Remove the :n extension from the name */
330 if (cp) {
331 *cp = (char) 0;
332 }
333 }
334#endif /* SUNOS5_0 || HPSTREAMS */
335
336 if (!ifl
337 || strncmp(if_name, ifl->ifl_name, IFNAMSIZ)) {
338 flag_t state;
339 metric_t metric;
340 mtu_t mtu;
341
342 /* And save for ioctls */
343 (void) strncpy(ifr->ifr_name, ifrp->ifr_name, IFNAMSIZ);
344
345#if defined(SUNOS5_0) || defined(HPSTREAMS)
346 /* State, MTU and metric are associated with addresses, not the interface */
347 state = mtu = metric = 0;
348
349#else /* SUNOS5_0 || HPSTREAMS */
350 /* Get interface flags */
351 bzero ((caddr_t) &ifr->ifr_ifru, sizeof (ifr->ifr_ifru));
352 if (task_ioctl(tp->task_socket,
353 (u_long) SIOCGIFFLAGS,
354 (char *) ifr,
355 sizeof (*ifr)) < 0) {
356 trace_log_tp(tp,
357 0,
358 LOG_ERR,
359 ("krt_ifread: %s: ioctl SIOCGIFFLAGS: %m",
360 ifr->ifr_name));
361 goto Continue;
362 }
363 state = krt_if_flags(ifr->ifr_flags);
364
365 /* Get a resonable default */
366 mtu = krt_mtu(state);
367
368#ifdef SIOCGIFMTU
369 /* Get interface MTU */
370 bzero ((caddr_t) &ifr->ifr_ifru, sizeof (ifr->ifr_ifru));
371 if (task_ioctl(tp->task_socket,
372 (u_long) SIOCGIFMTU,
373 (char *) ifr,
374 sizeof (*ifr)) < 0) {
375#ifdef notdef
376 trace_tp(tp,
377 TR_ALL,
378 ("krt_ifread: %s: ioctl SIOCGIFMTU: %m",
379 ifr->ifr_name));
380#endif /* notdef */
381 } else {
382 mtu = ifr->KRT_IFR_MTU;
383 }
384#endif /* SIOCGIFMTU */
385
386 /* Get interface metric */
387#if defined(SIOCGIFMETRIC) && defined(ifr_metric)
388 bzero ((caddr_t) &ifr->ifr_ifru, sizeof (ifr->ifr_ifru));
389 if (task_ioctl(tp->task_socket,
390 (u_long) SIOCGIFMETRIC,
391 (caddr_t)
392 ifr,
393 sizeof (*ifr)) < 0) {
394 trace_log_tp(tp,
395 0,
396 LOG_ERR,
397 ("krt_ifread: %s: ioctl SIOCGIFMETRIC: %m",
398 ifr->ifr_name));
399 goto Continue;
400 }
401 metric = (ifr->ifr_metric >= 0) ? ifr->ifr_metric : 0;
402#else /* defined(SIOCGIFMETRIC) && defined(ifr_metric) */
403 metric = 0;
404#endif /* defined(SIOCGIFMETRIC) && defined(ifr_metric) */
405#endif /* SUNOS5_0 || HPSTREAMS */
406
407
408 {
409#ifdef SOCKADDR_DL
410 register struct ifreq *ifrl = ifrp;
411
412 /* Search for an AF_LINK entry because it has */
413 /* the index and sometimes the physical address. */
414 /* On ``normal'' systems this is the first address, */
415 /* but on DEC OSF/1 systems the AF_LINK has been */
416 /* observed not to be. */
417 for (ifrl = ifrp;
418 (caddr_t) ifrl < limit;
419 ifrl = ifr_bump(ifrl)) {
420 if (strncmp(ifrl->ifr_name, ifrp->ifr_name, IFNAMSIZ)) {
421 /* Did not find one in the records for this interface */
422
423 ifrl = (struct ifreq *) 0;
424 break;
425 }
426
427 if (ifrl->ifr_addr.sa_family == AF_LINK) {
428 /* Found the AF_LINK entry */
429
430 break;
431 }
432 }
433
434 if (ifrl && ((caddr_t) ifrl < limit)) {
435 struct sockaddr_dl *sdl = (struct sockaddr_dl *) &ifrl->ifr_addr;
436 sockaddr_un *lladdr;
437
438 if (sdl->sdl_alen) {
439 /* We have an address */
440
441 lladdr = sockbuild_ll(krt_type_to_ll(sdl->sdl_type),
442 (byte *) (sdl->sdl_data + sdl->sdl_nlen),
443 (size_t) sdl->sdl_alen);
444 } else {
445 /* This system may not supply link-level addresses, */
446 /* or this interface may not have one. Just to be sure */
447 /* try to look one up */
448
449 lladdr = krt_lladdr(ifr);
450 }
451
452 ifl = ifl_addup(tp,
453 ifl_locate_index(sdl->sdl_index),
454 (indx = sdl->sdl_index),
455 state,
456 metric,
457 mtu,
458 sdl->sdl_data,
459 (size_t) sdl->sdl_nlen,
460 lladdr);
461 } else {
462#endif /* SOCKADDR_DL */
463 size_t n_len = strlen(if_name);
464
465 ifl = ifl_addup(tp,
466 ifl_locate_name(if_name, n_len),
467 ++indx,
468 state,
469 metric,
470 mtu,
471 if_name,
472 n_len,
473 krt_lladdr(ifr));
474 }
475#ifdef SOCKADDR_DL
476 }
477#endif /* SOCKADDR_DL */
478
479 if (TRACE_TP(tp, TR_KRT_IFLIST)) {
480 trace_only_tp(tp,
481 0,
482 ("krt_ifread: %s index %d address %A",
483 ifl->ifl_name,
484 ifl->ifl_index,
485 ifl->ifl_addr));
486 trace_only_tp(tp,
487 0,
488 ("krt_ifread: %s metric %u mtu %u state <%s>",
489 ifl->ifl_name,
490 ifl->ifl_metric,
491 ifl->ifl_mtu,
492 trace_bits(if_state_bits, ifl->ifl_state)));
493 }
494#if defined(SUNOS5_0) || defined(HPSTREAMS)
495 } else {
496 /* Always copy the interface name to get address selector */
497
498 (void) strncpy(ifr->ifr_name, ifrp->ifr_name, IFNAMSIZ);
499#endif /* SUNOS5_0 || HPSTREAMS */
500 }
501
502 bzero((caddr_t) &ifi, sizeof (ifi));
503 ifi.ifi_link = ifl;
504
505 /* Reject unknown families */
506 switch (ifrp->ifr_addr.sa_family) {
507#ifdef PROTO_INET
508 case AF_INET:
509 break;
510#endif /* PROTO_INET */
511
512#ifdef PROTO_ISO
513 case AF_ISO:
514 break;
515#endif /* PROTO_ISO */
516
517 default:
518 /* Bogus address */
519 goto Continue;
520 }
521
522 /* Copy the interface address */
523 ifi.ifi_addr_local = ifi.ifi_addr = sockdup(sock2gated(&ifrp->ifr_addr, unix_socksize(&ifrp->ifr_addr)));
524
525#if defined(SUNOS5_0) || defined(HPSTREAMS)
526 /* Get interface flags */
527 bzero ((caddr_t) &ifr->ifr_ifru, sizeof (ifr->ifr_ifru));
528 if (task_ioctl(tp->task_socket,
529 (u_long) SIOCGIFFLAGS,
530 (char *) ifr,
531 sizeof (*ifr)) < 0) {
532 trace_log_tp(tp,
533 0,
534 LOG_ERR,
535 ("krt_ifread: %s: ioctl SIOCGIFFLAGS: %m",
536 ifr->ifr_name));
537 goto Continue;
538 }
539 ifi.ifi_state = krt_if_flags(ifr->ifr_flags);
540 if (BIT_TEST(ifi.ifi_state, IFS_LOOPBACK)) {
541 /* Indicate this is a loopback interface */
542
543 BIT_SET(ifl->ifl_state, IFS_LOOPBACK);
544 }
545
546 /* Get interface MTU */
547 bzero ((caddr_t) &ifr->ifr_ifru, sizeof (ifr->ifr_ifru));
548 if (task_ioctl(tp->task_socket,
549 (u_long) SIOCGIFMTU,
550 (char *) ifr,
551 sizeof (*ifr)) < 0) {
552#ifdef notdef
553 trace_log_tp(tp,
554 0,
555 LOG_INFO,
556 ("krt_ifread: %s: ioctl SIOCGIFMTU: %m",
557 ifr->ifr_name));
558#endif /* notdef */
559
560 /* Figure out a default */
561 ifi.ifi_mtu = krt_mtu(ifi.ifi_state);
562 } else {
563 ifi.ifi_mtu = ifr->KRT_IFR_MTU;
564 }
565
566 /* Get interface metric */
567 bzero ((caddr_t) &ifr->ifr_ifru, sizeof (ifr->ifr_ifru));
568 if (task_ioctl(tp->task_socket,
569 (u_long) SIOCGIFMETRIC,
570 (caddr_t) ifr,
571 sizeof (*ifr)) < 0) {
572 trace_log_tp(tp,
573 0,
574 LOG_ERR,
575 ("krt_ifread: %s: ioctl SIOCGIFMETRIC: %m",
576 ifr->ifr_name));
577 goto Continue;
578 }
579 ifi.ifi_metric = (ifr->ifr_metric >= 0) ? ifr->ifr_metric : 0;
580#else /* SUNOS5_0 || HPSTREAMS */
581 /* Inherit parameters from physical interface */
582
583 ifi.ifi_state = ifl->ifl_state;
584 ifi.ifi_metric = ifl->ifl_metric;
585 ifi.ifi_mtu = ifl->ifl_mtu;
586#endif /* SUNOS5_0 || HPSTREAMS */
587
588 /* What we do next depends on the family */
589 switch (ifrp->ifr_addr.sa_family) {
590#ifdef PROTO_INET
591 case AF_INET:
592 /* Specify the right socket for this family */
593 if (s_in < 0) {
594 BIT_RESET(task_state, TASKS_INIT|TASKS_TEST);
595 s_in = task_floating_socket(tp,
596 task_get_socket(tp, PF_INET, SOCK_DGRAM, 0),
597 "ifread.inet");
598 task_state = save_task_state;
599 }
600 s = s_in;
601 if (BIT_TEST(ifi.ifi_state, IFS_POINTOPOINT)) {
602 siocgifdstaddr = (u_long) SIOCGIFDSTADDR;
603 }
604#ifdef SIOCGIFNETMASK
605 if (!BIT_TEST(ifi.ifi_state, IFS_LOOPBACK)) {
606 siocgifnetmask = (u_long) SIOCGIFNETMASK;
607#endif /* SIOCGIFNETMASK */
608 }
609 if (BIT_TEST(ifi.ifi_state, IFS_BROADCAST)) {
610 siocgifbrdaddr = (u_long) SIOCGIFBRDADDR;
611 }
612 break;
613#endif /* PROTO_INET */
614
615#ifdef PROTO_ISO
616 case AF_ISO:
617 /* Specify the right socket for this family */
618 if (s_iso < 0) {
619 BIT_RESET(task_state, TASKS_INIT|TASKS_TEST);
620 s_iso = task_floating_socket(tp,
621 task_get_socket(tp, PF_ISO, SOCK_DGRAM, 0),
622 "ifread.iso");
623 task_state = save_task_state;
624 }
625 s = s_iso;
626 if (BIT_TEST(ifi.ifi_state, IFS_POINTOPOINT)) {
627 siocgifdstaddr = SIOCGIFDSTADDR_ISO;
628 } else if (!BIT_TEST(ifi.ifi_state, IFS_LOOPBACK)) {
629 siocgifnetmask = SIOCGIFNETMASK_ISO;
630 }
631 break;
632#endif /* PROTO_ISO */
633
634 default:
635 goto Continue;
636 }
637
638 if (siocgifdstaddr) {
639 /* Get the destination address for point-to-point interfaces */
640
641 size_t a_len;
642
643 bzero ((caddr_t) &ifr->ifr_ifru, sizeof (ifr->ifr_ifru));
644 if (task_ioctl(s,
645 siocgifdstaddr,
646 (caddr_t) ifr,
647 sizeof (*ifr)) < 0) {
648 trace_log_tp(tp,
649 0,
650 LOG_ERR,
651 ("krt_ifread: %s: ioctl SIOCGIFDSTADDR: %m",
652 ifr->ifr_name));
653 goto Continue;
654 }
655 if ((a_len = unix_socksize(&ifr->ifr_dstaddr))
656 && (ifi.ifi_addr = sock2gated(&ifr->ifr_dstaddr, a_len))) {
657 ifi.ifi_addr = sockdup(ifi.ifi_addr);
658 } else {
659 ifi.ifi_addr = (sockaddr_un *) 0;
660 }
661 }
662#ifdef SIOCGIFNETMASK
663 if (siocgifnetmask) {
664 bzero ((caddr_t) &ifr->ifr_ifru, sizeof (ifr->ifr_ifru));
665 if (task_ioctl(s,
666 siocgifnetmask,
667 (caddr_t) ifr,
668 sizeof (*ifr)) < 0) {
669 trace_log_tp(tp,
670 0,
671 LOG_ERR,
672 ("krt_ifread: %s: ioctl SIOCGIFNETMASK: %m",
673 ifr->ifr_name));
674 goto Continue;
675 }
676#ifdef SOCKET_LENGTHS
677 /* A zero mask would have a length of zero */
678 if (ifr->ifr_addr.sa_len < 2) {
679 ifr->ifr_addr.sa_len = 2; /* Enough for address and family */
680 }
681 /* Masks don't have an address family specified */
682 if (ifr->ifr_addr.sa_family == AF_UNSPEC
683 && ifi.ifi_addr) {
684 ifr->ifr_addr.sa_family = socktype(ifi.ifi_addr);
685 }
686#endif /* SOCKET_LENGTHS */
687 /* Convert the mask */
688 ifi.ifi_netmask = sock2gated(&ifr->ifr_addr, unix_socksize(&ifr->ifr_addr));
689
690 if (ifi.ifi_netmask) {
691 /* We have a mask, get pointer to right one */
692 ifi.ifi_netmask = mask_locate(ifi.ifi_netmask);
693 }
694 }
695#else /* SIOCGIFNETMASK */
696 ifi.ifi_netmask = (sockaddr_un *) 0;
697#endif /* SIOCGIFNETMASK */
698
699 /* Get the broadcast address for broadcast interfaces */
700 if (siocgifbrdaddr) {
701#ifdef SIOCGIFBRDADDR
702/* Some systems (SunOS 3.x where x > 2) do not define ifr_broadaddr */
703#ifndef ifr_broadaddr
704#define ifr_broadaddr ifr_addr
705#endif /* ifr_broadaddr */
706 bzero ((caddr_t) &ifr->ifr_ifru, sizeof (ifr->ifr_ifru));
707 if (task_ioctl(s,
708 siocgifbrdaddr,
709 (caddr_t) ifr,
710 sizeof (*ifr)) < 0) {
711 trace_log_tp(tp,
712 0,
713 LOG_ERR,
714 ("krt_ifread: %s: ioctl SIOGIFBRDADDR: %m",
715 ifr->ifr_name));
716 goto Continue;
717 }
718 ifi.ifi_addr_broadcast = sock2gated(&ifr->ifr_broadaddr, unix_socksize(&ifr->ifr_broadaddr));
719 if (ifi.ifi_addr_broadcast) {
720 ifi.ifi_addr_broadcast = sockdup(ifi.ifi_addr_broadcast);
721 } else {
722 trace_log_tp(tp,
723 0,
724 LOG_ERR,
725 ("krt_ifread: no broadcast address for %A (%s)",
726 ifi.ifi_addr_local,
727 ifrp->ifr_name));
728 goto Continue;
729 }
730#else /* !SIOCGIFBRDADDR */
731 /* Assume a 4.2 based system with a zeros broadcast */
732 ifi.ifi_addr_broadcast = (sockaddr_un *) 0;
733#endif /* SIOCGIFBRDADDR */
734 }
735
736 if (TRACE_TP(tp, TR_KRT_IFLIST)) {
737 tracef("krt_ifread: %s %A",
738 ifl->ifl_name,
739 ifi.ifi_addr_local);
740 if (ifi.ifi_netmask) {
741 tracef("/%A",
742 ifi.ifi_netmask);
743 }
744 if (ifi.ifi_addr_broadcast) {
745 tracef(" -> %A",
746 ifi.ifi_addr_broadcast);
747 } else if (ifi.ifi_addr != ifi.ifi_addr_local) {
748 tracef(" -> %A",
749 ifi.ifi_addr);
750 }
751 trace_only_tp(tp,
752 0,
753 (NULL));
754 trace_only_tp(tp,
755 0,
756 ("krt_ifread: %s metric %u mtu %u state <%s>",
757 ifl->ifl_name,
758 ifi.ifi_metric,
759 ifi.ifi_mtu,
760 trace_bits(if_state_bits, ifi.ifi_state)));
761 }
762
763 /* And add the interface */
764 if_conf_addaddr(tp, &ifi);
765 continue;
766
767 Continue:
768 /* Free any allocated addresses */
769 ifi_addr_free(&ifi);
770 }
771
772 trace_tp(tp,
773 TR_KRT_IFLIST,
774 0,
775 (NULL));
776
777 if_conf_close(tp, FALSE);
778
779 return 0;
780}
This page took 0.251147 seconds and 4 git commands to generate.