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