Merge branch 'vendor/LIBPCAP'
[dragonfly.git] / sbin / routed / if.c
1 /*
2  * Copyright (c) 1983, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the University nor the names of its contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * @(#)if.c     8.1 (Berkeley) 6/5/93
30  * $FreeBSD: src/sbin/routed/if.c,v 1.6.2.1 2000/08/14 17:00:03 sheldonh Exp $
31  */
32
33 #include "defs.h"
34 #include "pathnames.h"
35
36 struct interface *ifnet;                /* all interfaces */
37
38 /* hash table for all interfaces, big enough to tolerate ridiculous
39  * numbers of IP aliases.  Crazy numbers of aliases such as 7000
40  * still will not do well, but not just in looking up interfaces
41  * by name or address.
42  */
43 #define AHASH_LEN 211                   /* must be prime */
44 #define AHASH(a) &ahash_tbl[(a)%AHASH_LEN]
45 struct interface *ahash_tbl[AHASH_LEN];
46
47 #define BHASH_LEN 211                   /* must be prime */
48 #define BHASH(a) &bhash_tbl[(a)%BHASH_LEN]
49 struct interface *bhash_tbl[BHASH_LEN];
50
51 struct interface *remote_if;            /* remote interfaces */
52
53 /* hash for physical interface names.
54  * Assume there are never more 100 or 200 real interfaces, and that
55  * aliases are put on the end of the hash chains.
56  */
57 #define NHASH_LEN 97
58 struct interface *nhash_tbl[NHASH_LEN];
59
60 int     tot_interfaces;                 /* # of remote and local interfaces */
61 int     rip_interfaces;                 /* # of interfaces doing RIP */
62 int     foundloopback;                  /* valid flag for loopaddr */
63 naddr   loopaddr;                       /* our address on loopback */
64 struct  rt_spare loop_rts;
65
66 struct timeval ifinit_timer;
67 static struct timeval last_ifinit;
68 #define IF_RESCAN_DELAY() (last_ifinit.tv_sec == now.tv_sec             \
69                            && last_ifinit.tv_usec == now.tv_usec        \
70                            && timercmp(&ifinit_timer, &now, >))
71
72 int     have_ripv1_out;                 /* have a RIPv1 interface */
73 int     have_ripv1_in;
74
75
76 static struct interface**
77 nhash(char *p)
78 {
79         u_int i;
80
81         for (i = 0; *p != '\0'; p++) {
82                 i = ((i<<1) & 0x7fffffff) | ((i>>31) & 1);
83                 i ^= *p;
84         }
85         return &nhash_tbl[i % NHASH_LEN];
86 }
87
88
89 /* Link a new interface into the lists and hash tables.
90  */
91 void
92 if_link(struct interface *ifp)
93 {
94         struct interface **hifp;
95
96         ifp->int_prev = &ifnet;
97         ifp->int_next = ifnet;
98         if (ifnet != NULL)
99                 ifnet->int_prev = &ifp->int_next;
100         ifnet = ifp;
101
102         hifp = AHASH(ifp->int_addr);
103         ifp->int_ahash_prev = hifp;
104         if ((ifp->int_ahash = *hifp) != NULL)
105                 (*hifp)->int_ahash_prev = &ifp->int_ahash;
106         *hifp = ifp;
107
108         if (ifp->int_if_flags & IFF_BROADCAST) {
109                 hifp = BHASH(ifp->int_brdaddr);
110                 ifp->int_bhash_prev = hifp;
111                 if ((ifp->int_bhash = *hifp) != NULL)
112                         (*hifp)->int_bhash_prev = &ifp->int_bhash;
113                 *hifp = ifp;
114         }
115
116         if (ifp->int_state & IS_REMOTE) {
117                 ifp->int_rlink_prev = &remote_if;
118                 ifp->int_rlink = remote_if;
119                 if (remote_if != NULL)
120                         remote_if->int_rlink_prev = &ifp->int_rlink;
121                 remote_if = ifp;
122         }
123
124         hifp = nhash(ifp->int_name);
125         if (ifp->int_state & IS_ALIAS) {
126                 /* put aliases on the end of the hash chain */
127                 while (*hifp != NULL)
128                         hifp = &(*hifp)->int_nhash;
129         }
130         ifp->int_nhash_prev = hifp;
131         if ((ifp->int_nhash = *hifp) != NULL)
132                 (*hifp)->int_nhash_prev = &ifp->int_nhash;
133         *hifp = ifp;
134 }
135
136
137 /* Find the interface with an address
138  */
139 struct interface *
140 ifwithaddr(naddr addr,
141            int  bcast,                  /* notice IFF_BROADCAST address */
142            int  remote)                 /* include IS_REMOTE interfaces */
143 {
144         struct interface *ifp, *possible = NULL;
145
146         remote = (remote == 0) ? IS_REMOTE : 0;
147
148         for (ifp = *AHASH(addr); ifp; ifp = ifp->int_ahash) {
149                 if (ifp->int_addr != addr)
150                         continue;
151                 if ((ifp->int_state & remote) != 0)
152                         continue;
153                 if ((ifp->int_state & (IS_BROKE | IS_PASSIVE)) == 0)
154                         return ifp;
155                 possible = ifp;
156         }
157
158         if (possible || !bcast)
159                 return possible;
160
161         for (ifp = *BHASH(addr); ifp; ifp = ifp->int_bhash) {
162                 if (ifp->int_brdaddr != addr)
163                         continue;
164                 if ((ifp->int_state & remote) != 0)
165                         continue;
166                 if ((ifp->int_state & (IS_BROKE | IS_PASSIVE)) == 0)
167                         return ifp;
168                 possible = ifp;
169         }
170
171         return possible;
172 }
173
174
175 /* find the interface with a name
176  */
177 struct interface *
178 ifwithname(char *name,                  /* "ec0" or whatever */
179            naddr addr)                  /* 0 or network address */
180 {
181         struct interface *ifp;
182
183         for (;;) {
184                 for (ifp = *nhash(name); ifp != NULL; ifp = ifp->int_nhash) {
185                         /* If the network address is not specified,
186                          * ignore any alias interfaces.  Otherwise, look
187                          * for the interface with the target name and address.
188                          */
189                         if (!strcmp(ifp->int_name, name)
190                             && ((addr == 0 && !(ifp->int_state & IS_ALIAS))
191                                 || (ifp->int_addr == addr)))
192                                 return ifp;
193                 }
194
195                 /* If there is no known interface, maybe there is a
196                  * new interface.  So just once look for new interfaces.
197                  */
198                 if (IF_RESCAN_DELAY())
199                         return 0;
200                 ifinit();
201         }
202 }
203
204
205 struct interface *
206 ifwithindex(u_short idx, int rescan_ok)
207 {
208         struct interface *ifp;
209
210         for (;;) {
211                 for (ifp = ifnet; NULL != ifp; ifp = ifp->int_next) {
212                         if (ifp->int_index == idx)
213                                 return ifp;
214                 }
215
216                 /* If there is no known interface, maybe there is a
217                  * new interface.  So just once look for new interfaces.
218                  */
219                 if (!rescan_ok
220                     || IF_RESCAN_DELAY())
221                         return 0;
222                 ifinit();
223         }
224 }
225
226
227 /* Find an interface from which the specified address
228  * should have come from.  Used for figuring out which
229  * interface a packet came in on.
230  */
231 struct interface *
232 iflookup(naddr addr)
233 {
234         struct interface *ifp, *maybe;
235
236         maybe = NULL;
237         for (;;) {
238                 for (ifp = ifnet; ifp; ifp = ifp->int_next) {
239                         if (ifp->int_if_flags & IFF_POINTOPOINT) {
240                                 /* finished with a match */
241                                 if (ifp->int_dstaddr == addr)
242                                         return ifp;
243
244                         } else {
245                                 /* finished with an exact match */
246                                 if (ifp->int_addr == addr)
247                                         return ifp;
248
249                                 /* Look for the longest approximate match.
250                                  */
251                                 if (on_net(addr, ifp->int_net, ifp->int_mask)
252                                     && (maybe == NULL
253                                         || ifp->int_mask > maybe->int_mask))
254                                         maybe = ifp;
255                         }
256                 }
257
258                 if (maybe != NULL
259                     || IF_RESCAN_DELAY())
260                         return maybe;
261
262                 /* If there is no known interface, maybe there is a
263                  * new interface.  So just once look for new interfaces.
264                  */
265                 ifinit();
266         }
267 }
268
269
270 /* Return the classical netmask for an IP address.
271  */
272 naddr                                   /* host byte order */
273 std_mask(naddr addr)                    /* network byte order */
274 {
275         addr = ntohl(addr);             /* was a host, not a network */
276
277         if (addr == 0)                  /* default route has mask 0 */
278                 return 0;
279         if (IN_CLASSA(addr))
280                 return IN_CLASSA_NET;
281         if (IN_CLASSB(addr))
282                 return IN_CLASSB_NET;
283         return IN_CLASSC_NET;
284 }
285
286
287 /* Find the netmask that would be inferred by RIPv1 listeners
288  *      on the given interface for a given network.
289  *      If no interface is specified, look for the best fitting interface.
290  */
291 naddr
292 ripv1_mask_net(naddr addr,              /* in network byte order */
293                struct interface *ifp)   /* as seen on this interface */
294 {
295         struct r1net *r1p;
296         naddr mask = 0;
297
298         if (addr == 0)                  /* default always has 0 mask */
299                 return mask;
300
301         if (ifp != NULL && ifp->int_ripv1_mask != HOST_MASK) {
302                 /* If the target network is that of the associated interface
303                  * on which it arrived, then use the netmask of the interface.
304                  */
305                 if (on_net(addr, ifp->int_net, ifp->int_std_mask))
306                         mask = ifp->int_ripv1_mask;
307
308         } else {
309                 /* Examine all interfaces, and if it the target seems
310                  * to have the same network number of an interface, use the
311                  * netmask of that interface.  If there is more than one
312                  * such interface, prefer the interface with the longest
313                  * match.
314                  */
315                 for (ifp = ifnet; ifp != NULL; ifp = ifp->int_next) {
316                         if (on_net(addr, ifp->int_std_net, ifp->int_std_mask)
317                             && ifp->int_ripv1_mask > mask
318                             && ifp->int_ripv1_mask != HOST_MASK)
319                                 mask = ifp->int_ripv1_mask;
320                 }
321
322         }
323
324         /* check special definitions */
325         if (mask == 0) {
326                 for (r1p = r1nets; r1p != NULL; r1p = r1p->r1net_next) {
327                         if (on_net(addr, r1p->r1net_net, r1p->r1net_match)
328                             && r1p->r1net_mask > mask)
329                                 mask = r1p->r1net_mask;
330                 }
331
332                 /* Otherwise, make the classic A/B/C guess.
333                  */
334                 if (mask == 0)
335                         mask = std_mask(addr);
336         }
337
338         return mask;
339 }
340
341
342 naddr
343 ripv1_mask_host(naddr addr,             /* in network byte order */
344                 struct interface *ifp)  /* as seen on this interface */
345 {
346         naddr mask = ripv1_mask_net(addr, ifp);
347
348
349         /* If the computed netmask does not mask the address,
350          * then assume it is a host address
351          */
352         if ((ntohl(addr) & ~mask) != 0)
353                 mask = HOST_MASK;
354         return mask;
355 }
356
357
358 /* See if a IP address looks reasonable as a destination
359  */
360 int                                     /* 0=bad */
361 check_dst(naddr addr)
362 {
363         addr = ntohl(addr);
364
365         if (IN_CLASSA(addr)) {
366                 if (addr == 0)
367                         return 1;       /* default */
368
369                 addr >>= IN_CLASSA_NSHIFT;
370                 return (addr != 0 && addr != IN_LOOPBACKNET);
371         }
372
373         return (IN_CLASSB(addr) || IN_CLASSC(addr));
374 }
375
376
377 /* See a new interface duplicates an existing interface.
378  */
379 struct interface *
380 check_dup(naddr addr,                   /* IP address, so network byte order */
381           naddr dstaddr,                /* ditto */
382           naddr mask,                   /* mask, so host byte order */
383           int if_flags)
384 {
385         struct interface *ifp;
386
387         for (ifp = ifnet; NULL != ifp; ifp = ifp->int_next) {
388                 if (ifp->int_mask != mask)
389                         continue;
390
391                 if (!iff_up(ifp->int_if_flags))
392                         continue;
393
394                 /* The local address can only be shared with a point-to-point
395                  * link.
396                  */
397                 if (ifp->int_addr == addr
398                     && (((if_flags|ifp->int_if_flags) & IFF_POINTOPOINT) == 0))
399                         return ifp;
400
401                 if (on_net(ifp->int_dstaddr, ntohl(dstaddr),mask))
402                         return ifp;
403         }
404         return 0;
405 }
406
407
408 /* See that a remote gateway is reachable.
409  *      Note that the answer can change as real interfaces come and go.
410  */
411 int                                     /* 0=bad */
412 check_remote(struct interface *ifp)
413 {
414         struct rt_entry *rt;
415
416         /* do not worry about other kinds */
417         if (!(ifp->int_state & IS_REMOTE))
418             return 1;
419
420         rt = rtfind(ifp->int_addr);
421         if (rt != NULL
422             && rt->rt_ifp != 0
423             &&on_net(ifp->int_addr,
424                      rt->rt_ifp->int_net, rt->rt_ifp->int_mask))
425                 return 1;
426
427         /* the gateway cannot be reached directly from one of our
428          * interfaces
429          */
430         if (!(ifp->int_state & IS_BROKE)) {
431                 msglog("unreachable gateway %s in "_PATH_GATEWAYS,
432                        naddr_ntoa(ifp->int_addr));
433                 if_bad(ifp);
434         }
435         return 0;
436 }
437
438
439 /* Delete an interface.
440  */
441 static void
442 ifdel(struct interface *ifp)
443 {
444         struct ip_mreq m;
445         struct interface *ifp1;
446
447
448         trace_if("Del", ifp);
449
450         ifp->int_state |= IS_BROKE;
451
452         /* unlink the interface
453          */
454         *ifp->int_prev = ifp->int_next;
455         if (ifp->int_next != 0)
456                 ifp->int_next->int_prev = ifp->int_prev;
457         *ifp->int_ahash_prev = ifp->int_ahash;
458         if (ifp->int_ahash != 0)
459                 ifp->int_ahash->int_ahash_prev = ifp->int_ahash_prev;
460         *ifp->int_nhash_prev = ifp->int_nhash;
461         if (ifp->int_nhash != 0)
462                 ifp->int_nhash->int_nhash_prev = ifp->int_nhash_prev;
463         if (ifp->int_if_flags & IFF_BROADCAST) {
464                 *ifp->int_bhash_prev = ifp->int_bhash;
465                 if (ifp->int_bhash != 0)
466                         ifp->int_bhash->int_bhash_prev = ifp->int_bhash_prev;
467         }
468         if (ifp->int_state & IS_REMOTE) {
469                 *ifp->int_rlink_prev = ifp->int_rlink;
470                 if (ifp->int_rlink != 0)
471                         ifp->int_rlink->int_rlink_prev = ifp->int_rlink_prev;
472         }
473
474         if (!(ifp->int_state & IS_ALIAS)) {
475                 /* delete aliases when the main interface dies
476                  */
477                 for (ifp1 = ifnet; NULL != ifp1; ifp1 = ifp1->int_next) {
478                         if (ifp1 != ifp
479                             && !strcmp(ifp->int_name, ifp1->int_name))
480                                 ifdel(ifp1);
481                 }
482
483                 if ((ifp->int_if_flags & IFF_MULTICAST)
484 #ifdef MCAST_PPP_BUG
485                     && !(ifp->int_if_flags & IFF_POINTOPOINT)
486 #endif
487                     && rip_sock >= 0) {
488                         m.imr_multiaddr.s_addr = htonl(INADDR_RIP_GROUP);
489                         m.imr_interface.s_addr = ((ifp->int_if_flags
490                                                    & IFF_POINTOPOINT)
491                                                   ? ifp->int_dstaddr
492                                                   : ifp->int_addr);
493                         if (setsockopt(rip_sock,IPPROTO_IP,IP_DROP_MEMBERSHIP,
494                                        &m, sizeof(m)) < 0
495                             && errno != EADDRNOTAVAIL
496                             && !TRACEACTIONS)
497                                 LOGERR("setsockopt(IP_DROP_MEMBERSHIP RIP)");
498                         if (rip_sock_mcast == ifp)
499                                 rip_sock_mcast = 0;
500                 }
501                 if (ifp->int_rip_sock >= 0) {
502                         close(ifp->int_rip_sock);
503                         ifp->int_rip_sock = -1;
504                         fix_select();
505                 }
506
507                 tot_interfaces--;
508                 if (!IS_RIP_OFF(ifp->int_state))
509                         rip_interfaces--;
510
511                 /* Zap all routes associated with this interface.
512                  * Assume routes just using gateways beyond this interface
513                  * will timeout naturally, and have probably already died.
514                  */
515                 rn_walktree(rhead, walk_bad, 0);
516
517                 set_rdisc_mg(ifp, 0);
518                 if_bad_rdisc(ifp);
519         }
520
521         free(ifp);
522 }
523
524
525 /* Mark an interface ill.
526  */
527 void
528 if_sick(struct interface *ifp)
529 {
530         if (0 == (ifp->int_state & (IS_SICK | IS_BROKE))) {
531                 ifp->int_state |= IS_SICK;
532                 ifp->int_act_time = NEVER;
533                 trace_if("Chg", ifp);
534
535                 LIM_SEC(ifinit_timer, now.tv_sec+CHECK_BAD_INTERVAL);
536         }
537 }
538
539
540 /* Mark an interface dead.
541  */
542 void
543 if_bad(struct interface *ifp)
544 {
545         struct interface *ifp1;
546
547
548         if (ifp->int_state & IS_BROKE)
549                 return;
550
551         LIM_SEC(ifinit_timer, now.tv_sec+CHECK_BAD_INTERVAL);
552
553         ifp->int_state |= (IS_BROKE | IS_SICK);
554         ifp->int_act_time = NEVER;
555         ifp->int_query_time = NEVER;
556         ifp->int_data.ts = now.tv_sec;
557
558         trace_if("Chg", ifp);
559
560         if (!(ifp->int_state & IS_ALIAS)) {
561                 for (ifp1 = ifnet; NULL != ifp1; ifp1 = ifp1->int_next) {
562                         if (ifp1 != ifp
563                             && !strcmp(ifp->int_name, ifp1->int_name))
564                                 if_bad(ifp1);
565                 }
566                 rn_walktree(rhead, walk_bad, 0);
567                 if_bad_rdisc(ifp);
568         }
569 }
570
571
572 /* Mark an interface alive
573  */
574 int                                     /* 1=it was dead */
575 if_ok(struct interface *ifp,
576       const char *type)
577 {
578         struct interface *ifp1;
579
580
581         if (!(ifp->int_state & IS_BROKE)) {
582                 if (ifp->int_state & IS_SICK) {
583                         trace_act("%sinterface %s to %s working better",
584                                   type,
585                                   ifp->int_name, naddr_ntoa(ifp->int_dstaddr));
586                         ifp->int_state &= ~IS_SICK;
587                 }
588                 return 0;
589         }
590
591         msglog("%sinterface %s to %s restored",
592                type, ifp->int_name, naddr_ntoa(ifp->int_dstaddr));
593         ifp->int_state &= ~(IS_BROKE | IS_SICK);
594         ifp->int_data.ts = 0;
595
596         if (!(ifp->int_state & IS_ALIAS)) {
597                 for (ifp1 = ifnet; NULL != ifp1; ifp1 = ifp1->int_next) {
598                         if (ifp1 != ifp
599                             && !strcmp(ifp->int_name, ifp1->int_name))
600                                 if_ok(ifp1, type);
601                 }
602                 if_ok_rdisc(ifp);
603         }
604
605         if (ifp->int_state & IS_REMOTE) {
606                 if (!addrouteforif(ifp))
607                         return 0;
608         }
609         return 1;
610 }
611
612
613 /* disassemble routing message
614  */
615 void
616 rt_xaddrs(struct rt_addrinfo *info,
617           struct sockaddr *sa,
618           struct sockaddr *lim,
619           int addrs)
620 {
621         int i;
622 #ifdef _HAVE_SA_LEN
623         static struct sockaddr sa_zero;
624 #endif
625 #define ROUNDUP(a) RT_ROUNDUP(a)
626
627
628         memset(info, 0, sizeof(*info));
629         info->rti_addrs = addrs;
630         for (i = 0; i < RTAX_MAX && sa < lim; i++) {
631                 if ((addrs & (1 << i)) == 0)
632                         continue;
633 #ifdef _HAVE_SA_LEN
634                 info->rti_info[i] = (sa->sa_len != 0) ? sa : &sa_zero;
635                 sa = (struct sockaddr *)((char*)(sa)
636                                          + ROUNDUP(sa->sa_len));
637 #else
638                 info->rti_info[i] = sa;
639                 sa = (struct sockaddr *)((char*)(sa)
640                                          + ROUNDUP(_FAKE_SA_LEN_DST(sa)));
641 #endif
642         }
643 }
644
645
646 /* Find the network interfaces which have configured themselves.
647  *      This must be done regularly, if only for extra addresses
648  *      that come and go on interfaces.
649  */
650 void
651 ifinit(void)
652 {
653         static char *sysctl_buf;
654         static size_t sysctl_buf_size = 0;
655         uint complaints = 0;
656         static u_int prev_complaints = 0;
657 #       define COMP_NOT_INET    0x001
658 #       define COMP_NOADDR      0x002
659 #       define COMP_BADADDR     0x004
660 #       define COMP_NODST       0x008
661 #       define COMP_NOBADR      0x010
662 #       define COMP_NOMASK      0x020
663 #       define COMP_DUP         0x040
664 #       define COMP_BAD_METRIC  0x080
665 #       define COMP_NETMASK     0x100
666
667         struct interface ifs, ifs0, *ifp, *ifp1;
668         struct rt_entry *rt;
669         size_t needed;
670         int mib[6];
671         struct if_msghdr *ifm;
672         struct ifa_msghdr *ifam, *ifam_lim, *ifam2;
673         int in, ierr, out, oerr;
674         struct intnet *intnetp;
675         struct rt_addrinfo info;
676 #ifdef SIOCGIFMETRIC
677         struct ifreq ifr;
678 #endif
679
680
681         last_ifinit = now;
682         ifinit_timer.tv_sec = now.tv_sec + (supplier
683                                             ? CHECK_ACT_INTERVAL
684                                             : CHECK_QUIET_INTERVAL);
685
686         /* mark all interfaces so we can get rid of those that disappear */
687         for (ifp = ifnet; NULL != ifp; ifp = ifp->int_next)
688                 ifp->int_state &= ~(IS_CHECKED | IS_DUP);
689
690         /* Fetch the interface list, without too many system calls
691          * since we do it repeatedly.
692          */
693         mib[0] = CTL_NET;
694         mib[1] = PF_ROUTE;
695         mib[2] = 0;
696         mib[3] = AF_INET;
697         mib[4] = NET_RT_IFLIST;
698         mib[5] = 0;
699         for (;;) {
700                 if ((needed = sysctl_buf_size) != 0) {
701                         if (sysctl(mib, 6, sysctl_buf,&needed, 0, 0) >= 0)
702                                 break;
703                         /* retry if the table grew */
704                         if (errno != ENOMEM && errno != EFAULT)
705                                 BADERR(1, "ifinit: sysctl(RT_IFLIST)");
706                         free(sysctl_buf);
707                         needed = 0;
708                 }
709                 if (sysctl(mib, 6, 0, &needed, 0, 0) < 0)
710                         BADERR(1,"ifinit: sysctl(RT_IFLIST) estimate");
711                 sysctl_buf = rtmalloc(sysctl_buf_size = needed,
712                                       "ifinit sysctl");
713         }
714
715         ifam_lim = (struct ifa_msghdr *)(sysctl_buf + needed);
716         for (ifam = (struct ifa_msghdr *)sysctl_buf;
717              ifam < ifam_lim;
718              ifam = ifam2) {
719
720                 ifam2 = (struct ifa_msghdr*)((char*)ifam + ifam->ifam_msglen);
721
722                 if (ifam->ifam_type == RTM_IFINFO) {
723                         struct sockaddr_dl *sdl;
724
725                         ifm = (struct if_msghdr *)ifam;
726                         /* make prototype structure for the IP aliases
727                          */
728                         memset(&ifs0, 0, sizeof(ifs0));
729                         ifs0.int_rip_sock = -1;
730                         ifs0.int_index = ifm->ifm_index;
731                         ifs0.int_if_flags = ifm->ifm_flags;
732                         ifs0.int_state = IS_CHECKED;
733                         ifs0.int_query_time = NEVER;
734                         ifs0.int_act_time = now.tv_sec;
735                         ifs0.int_data.ts = now.tv_sec;
736                         ifs0.int_data.ipackets = ifm->ifm_data.ifi_ipackets;
737                         ifs0.int_data.ierrors = ifm->ifm_data.ifi_ierrors;
738                         ifs0.int_data.opackets = ifm->ifm_data.ifi_opackets;
739                         ifs0.int_data.oerrors = ifm->ifm_data.ifi_oerrors;
740                         sdl = (struct sockaddr_dl *)(ifm + 1);
741                         sdl->sdl_data[sdl->sdl_nlen] = 0;
742                         strncpy(ifs0.int_name, sdl->sdl_data,
743                                 MIN(sizeof(ifs0.int_name), sdl->sdl_nlen));
744                         continue;
745                 }
746                 if (ifam->ifam_type != RTM_NEWADDR) {
747                         logbad(1,"ifinit: out of sync");
748                         continue;
749                 }
750                 rt_xaddrs(&info, (struct sockaddr *)(ifam+1),
751                           (struct sockaddr *)ifam2,
752                           ifam->ifam_addrs);
753
754                 /* Prepare for the next address of this interface, which
755                  * will be an alias.
756                  * Do not output RIP or Router-Discovery packets via aliases.
757                  */
758                 memcpy(&ifs, &ifs0, sizeof(ifs));
759                 ifs0.int_state |= (IS_ALIAS | IS_NO_RIP_OUT | IS_NO_RDISC);
760
761                 if (INFO_IFA(&info) == 0) {
762                         if (iff_up(ifs.int_if_flags)) {
763                                 if (!(prev_complaints & COMP_NOADDR))
764                                         msglog("%s has no address",
765                                                ifs.int_name);
766                                 complaints |= COMP_NOADDR;
767                         }
768                         continue;
769                 }
770                 if (INFO_IFA(&info)->sa_family != AF_INET) {
771                         if (iff_up(ifs.int_if_flags)) {
772                                 if (!(prev_complaints & COMP_NOT_INET))
773                                         trace_act("%s: not AF_INET",
774                                                   ifs.int_name);
775                                 complaints |= COMP_NOT_INET;
776                         }
777                         continue;
778                 }
779
780                 ifs.int_addr = S_ADDR(INFO_IFA(&info));
781
782                 if (ntohl(ifs.int_addr)>>24 == 0
783                     || ntohl(ifs.int_addr)>>24 == 0xff) {
784                         if (iff_up(ifs.int_if_flags)) {
785                                 if (!(prev_complaints & COMP_BADADDR))
786                                         msglog("%s has a bad address",
787                                                ifs.int_name);
788                                 complaints |= COMP_BADADDR;
789                         }
790                         continue;
791                 }
792
793                 if (ifs.int_if_flags & IFF_LOOPBACK) {
794                         ifs.int_state |= IS_PASSIVE | IS_NO_RIP | IS_NO_RDISC;
795                         ifs.int_dstaddr = ifs.int_addr;
796                         ifs.int_mask = HOST_MASK;
797                         ifs.int_ripv1_mask = HOST_MASK;
798                         ifs.int_std_mask = std_mask(ifs.int_dstaddr);
799                         ifs.int_net = ntohl(ifs.int_dstaddr);
800                         if (!foundloopback) {
801                                 foundloopback = 1;
802                                 loopaddr = ifs.int_addr;
803                                 loop_rts.rts_gate = loopaddr;
804                                 loop_rts.rts_router = loopaddr;
805                         }
806
807                 } else if (ifs.int_if_flags & IFF_POINTOPOINT) {
808                         if (INFO_BRD(&info) == 0
809                             || INFO_BRD(&info)->sa_family != AF_INET) {
810                                 if (iff_up(ifs.int_if_flags)) {
811                                         if (!(prev_complaints & COMP_NODST))
812                                                 msglog("%s has a bad"
813                                                        " destination address",
814                                                        ifs.int_name);
815                                         complaints |= COMP_NODST;
816                                 }
817                                 continue;
818                         }
819                         ifs.int_dstaddr = S_ADDR(INFO_BRD(&info));
820                         if (ntohl(ifs.int_dstaddr)>>24 == 0
821                             || ntohl(ifs.int_dstaddr)>>24 == 0xff) {
822                                 if (iff_up(ifs.int_if_flags)) {
823                                         if (!(prev_complaints & COMP_NODST))
824                                                 msglog("%s has a bad"
825                                                        " destination address",
826                                                        ifs.int_name);
827                                         complaints |= COMP_NODST;
828                                 }
829                                 continue;
830                         }
831                         ifs.int_mask = HOST_MASK;
832                         ifs.int_ripv1_mask = ntohl(S_ADDR(INFO_MASK(&info)));
833                         ifs.int_std_mask = std_mask(ifs.int_dstaddr);
834                         ifs.int_net = ntohl(ifs.int_dstaddr);
835
836                 }  else {
837                         if (INFO_MASK(&info) == 0) {
838                                 if (iff_up(ifs.int_if_flags)) {
839                                         if (!(prev_complaints & COMP_NOMASK))
840                                                 msglog("%s has no netmask",
841                                                        ifs.int_name);
842                                         complaints |= COMP_NOMASK;
843                                 }
844                                 continue;
845                         }
846                         ifs.int_dstaddr = ifs.int_addr;
847                         ifs.int_mask = ntohl(S_ADDR(INFO_MASK(&info)));
848                         ifs.int_ripv1_mask = ifs.int_mask;
849                         ifs.int_std_mask = std_mask(ifs.int_addr);
850                         ifs.int_net = ntohl(ifs.int_addr) & ifs.int_mask;
851                         if (ifs.int_mask != ifs.int_std_mask)
852                                 ifs.int_state |= IS_SUBNET;
853
854                         if (ifs.int_if_flags & IFF_BROADCAST) {
855                                 if (INFO_BRD(&info) == 0) {
856                                         if (iff_up(ifs.int_if_flags)) {
857                                             if (!(prev_complaints
858                                                   & COMP_NOBADR))
859                                                 msglog("%s has"
860                                                        "no broadcast address",
861                                                        ifs.int_name);
862                                             complaints |= COMP_NOBADR;
863                                         }
864                                         continue;
865                                 }
866                                 ifs.int_brdaddr = S_ADDR(INFO_BRD(&info));
867                         }
868                 }
869                 ifs.int_std_net = ifs.int_net & ifs.int_std_mask;
870                 ifs.int_std_addr = htonl(ifs.int_std_net);
871
872                 /* Use a minimum metric of one.  Treat the interface metric
873                  * (default 0) as an increment to the hop count of one.
874                  *
875                  * The metric obtained from the routing socket dump of
876                  * interface addresses is wrong.  It is not set by the
877                  * SIOCSIFMETRIC ioctl.
878                  */
879 #ifdef SIOCGIFMETRIC
880                 strncpy(ifr.ifr_name, ifs.int_name, sizeof(ifr.ifr_name));
881                 if (ioctl(rt_sock, SIOCGIFMETRIC, &ifr) < 0) {
882                         DBGERR(1, "ioctl(SIOCGIFMETRIC)");
883                         ifs.int_metric = 0;
884                 } else {
885                         ifs.int_metric = ifr.ifr_metric;
886                 }
887 #else
888                 ifs.int_metric = ifam->ifam_metric;
889 #endif
890                 if (ifs.int_metric > HOPCNT_INFINITY) {
891                         ifs.int_metric = 0;
892                         if (!(prev_complaints & COMP_BAD_METRIC)
893                             && iff_up(ifs.int_if_flags)) {
894                                 complaints |= COMP_BAD_METRIC;
895                                 msglog("%s has a metric of %d",
896                                        ifs.int_name, ifs.int_metric);
897                         }
898                 }
899
900                 /* See if this is a familiar interface.
901                  * If so, stop worrying about it if it is the same.
902                  * Start it over if it now is to somewhere else, as happens
903                  * frequently with PPP and SLIP.
904                  */
905                 ifp = ifwithname(ifs.int_name, ((ifs.int_state & IS_ALIAS)
906                                                 ? ifs.int_addr
907                                                 : 0));
908                 if (ifp != NULL) {
909                         ifp->int_state |= IS_CHECKED;
910
911                         if (0 != ((ifp->int_if_flags ^ ifs.int_if_flags)
912                                   & (IFF_BROADCAST
913                                      | IFF_LOOPBACK
914                                      | IFF_POINTOPOINT
915                                      | IFF_MULTICAST))
916                             || 0 != ((ifp->int_state ^ ifs.int_state)
917                                      & IS_ALIAS)
918                             || ifp->int_addr != ifs.int_addr
919                             || ifp->int_brdaddr != ifs.int_brdaddr
920                             || ifp->int_dstaddr != ifs.int_dstaddr
921                             || ifp->int_mask != ifs.int_mask
922                             || ifp->int_metric != ifs.int_metric) {
923                                 /* Forget old information about
924                                  * a changed interface.
925                                  */
926                                 trace_act("interface %s has changed",
927                                           ifp->int_name);
928                                 ifdel(ifp);
929                                 ifp = NULL;
930                         }
931                 }
932
933                 if (ifp != NULL) {
934                         /* The primary representative of an alias worries
935                          * about how things are working.
936                          */
937                         if (ifp->int_state & IS_ALIAS)
938                                 continue;
939
940                         /* note interfaces that have been turned off
941                          */
942                         if (!iff_up(ifs.int_if_flags)) {
943                                 if (iff_up(ifp->int_if_flags)) {
944                                         msglog("interface %s to %s turned off",
945                                                ifp->int_name,
946                                                naddr_ntoa(ifp->int_dstaddr));
947                                         if_bad(ifp);
948                                         ifp->int_if_flags &= ~IFF_UP;
949                                 } else if (now.tv_sec>(ifp->int_data.ts
950                                                        + CHECK_BAD_INTERVAL)) {
951                                         trace_act("interface %s has been off"
952                                                   " %ld seconds; forget it",
953                                                   ifp->int_name,
954                                                   now.tv_sec-ifp->int_data.ts);
955                                         ifdel(ifp);
956                                 }
957                                 continue;
958                         }
959                         /* or that were off and are now ok */
960                         if (!iff_up(ifp->int_if_flags)) {
961                                 ifp->int_if_flags |= IFF_UP;
962                                 if_ok(ifp, "");
963                         }
964
965                         /* If it has been long enough,
966                          * see if the interface is broken.
967                          */
968                         if (now.tv_sec < ifp->int_data.ts+CHECK_BAD_INTERVAL)
969                                 continue;
970
971                         in = ifs.int_data.ipackets - ifp->int_data.ipackets;
972                         ierr = ifs.int_data.ierrors - ifp->int_data.ierrors;
973                         out = ifs.int_data.opackets - ifp->int_data.opackets;
974                         oerr = ifs.int_data.oerrors - ifp->int_data.oerrors;
975                         /* If the interface just awoke, restart the counters.
976                          */
977                         if (ifp->int_data.ts == 0) {
978                                 ifp->int_data = ifs.int_data;
979                                 continue;
980                         }
981                         ifp->int_data = ifs.int_data;
982
983                         /* Withhold judgment when the short error
984                          * counters wrap or the interface is reset.
985                          */
986                         if (ierr < 0 || in < 0 || oerr < 0 || out < 0) {
987                                 LIM_SEC(ifinit_timer,
988                                         now.tv_sec+CHECK_BAD_INTERVAL);
989                                 continue;
990                         }
991
992                         /* Withhold judgement when there is no traffic
993                          */
994                         if (in == 0 && out == 0 && ierr == 0 && oerr == 0)
995                                 continue;
996
997                         /* It is bad if input or output is not working.
998                          * Require presistent problems before marking it dead.
999                          */
1000                         if ((in <= ierr && ierr > 0)
1001                             || (out <= oerr && oerr > 0)) {
1002                                 if (!(ifp->int_state & IS_SICK)) {
1003                                         trace_act("interface %s to %s"
1004                                                   " sick: in=%d ierr=%d"
1005                                                   " out=%d oerr=%d",
1006                                                   ifp->int_name,
1007                                                   naddr_ntoa(ifp->int_dstaddr),
1008                                                   in, ierr, out, oerr);
1009                                         if_sick(ifp);
1010                                         continue;
1011                                 }
1012                                 if (!(ifp->int_state & IS_BROKE)) {
1013                                         msglog("interface %s to %s broken:"
1014                                                " in=%d ierr=%d out=%d oerr=%d",
1015                                                ifp->int_name,
1016                                                naddr_ntoa(ifp->int_dstaddr),
1017                                                in, ierr, out, oerr);
1018                                         if_bad(ifp);
1019                                 }
1020                                 continue;
1021                         }
1022
1023                         /* otherwise, it is active and healthy
1024                          */
1025                         ifp->int_act_time = now.tv_sec;
1026                         if_ok(ifp, "");
1027                         continue;
1028                 }
1029
1030                 /* This is a new interface.
1031                  * If it is dead, forget it.
1032                  */
1033                 if (!iff_up(ifs.int_if_flags))
1034                         continue;
1035
1036                 /* If it duplicates an existing interface,
1037                  * complain about it, mark the other one
1038                  * duplicated, and forget this one.
1039                  */
1040                 ifp = check_dup(ifs.int_addr,ifs.int_dstaddr,ifs.int_mask,
1041                                 ifs.int_if_flags);
1042                 if (ifp != NULL) {
1043                         /* Ignore duplicates of itself, caused by having
1044                          * IP aliases on the same network.
1045                          */
1046                         if (!strcmp(ifp->int_name, ifs.int_name))
1047                                 continue;
1048
1049                         if (!(prev_complaints & COMP_DUP)) {
1050                                 complaints |= COMP_DUP;
1051                                 msglog("%s (%s%s%s) is duplicated by"
1052                                        " %s (%s%s%s)",
1053                                        ifs.int_name,
1054                                        addrname(ifs.int_addr,ifs.int_mask,1),
1055                                        ((ifs.int_if_flags & IFF_POINTOPOINT)
1056                                         ? "-->" : ""),
1057                                        ((ifs.int_if_flags & IFF_POINTOPOINT)
1058                                         ? naddr_ntoa(ifs.int_dstaddr) : ""),
1059                                        ifp->int_name,
1060                                        addrname(ifp->int_addr,ifp->int_mask,1),
1061                                        ((ifp->int_if_flags & IFF_POINTOPOINT)
1062                                         ? "-->" : ""),
1063                                        ((ifp->int_if_flags & IFF_POINTOPOINT)
1064                                         ? naddr_ntoa(ifp->int_dstaddr) : ""));
1065                         }
1066                         ifp->int_state |= IS_DUP;
1067                         continue;
1068                 }
1069
1070                 if (0 == (ifs.int_if_flags & (IFF_POINTOPOINT | IFF_BROADCAST))
1071                     && !(ifs.int_state & IS_PASSIVE)) {
1072                         trace_act("%s is neither broadcast, point-to-point,"
1073                                   " nor loopback",
1074                                   ifs.int_name);
1075                         if (!(ifs.int_state & IFF_MULTICAST))
1076                                 ifs.int_state |= IS_NO_RDISC;
1077                 }
1078
1079
1080                 /* It is new and ok.   Add it to the list of interfaces
1081                  */
1082                 ifp = (struct interface *)rtmalloc(sizeof(*ifp), "ifinit ifp");
1083                 memcpy(ifp, &ifs, sizeof(*ifp));
1084                 get_parms(ifp);
1085                 if_link(ifp);
1086                 trace_if("Add", ifp);
1087
1088                 /* Notice likely bad netmask.
1089                  */
1090                 if (!(prev_complaints & COMP_NETMASK)
1091                     && !(ifp->int_if_flags & IFF_POINTOPOINT)
1092                     && ifp->int_addr != RIP_DEFAULT) {
1093                         for (ifp1 = ifnet; NULL != ifp1; ifp1 = ifp1->int_next) {
1094                                 if (ifp1->int_mask == ifp->int_mask)
1095                                         continue;
1096                                 if (ifp1->int_if_flags & IFF_POINTOPOINT)
1097                                         continue;
1098                                 if (ifp1->int_dstaddr == RIP_DEFAULT)
1099                                         continue;
1100                                 /* ignore aliases on the right network */
1101                                 if (!strcmp(ifp->int_name, ifp1->int_name))
1102                                         continue;
1103                                 if (on_net(ifp->int_dstaddr,
1104                                            ifp1->int_net, ifp1->int_mask)
1105                                     || on_net(ifp1->int_dstaddr,
1106                                               ifp->int_net, ifp->int_mask)) {
1107                                         msglog("possible netmask problem"
1108                                                " between %s:%s and %s:%s",
1109                                                ifp->int_name,
1110                                                addrname(htonl(ifp->int_net),
1111                                                         ifp->int_mask, 1),
1112                                                ifp1->int_name,
1113                                                addrname(htonl(ifp1->int_net),
1114                                                         ifp1->int_mask, 1));
1115                                         complaints |= COMP_NETMASK;
1116                                 }
1117                         }
1118                 }
1119
1120                 if (!(ifp->int_state & IS_ALIAS)) {
1121                         /* Count the # of directly connected networks.
1122                          */
1123                         if (!(ifp->int_if_flags & IFF_LOOPBACK))
1124                                 tot_interfaces++;
1125                         if (!IS_RIP_OFF(ifp->int_state))
1126                                 rip_interfaces++;
1127
1128                         /* turn on router discovery and RIP If needed */
1129                         if_ok_rdisc(ifp);
1130                         rip_on(ifp);
1131                 }
1132         }
1133
1134         /* If we are multi-homed and have at least two interfaces
1135          * listening to RIP, then output by default.
1136          */
1137         if (!supplier_set && rip_interfaces > 1)
1138                 set_supplier();
1139
1140         /* If we are multi-homed, optionally advertise a route to
1141          * our main address.
1142          */
1143         if (advertise_mhome
1144             || (tot_interfaces > 1
1145                 && mhome
1146                 && (ifp = ifwithaddr(myaddr, 0, 0)) != NULL
1147                 && foundloopback)) {
1148                 advertise_mhome = 1;
1149                 rt = rtget(myaddr, HOST_MASK);
1150                 if (rt != NULL) {
1151                         if (rt->rt_ifp != ifp
1152                             || rt->rt_router != loopaddr) {
1153                                 rtdelete(rt);
1154                                 rt = NULL;
1155                         } else {
1156                                 loop_rts.rts_ifp = ifp;
1157                                 loop_rts.rts_metric = 0;
1158                                 loop_rts.rts_time = rt->rt_time;
1159                                 rtchange(rt, rt->rt_state | RS_MHOME,
1160                                          &loop_rts, 0);
1161                         }
1162                 }
1163                 if (rt == NULL) {
1164                         loop_rts.rts_ifp = ifp;
1165                         loop_rts.rts_metric = 0;
1166                         rtadd(myaddr, HOST_MASK, RS_MHOME, &loop_rts);
1167                 }
1168         }
1169
1170         for (ifp = ifnet; ifp != NULL; ifp = ifp1) {
1171                 ifp1 = ifp->int_next;   /* because we may delete it */
1172
1173                 /* Forget any interfaces that have disappeared.
1174                  */
1175                 if (!(ifp->int_state & (IS_CHECKED | IS_REMOTE))) {
1176                         trace_act("interface %s has disappeared",
1177                                   ifp->int_name);
1178                         ifdel(ifp);
1179                         continue;
1180                 }
1181
1182                 if ((ifp->int_state & IS_BROKE)
1183                     && !(ifp->int_state & IS_PASSIVE))
1184                         LIM_SEC(ifinit_timer, now.tv_sec+CHECK_BAD_INTERVAL);
1185
1186                 /* If we ever have a RIPv1 interface, assume we always will.
1187                  * It might come back if it ever goes away.
1188                  */
1189                 if (!(ifp->int_state & IS_NO_RIPV1_OUT) && supplier)
1190                         have_ripv1_out = 1;
1191                 if (!(ifp->int_state & IS_NO_RIPV1_IN))
1192                         have_ripv1_in = 1;
1193         }
1194
1195         for (ifp = ifnet; ifp != NULL; ifp = ifp->int_next) {
1196                 /* Ensure there is always a network route for interfaces,
1197                  * after any dead interfaces have been deleted, which
1198                  * might affect routes for point-to-point links.
1199                  */
1200                 if (!addrouteforif(ifp))
1201                         continue;
1202
1203                 /* Add routes to the local end of point-to-point interfaces
1204                  * using loopback.
1205                  */
1206                 if ((ifp->int_if_flags & IFF_POINTOPOINT)
1207                     && !(ifp->int_state & IS_REMOTE)
1208                     && foundloopback) {
1209                         /* Delete any routes to the network address through
1210                          * foreign routers. Remove even static routes.
1211                          */
1212                         del_static(ifp->int_addr, HOST_MASK, 0, 0);
1213                         rt = rtget(ifp->int_addr, HOST_MASK);
1214                         if (rt != NULL && rt->rt_router != loopaddr) {
1215                                 rtdelete(rt);
1216                                 rt = NULL;
1217                         }
1218                         if (rt != NULL) {
1219                                 if (!(rt->rt_state & RS_LOCAL)
1220                                     || rt->rt_metric > ifp->int_metric) {
1221                                         ifp1 = ifp;
1222                                 } else {
1223                                         ifp1 = rt->rt_ifp;
1224                                 }
1225                                 loop_rts.rts_ifp = ifp1;
1226                                 loop_rts.rts_metric = 0;
1227                                 loop_rts.rts_time = rt->rt_time;
1228                                 rtchange(rt, ((rt->rt_state & ~RS_NET_SYN)
1229                                               | (RS_IF|RS_LOCAL)),
1230                                          &loop_rts, 0);
1231                         } else {
1232                                 loop_rts.rts_ifp = ifp;
1233                                 loop_rts.rts_metric = 0;
1234                                 rtadd(ifp->int_addr, HOST_MASK,
1235                                       (RS_IF | RS_LOCAL), &loop_rts);
1236                         }
1237                 }
1238         }
1239
1240         /* add the authority routes */
1241         for (intnetp = intnets; intnetp!=NULL; intnetp = intnetp->intnet_next) {
1242                 rt = rtget(intnetp->intnet_addr, intnetp->intnet_mask);
1243                 if (rt != NULL
1244                     && !(rt->rt_state & RS_NO_NET_SYN)
1245                     && !(rt->rt_state & RS_NET_INT)) {
1246                         rtdelete(rt);
1247                         rt = NULL;
1248                 }
1249                 if (rt == NULL) {
1250                         loop_rts.rts_ifp = 0;
1251                         loop_rts.rts_metric = intnetp->intnet_metric-1;
1252                         rtadd(intnetp->intnet_addr, intnetp->intnet_mask,
1253                               RS_NET_SYN | RS_NET_INT, &loop_rts);
1254                 }
1255         }
1256
1257         prev_complaints = complaints;
1258 }
1259
1260
1261 static void
1262 check_net_syn(struct interface *ifp)
1263 {
1264         struct rt_entry *rt;
1265         static struct rt_spare new;
1266
1267
1268         /* Turn on the need to automatically synthesize a network route
1269          * for this interface only if we are running RIPv1 on some other
1270          * interface that is on a different class-A,B,or C network.
1271          */
1272         if (have_ripv1_out || have_ripv1_in) {
1273                 ifp->int_state |= IS_NEED_NET_SYN;
1274                 rt = rtget(ifp->int_std_addr, ifp->int_std_mask);
1275                 if (rt != NULL
1276                     && 0 == (rt->rt_state & RS_NO_NET_SYN)
1277                     && (!(rt->rt_state & RS_NET_SYN)
1278                         || rt->rt_metric > ifp->int_metric)) {
1279                         rtdelete(rt);
1280                         rt = NULL;
1281                 }
1282                 if (rt == NULL) {
1283                         new.rts_ifp = ifp;
1284                         new.rts_gate = ifp->int_addr;
1285                         new.rts_router = ifp->int_addr;
1286                         new.rts_metric = ifp->int_metric;
1287                         rtadd(ifp->int_std_addr, ifp->int_std_mask,
1288                               RS_NET_SYN, &new);
1289                 }
1290
1291         } else {
1292                 ifp->int_state &= ~IS_NEED_NET_SYN;
1293
1294                 rt = rtget(ifp->int_std_addr,
1295                            ifp->int_std_mask);
1296                 if (rt != NULL
1297                     && (rt->rt_state & RS_NET_SYN)
1298                     && rt->rt_ifp == ifp)
1299                         rtbad_sub(rt);
1300         }
1301 }
1302
1303
1304 /* Add route for interface if not currently installed.
1305  * Create route to other end if a point-to-point link,
1306  * otherwise a route to this (sub)network.
1307  */
1308 int                                     /* 0=bad interface */
1309 addrouteforif(struct interface *ifp)
1310 {
1311         struct rt_entry *rt;
1312         static struct rt_spare new;
1313         naddr dst;
1314
1315
1316         /* skip sick interfaces
1317          */
1318         if (ifp->int_state & IS_BROKE)
1319                 return 0;
1320
1321         /* If the interface on a subnet, then install a RIPv1 route to
1322          * the network as well (unless it is sick).
1323          */
1324         if (ifp->int_state & IS_SUBNET)
1325                 check_net_syn(ifp);
1326
1327         dst = (0 != (ifp->int_if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK))
1328                ? ifp->int_dstaddr
1329                : htonl(ifp->int_net));
1330
1331         new.rts_ifp = ifp;
1332         new.rts_router = ifp->int_addr;
1333         new.rts_gate = ifp->int_addr;
1334         new.rts_metric = ifp->int_metric;
1335         new.rts_time = now.tv_sec;
1336
1337         /* If we are going to send packets to the gateway,
1338          * it must be reachable using our physical interfaces
1339          */
1340         if ((ifp->int_state & IS_REMOTE)
1341             && !(ifp->int_state & IS_EXTERNAL)
1342             && !check_remote(ifp))
1343                 return 0;
1344
1345         /* We are finished if the correct main interface route exists.
1346          * The right route must be for the right interface, not synthesized
1347          * from a subnet, be a "gateway" or not as appropriate, and so forth.
1348          */
1349         del_static(dst, ifp->int_mask, 0, 0);
1350         rt = rtget(dst, ifp->int_mask);
1351         if (rt != NULL) {
1352                 if ((rt->rt_ifp != ifp
1353                      || rt->rt_router != ifp->int_addr)
1354                     && (!(ifp->int_state & IS_DUP)
1355                         || rt->rt_ifp == 0
1356                         || (rt->rt_ifp->int_state & IS_BROKE))) {
1357                         rtdelete(rt);
1358                         rt = NULL;
1359                 } else {
1360                         rtchange(rt, ((rt->rt_state | RS_IF)
1361                                       & ~(RS_NET_SYN | RS_LOCAL)),
1362                                  &new, 0);
1363                 }
1364         }
1365         if (rt == NULL) {
1366                 if (ifp->int_transitions++ > 0)
1367                         trace_act("re-install interface %s",
1368                                   ifp->int_name);
1369
1370                 rtadd(dst, ifp->int_mask, RS_IF, &new);
1371         }
1372
1373         return 1;
1374 }