]> git.pld-linux.org Git - packages/gated.git/blob - gated-3.5.9-krt_ifread_ioctl.c
- dropped pre-cvs changelog
[packages/gated.git] / gated-3.5.9-krt_ifread_ioctl.c
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
89 error - IFL_NAMELEN not compatible with IFNAMESIZ
90 #endif
91
92 /* Make some assumptions about interface MTU */
93 static inline mtu_t
94 krt_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
116 int
117 krt_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.234213 seconds and 3 git commands to generate.