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