1*8a16b7a1SPedro F. Giffuni /*- 2*8a16b7a1SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause 3*8a16b7a1SPedro F. Giffuni * 47b6ab19dSGarrett Wollman * Copyright (c) 1983, 1988, 1993 57b6ab19dSGarrett Wollman * The Regents of the University of California. All rights reserved. 67b6ab19dSGarrett Wollman * 77b6ab19dSGarrett Wollman * Redistribution and use in source and binary forms, with or without 87b6ab19dSGarrett Wollman * modification, are permitted provided that the following conditions 97b6ab19dSGarrett Wollman * are met: 107b6ab19dSGarrett Wollman * 1. Redistributions of source code must retain the above copyright 117b6ab19dSGarrett Wollman * notice, this list of conditions and the following disclaimer. 127b6ab19dSGarrett Wollman * 2. Redistributions in binary form must reproduce the above copyright 137b6ab19dSGarrett Wollman * notice, this list of conditions and the following disclaimer in the 147b6ab19dSGarrett Wollman * documentation and/or other materials provided with the distribution. 15fbbd9655SWarner Losh * 3. Neither the name of the University nor the names of its contributors 167b6ab19dSGarrett Wollman * may be used to endorse or promote products derived from this software 177b6ab19dSGarrett Wollman * without specific prior written permission. 187b6ab19dSGarrett Wollman * 197b6ab19dSGarrett Wollman * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 207b6ab19dSGarrett Wollman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 217b6ab19dSGarrett Wollman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 227b6ab19dSGarrett Wollman * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 237b6ab19dSGarrett Wollman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 247b6ab19dSGarrett Wollman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 257b6ab19dSGarrett Wollman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 267b6ab19dSGarrett Wollman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 277b6ab19dSGarrett Wollman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 287b6ab19dSGarrett Wollman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 297b6ab19dSGarrett Wollman * SUCH DAMAGE. 307b6ab19dSGarrett Wollman */ 317b6ab19dSGarrett Wollman 327b6ab19dSGarrett Wollman 337b6ab19dSGarrett Wollman /* Definitions for RIPv2 routing process. 347b6ab19dSGarrett Wollman * 357b6ab19dSGarrett Wollman * This code is based on the 4.4BSD `routed` daemon, with extensions to 367b6ab19dSGarrett Wollman * support: 377b6ab19dSGarrett Wollman * RIPv2, including variable length subnet masks. 387b6ab19dSGarrett Wollman * Router Discovery 397b6ab19dSGarrett Wollman * aggregate routes in the kernel tables. 407b6ab19dSGarrett Wollman * aggregate advertised routes. 417b6ab19dSGarrett Wollman * maintain spare routes for faster selection of another gateway 427b6ab19dSGarrett Wollman * when the current gateway dies. 437b6ab19dSGarrett Wollman * timers on routes with second granularity so that selection 447b6ab19dSGarrett Wollman * of a new route does not wait 30-60 seconds. 457b6ab19dSGarrett Wollman * tolerance of static routes. 467b6ab19dSGarrett Wollman * tell the kernel hop counts 477b6ab19dSGarrett Wollman * do not advertise if ipforwarding=0 487b6ab19dSGarrett Wollman * 4990100551SPhilippe Charnier * The vestigial support for other protocols has been removed. There 507b6ab19dSGarrett Wollman * is no likelihood that IETF RIPv1 or RIPv2 will ever be used with 517b6ab19dSGarrett Wollman * other protocols. The result is far smaller, faster, cleaner, and 527b6ab19dSGarrett Wollman * perhaps understandable. 537b6ab19dSGarrett Wollman * 547b6ab19dSGarrett Wollman * The accumulation of special flags and kludges added over the many 557b6ab19dSGarrett Wollman * years have been simplified and integrated. 567b6ab19dSGarrett Wollman */ 577b6ab19dSGarrett Wollman 58a3e04ddcSPoul-Henning Kamp #include <assert.h> 597b6ab19dSGarrett Wollman #include <stdio.h> 607b6ab19dSGarrett Wollman #include <netdb.h> 617b6ab19dSGarrett Wollman #include <stdlib.h> 627b6ab19dSGarrett Wollman #include <unistd.h> 637b6ab19dSGarrett Wollman #include <errno.h> 647b6ab19dSGarrett Wollman #include <string.h> 657b6ab19dSGarrett Wollman #include <stdarg.h> 667b6ab19dSGarrett Wollman #include <syslog.h> 677b6ab19dSGarrett Wollman #include <time.h> 682c7a9781SMark Murray #include <sys/cdefs.h> 69337e72d0SGarrett Wollman #include <sys/time.h> 707b6ab19dSGarrett Wollman #include <sys/types.h> 717b6ab19dSGarrett Wollman #include <sys/param.h> 727b6ab19dSGarrett Wollman #include <sys/ioctl.h> 737b6ab19dSGarrett Wollman #include <sys/sysctl.h> 747b6ab19dSGarrett Wollman #include <sys/socket.h> 7538ae6523SPoul-Henning Kamp #include <sys/queue.h> 767b6ab19dSGarrett Wollman #include "radix.h" 772c7a9781SMark Murray #define UNUSED __attribute__((unused)) 782c7a9781SMark Murray #define PATTRIB(f,l) __attribute__((format (printf,f,l))) 797b6ab19dSGarrett Wollman #include <net/if.h> 807b6ab19dSGarrett Wollman #include <net/route.h> 817b6ab19dSGarrett Wollman #include <net/if_dl.h> 827b6ab19dSGarrett Wollman #include <netinet/in.h> 837b6ab19dSGarrett Wollman #include <arpa/inet.h> 847b6ab19dSGarrett Wollman #define RIPVERSION RIPv2 857b6ab19dSGarrett Wollman #include <protocols/routed.h> 867b6ab19dSGarrett Wollman 87caa79e36SBruce M Simpson #ifndef __COPYRIGHT 88caa79e36SBruce M Simpson #define __COPYRIGHT(_s) static const char copyright[] UNUSED = _s 89caa79e36SBruce M Simpson #endif 907b6ab19dSGarrett Wollman 917b6ab19dSGarrett Wollman /* Type of an IP address. 927b6ab19dSGarrett Wollman * Some systems do not like to pass structures, so do not use in_addr. 937b6ab19dSGarrett Wollman * Some systems think a long has 64 bits, which would be a gross waste. 947b6ab19dSGarrett Wollman * So define it here so it can be changed for the target system. 957b6ab19dSGarrett Wollman * It should be defined somewhere netinet/in.h, but it is not. 967b6ab19dSGarrett Wollman */ 977b6ab19dSGarrett Wollman #define naddr u_long 987b6ab19dSGarrett Wollman #define _HAVE_SA_LEN 997b6ab19dSGarrett Wollman #define _HAVE_SIN_LEN 1007b6ab19dSGarrett Wollman 101a30febecSGarrett Wollman #define DAY (24*60*60) 102a30febecSGarrett Wollman #define NEVER DAY /* a long time */ 1037b6ab19dSGarrett Wollman #define EPOCH NEVER /* bias time by this to avoid <0 */ 1047b6ab19dSGarrett Wollman 1057b6ab19dSGarrett Wollman /* Scan the kernel regularly to see if any interfaces have appeared or been 1067b6ab19dSGarrett Wollman * turned off. These must be less than STALE_TIME. 1077b6ab19dSGarrett Wollman */ 1087b6ab19dSGarrett Wollman #define CHECK_BAD_INTERVAL 5 /* when an interface is known bad */ 1097b6ab19dSGarrett Wollman #define CHECK_ACT_INTERVAL 30 /* when advertising */ 1107b6ab19dSGarrett Wollman #define CHECK_QUIET_INTERVAL 300 /* when not */ 1117b6ab19dSGarrett Wollman 1127b6ab19dSGarrett Wollman #define LIM_SEC(s,l) ((s).tv_sec = MIN((s).tv_sec, (l))) 1137b6ab19dSGarrett Wollman 11452ad6021SGarrett Wollman /* Metric used for fake default routes. It ought to be 15, but when 11552ad6021SGarrett Wollman * processing advertised routes, previous versions of `routed` added 11652ad6021SGarrett Wollman * to the received metric and discarded the route if the total was 16 11752ad6021SGarrett Wollman * or larger. 11852ad6021SGarrett Wollman */ 11952ad6021SGarrett Wollman #define FAKE_METRIC (HOPCNT_INFINITY-2) 12052ad6021SGarrett Wollman 1217b6ab19dSGarrett Wollman 1227b6ab19dSGarrett Wollman /* Router Discovery parameters */ 1237b6ab19dSGarrett Wollman #define INADDR_ALLROUTERS_GROUP 0xe0000002 /* 224.0.0.2 */ 1247b6ab19dSGarrett Wollman #define MaxMaxAdvertiseInterval 1800 1257b6ab19dSGarrett Wollman #define MinMaxAdvertiseInterval 4 1267b6ab19dSGarrett Wollman #define DefMaxAdvertiseInterval 600 1277b6ab19dSGarrett Wollman #define MIN_PreferenceLevel 0x80000000 1287b6ab19dSGarrett Wollman 1297b6ab19dSGarrett Wollman #define MAX_INITIAL_ADVERT_INTERVAL 16 1307b6ab19dSGarrett Wollman #define MAX_INITIAL_ADVERTS 3 1317b6ab19dSGarrett Wollman 1327b6ab19dSGarrett Wollman #define MAX_SOLICITATION_DELAY 1 1337b6ab19dSGarrett Wollman #define SOLICITATION_INTERVAL 3 1347b6ab19dSGarrett Wollman #define MAX_SOLICITATIONS 3 1357b6ab19dSGarrett Wollman 1367b6ab19dSGarrett Wollman 13752ad6021SGarrett Wollman /* Bloated packet size for systems that simply add authentication to 13852ad6021SGarrett Wollman * full-sized packets 13952ad6021SGarrett Wollman */ 14052ad6021SGarrett Wollman #define OVER_MAXPACKETSIZE (MAXPACKETSIZE+sizeof(struct netinfo)*2) 1417b6ab19dSGarrett Wollman /* typical packet buffers */ 1427b6ab19dSGarrett Wollman union pkt_buf { 14352ad6021SGarrett Wollman char packet[OVER_MAXPACKETSIZE*2]; 1447b6ab19dSGarrett Wollman struct rip rip; 1457b6ab19dSGarrett Wollman }; 1467b6ab19dSGarrett Wollman 1472c7a9781SMark Murray #define GNAME_LEN 64 /* assumed=64 in parms.c */ 1482c7a9781SMark Murray /* bigger than IFNAMSIZ, with room for "external()" or "remote()" */ 1492c7a9781SMark Murray #define IF_NAME_LEN (GNAME_LEN+15) 1507b6ab19dSGarrett Wollman 15152ad6021SGarrett Wollman /* No more routes than this, to protect ourself in case something goes 15252ad6021SGarrett Wollman * whacko and starts broadcasting zillions of bogus routes. 1537b6ab19dSGarrett Wollman */ 1547b6ab19dSGarrett Wollman #define MAX_ROUTES (128*1024) 1557b6ab19dSGarrett Wollman extern int total_routes; 1567b6ab19dSGarrett Wollman 1577b6ab19dSGarrett Wollman /* Main, daemon routing table structure 1587b6ab19dSGarrett Wollman */ 1597b6ab19dSGarrett Wollman struct rt_entry { 1607b6ab19dSGarrett Wollman struct radix_node rt_nodes[2]; /* radix tree glue */ 1617b6ab19dSGarrett Wollman u_int rt_state; 1627b6ab19dSGarrett Wollman # define RS_IF 0x001 /* for network interface */ 1637b6ab19dSGarrett Wollman # define RS_NET_INT 0x002 /* authority route */ 1647b6ab19dSGarrett Wollman # define RS_NET_SYN 0x004 /* fake net route for subnet */ 1657b6ab19dSGarrett Wollman # define RS_NO_NET_SYN (RS_LOCAL | RS_LOCAL | RS_IF) 1667b6ab19dSGarrett Wollman # define RS_SUBNET 0x008 /* subnet route from any source */ 1677b6ab19dSGarrett Wollman # define RS_LOCAL 0x010 /* loopback for pt-to-pt */ 1687b6ab19dSGarrett Wollman # define RS_MHOME 0x020 /* from -m */ 1697b6ab19dSGarrett Wollman # define RS_STATIC 0x040 /* from the kernel */ 1707b6ab19dSGarrett Wollman # define RS_RDISC 0x080 /* from router discovery */ 1717b6ab19dSGarrett Wollman struct sockaddr_in rt_dst_sock; 1727b6ab19dSGarrett Wollman naddr rt_mask; 1737b6ab19dSGarrett Wollman struct rt_spare { 1747b6ab19dSGarrett Wollman struct interface *rts_ifp; 1757b6ab19dSGarrett Wollman naddr rts_gate; /* forward packets here */ 1767b6ab19dSGarrett Wollman naddr rts_router; /* on the authority of this router */ 1777b6ab19dSGarrett Wollman char rts_metric; 1787b6ab19dSGarrett Wollman u_short rts_tag; 1797b6ab19dSGarrett Wollman time_t rts_time; /* timer to junk stale routes */ 1802c7a9781SMark Murray u_int rts_de_ag; /* de-aggregation level */ 1817b6ab19dSGarrett Wollman #define NUM_SPARES 4 1827b6ab19dSGarrett Wollman } rt_spares[NUM_SPARES]; 1837b6ab19dSGarrett Wollman u_int rt_seqno; /* when last changed */ 1847b6ab19dSGarrett Wollman char rt_poison_metric; /* to notice maximum recently */ 1857b6ab19dSGarrett Wollman time_t rt_poison_time; /* advertised metric */ 1867b6ab19dSGarrett Wollman }; 1877b6ab19dSGarrett Wollman #define rt_dst rt_dst_sock.sin_addr.s_addr 1887b6ab19dSGarrett Wollman #define rt_ifp rt_spares[0].rts_ifp 1897b6ab19dSGarrett Wollman #define rt_gate rt_spares[0].rts_gate 1907b6ab19dSGarrett Wollman #define rt_router rt_spares[0].rts_router 1917b6ab19dSGarrett Wollman #define rt_metric rt_spares[0].rts_metric 1927b6ab19dSGarrett Wollman #define rt_tag rt_spares[0].rts_tag 1937b6ab19dSGarrett Wollman #define rt_time rt_spares[0].rts_time 1942c7a9781SMark Murray #define rt_de_ag rt_spares[0].rts_de_ag 1957b6ab19dSGarrett Wollman 1967b6ab19dSGarrett Wollman #define HOST_MASK 0xffffffff 1977b6ab19dSGarrett Wollman #define RT_ISHOST(rt) ((rt)->rt_mask == HOST_MASK) 1987b6ab19dSGarrett Wollman 1997b6ab19dSGarrett Wollman /* age all routes that 2007b6ab19dSGarrett Wollman * are not from -g, -m, or static routes from the kernel 2017b6ab19dSGarrett Wollman * not unbroken interface routes 2027b6ab19dSGarrett Wollman * but not broken interfaces 2037b6ab19dSGarrett Wollman * nor non-passive, remote interfaces that are not aliases 2047b6ab19dSGarrett Wollman * (i.e. remote & metric=0) 2057b6ab19dSGarrett Wollman */ 2067b6ab19dSGarrett Wollman #define AGE_RT(rt_state,ifp) (0 == ((rt_state) & (RS_MHOME | RS_STATIC \ 2077b6ab19dSGarrett Wollman | RS_NET_SYN | RS_RDISC)) \ 2087b6ab19dSGarrett Wollman && (!((rt_state) & RS_IF) \ 2097b6ab19dSGarrett Wollman || (ifp) == 0 \ 2107b6ab19dSGarrett Wollman || (((ifp)->int_state & IS_REMOTE) \ 2117b6ab19dSGarrett Wollman && !((ifp)->int_state & IS_PASSIVE)))) 2127b6ab19dSGarrett Wollman 2137b6ab19dSGarrett Wollman /* true if A is better than B 2147b6ab19dSGarrett Wollman * Better if 2157b6ab19dSGarrett Wollman * - A is not a poisoned route 2167b6ab19dSGarrett Wollman * - and A is not stale 2177b6ab19dSGarrett Wollman * - and A has a shorter path 2187b6ab19dSGarrett Wollman * - or is the router speaking for itself 2197b6ab19dSGarrett Wollman * - or the current route is equal but stale 2207b6ab19dSGarrett Wollman * - or it is a host route advertised by a system for itself 2217b6ab19dSGarrett Wollman */ 2227b6ab19dSGarrett Wollman #define BETTER_LINK(rt,A,B) ((A)->rts_metric < HOPCNT_INFINITY \ 2237b6ab19dSGarrett Wollman && now_stale <= (A)->rts_time \ 2247b6ab19dSGarrett Wollman && ((A)->rts_metric < (B)->rts_metric \ 2257b6ab19dSGarrett Wollman || ((A)->rts_gate == (A)->rts_router \ 2267b6ab19dSGarrett Wollman && (B)->rts_gate != (B)->rts_router) \ 2277b6ab19dSGarrett Wollman || ((A)->rts_metric == (B)->rts_metric \ 2287b6ab19dSGarrett Wollman && now_stale > (B)->rts_time) \ 2297b6ab19dSGarrett Wollman || (RT_ISHOST(rt) \ 2307b6ab19dSGarrett Wollman && (rt)->rt_dst == (A)->rts_router \ 2317b6ab19dSGarrett Wollman && (A)->rts_metric == (B)->rts_metric))) 2327b6ab19dSGarrett Wollman 2337b6ab19dSGarrett Wollman 2347b6ab19dSGarrett Wollman /* An "interface" is similar to a kernel ifnet structure, except it also 2357b6ab19dSGarrett Wollman * handles "logical" or "IS_REMOTE" interfaces (remote gateways). 2367b6ab19dSGarrett Wollman */ 2377b6ab19dSGarrett Wollman struct interface { 23838ae6523SPoul-Henning Kamp LIST_ENTRY(interface) int_list; 2396b6b8280SPoul-Henning Kamp LIST_ENTRY(interface) remote_list; 24052ad6021SGarrett Wollman struct interface *int_ahash, **int_ahash_prev; 24152ad6021SGarrett Wollman struct interface *int_bhash, **int_bhash_prev; 24252ad6021SGarrett Wollman struct interface *int_nhash, **int_nhash_prev; 2432c7a9781SMark Murray char int_name[IF_NAME_LEN+1]; 2447b6ab19dSGarrett Wollman u_short int_index; 2457b6ab19dSGarrett Wollman naddr int_addr; /* address on this host (net order) */ 2467b6ab19dSGarrett Wollman naddr int_brdaddr; /* broadcast address (n) */ 2477b6ab19dSGarrett Wollman naddr int_dstaddr; /* other end of pt-to-pt link (n) */ 2487b6ab19dSGarrett Wollman naddr int_net; /* working network # (host order)*/ 2497b6ab19dSGarrett Wollman naddr int_mask; /* working net mask (host order) */ 2507b6ab19dSGarrett Wollman naddr int_ripv1_mask; /* for inferring a mask (n) */ 2517b6ab19dSGarrett Wollman naddr int_std_addr; /* class A/B/C address (n) */ 2527b6ab19dSGarrett Wollman naddr int_std_net; /* class A/B/C network (h) */ 2537b6ab19dSGarrett Wollman naddr int_std_mask; /* class A/B/C netmask (h) */ 2547b6ab19dSGarrett Wollman int int_rip_sock; /* for queries */ 2557b6ab19dSGarrett Wollman int int_if_flags; /* some bits copied from kernel */ 2567b6ab19dSGarrett Wollman u_int int_state; 2577b6ab19dSGarrett Wollman time_t int_act_time; /* last thought healthy */ 25852ad6021SGarrett Wollman time_t int_query_time; 2597b6ab19dSGarrett Wollman u_short int_transitions; /* times gone up-down */ 2607b6ab19dSGarrett Wollman char int_metric; 261caa79e36SBruce M Simpson u_char int_d_metric; /* for faked default route */ 262caa79e36SBruce M Simpson u_char int_adj_inmetric; /* adjust advertised metrics */ 263caa79e36SBruce M Simpson u_char int_adj_outmetric; /* instead of interface metric */ 2647b6ab19dSGarrett Wollman struct int_data { 2657b6ab19dSGarrett Wollman u_int ipackets; /* previous network stats */ 2667b6ab19dSGarrett Wollman u_int ierrors; 2677b6ab19dSGarrett Wollman u_int opackets; 2687b6ab19dSGarrett Wollman u_int oerrors; 2697b6ab19dSGarrett Wollman time_t ts; /* timestamp on network stats */ 2707b6ab19dSGarrett Wollman } int_data; 271a30febecSGarrett Wollman # define MAX_AUTH_KEYS 5 27252ad6021SGarrett Wollman struct auth { /* authentication info */ 2732c7a9781SMark Murray u_int16_t type; 27452ad6021SGarrett Wollman u_char key[RIP_AUTH_PW_LEN]; 27552ad6021SGarrett Wollman u_char keyid; 27652ad6021SGarrett Wollman time_t start, end; 277a30febecSGarrett Wollman } int_auth[MAX_AUTH_KEYS]; 2782c7a9781SMark Murray /* router discovery parameters */ 2792c7a9781SMark Murray int int_rdisc_pref; /* signed preference to advertise */ 2807b6ab19dSGarrett Wollman int int_rdisc_int; /* MaxAdvertiseInterval */ 2817b6ab19dSGarrett Wollman int int_rdisc_cnt; 2827b6ab19dSGarrett Wollman struct timeval int_rdisc_timer; 2837b6ab19dSGarrett Wollman }; 2847b6ab19dSGarrett Wollman 2857b6ab19dSGarrett Wollman /* bits in int_state */ 2867b6ab19dSGarrett Wollman #define IS_ALIAS 0x0000001 /* interface alias */ 2877b6ab19dSGarrett Wollman #define IS_SUBNET 0x0000002 /* interface on subnetted network */ 2887b6ab19dSGarrett Wollman #define IS_REMOTE 0x0000004 /* interface is not on this machine */ 2897b6ab19dSGarrett Wollman #define IS_PASSIVE 0x0000008 /* remote and does not do RIP */ 2907b6ab19dSGarrett Wollman #define IS_EXTERNAL 0x0000010 /* handled by EGP or something */ 2917b6ab19dSGarrett Wollman #define IS_CHECKED 0x0000020 /* still exists */ 2927b6ab19dSGarrett Wollman #define IS_ALL_HOSTS 0x0000040 /* in INADDR_ALLHOSTS_GROUP */ 2937b6ab19dSGarrett Wollman #define IS_ALL_ROUTERS 0x0000080 /* in INADDR_ALLROUTERS_GROUP */ 29452ad6021SGarrett Wollman #define IS_DISTRUST 0x0000100 /* ignore untrusted routers */ 295a30febecSGarrett Wollman #define IS_REDIRECT_OK 0x0000200 /* accept ICMP redirects */ 296a30febecSGarrett Wollman #define IS_BROKE 0x0000400 /* seems to be broken */ 297a30febecSGarrett Wollman #define IS_SICK 0x0000800 /* seems to be broken */ 298a30febecSGarrett Wollman #define IS_DUP 0x0001000 /* has a duplicate address */ 2997b6ab19dSGarrett Wollman #define IS_NEED_NET_SYN 0x0002000 /* need RS_NET_SYN route */ 3007b6ab19dSGarrett Wollman #define IS_NO_AG 0x0004000 /* do not aggregate subnets */ 3017b6ab19dSGarrett Wollman #define IS_NO_SUPER_AG 0x0008000 /* do not aggregate networks */ 3027b6ab19dSGarrett Wollman #define IS_NO_RIPV1_IN 0x0010000 /* no RIPv1 input at all */ 3037b6ab19dSGarrett Wollman #define IS_NO_RIPV2_IN 0x0020000 /* no RIPv2 input at all */ 3047b6ab19dSGarrett Wollman #define IS_NO_RIP_IN (IS_NO_RIPV1_IN | IS_NO_RIPV2_IN) 3057b6ab19dSGarrett Wollman #define IS_RIP_IN_OFF(s) (((s) & IS_NO_RIP_IN) == IS_NO_RIP_IN) 3067b6ab19dSGarrett Wollman #define IS_NO_RIPV1_OUT 0x0040000 /* no RIPv1 output at all */ 3077b6ab19dSGarrett Wollman #define IS_NO_RIPV2_OUT 0x0080000 /* no RIPv2 output at all */ 3087b6ab19dSGarrett Wollman #define IS_NO_RIP_OUT (IS_NO_RIPV1_OUT | IS_NO_RIPV2_OUT) 3097b6ab19dSGarrett Wollman #define IS_NO_RIP (IS_NO_RIP_OUT | IS_NO_RIP_IN) 3107b6ab19dSGarrett Wollman #define IS_RIP_OUT_OFF(s) (((s) & IS_NO_RIP_OUT) == IS_NO_RIP_OUT) 3117b6ab19dSGarrett Wollman #define IS_RIP_OFF(s) (((s) & IS_NO_RIP) == IS_NO_RIP) 3122c7a9781SMark Murray #define IS_NO_RIP_MCAST 0x0100000 /* broadcast RIPv2 */ 3132c7a9781SMark Murray #define IS_NO_ADV_IN 0x0200000 /* do not listen to advertisements */ 3142c7a9781SMark Murray #define IS_NO_SOL_OUT 0x0400000 /* send no solicitations */ 3152c7a9781SMark Murray #define IS_SOL_OUT 0x0800000 /* send solicitations */ 3162c7a9781SMark Murray #define GROUP_IS_SOL_OUT (IS_SOL_OUT | IS_NO_SOL_OUT) 3172c7a9781SMark Murray #define IS_NO_ADV_OUT 0x1000000 /* do not advertise rdisc */ 3182c7a9781SMark Murray #define IS_ADV_OUT 0x2000000 /* advertise rdisc */ 3192c7a9781SMark Murray #define GROUP_IS_ADV_OUT (IS_NO_ADV_OUT | IS_ADV_OUT) 3202c7a9781SMark Murray #define IS_BCAST_RDISC 0x4000000 /* broadcast instead of multicast */ 3217b6ab19dSGarrett Wollman #define IS_NO_RDISC (IS_NO_ADV_IN | IS_NO_SOL_OUT | IS_NO_ADV_OUT) 3222c7a9781SMark Murray #define IS_PM_RDISC 0x8000000 /* poor-man's router discovery */ 3237b6ab19dSGarrett Wollman 3242c7a9781SMark Murray #define iff_up(f) ((f) & IFF_UP) 3257b6ab19dSGarrett Wollman 32638ae6523SPoul-Henning Kamp LIST_HEAD(ifhead, interface); 3277b6ab19dSGarrett Wollman 3287b6ab19dSGarrett Wollman /* Information for aggregating routes */ 3297b6ab19dSGarrett Wollman #define NUM_AG_SLOTS 32 3307b6ab19dSGarrett Wollman struct ag_info { 3317b6ab19dSGarrett Wollman struct ag_info *ag_fine; /* slot with finer netmask */ 3327b6ab19dSGarrett Wollman struct ag_info *ag_cors; /* more coarse netmask */ 3337b6ab19dSGarrett Wollman naddr ag_dst_h; /* destination in host byte order */ 3347b6ab19dSGarrett Wollman naddr ag_mask; 3357b6ab19dSGarrett Wollman naddr ag_gate; 3367b6ab19dSGarrett Wollman naddr ag_nhop; 3377b6ab19dSGarrett Wollman char ag_metric; /* metric to be advertised */ 3387b6ab19dSGarrett Wollman char ag_pref; /* aggregate based on this */ 3397b6ab19dSGarrett Wollman u_int ag_seqno; 3407b6ab19dSGarrett Wollman u_short ag_tag; 3417b6ab19dSGarrett Wollman u_short ag_state; 34290100551SPhilippe Charnier #define AGS_SUPPRESS 0x001 /* combine with coarser mask */ 3432c7a9781SMark Murray #define AGS_AGGREGATE 0x002 /* synthesize combined routes */ 3447b6ab19dSGarrett Wollman #define AGS_REDUN0 0x004 /* redundant, finer routes output */ 3457b6ab19dSGarrett Wollman #define AGS_REDUN1 0x008 3467b6ab19dSGarrett Wollman #define AG_IS_REDUN(state) (((state) & (AGS_REDUN0 | AGS_REDUN1)) \ 3477b6ab19dSGarrett Wollman == (AGS_REDUN0 | AGS_REDUN1)) 3487b6ab19dSGarrett Wollman #define AGS_GATEWAY 0x010 /* tell kernel RTF_GATEWAY */ 3497b6ab19dSGarrett Wollman #define AGS_IF 0x020 /* for an interface */ 3507b6ab19dSGarrett Wollman #define AGS_RIPV2 0x040 /* send only as RIPv2 */ 3517b6ab19dSGarrett Wollman #define AGS_FINE_GATE 0x080 /* ignore differing ag_gate when this 3527b6ab19dSGarrett Wollman * has the finer netmask */ 3537b6ab19dSGarrett Wollman #define AGS_CORS_GATE 0x100 /* ignore differing gate when this 35490100551SPhilippe Charnier * has the coarser netmasks */ 3557b6ab19dSGarrett Wollman #define AGS_SPLIT_HZ 0x200 /* suppress for split horizon */ 3567b6ab19dSGarrett Wollman 3577b6ab19dSGarrett Wollman /* some bits are set if they are set on either route */ 3582c7a9781SMark Murray #define AGS_AGGREGATE_EITHER (AGS_RIPV2 | AGS_GATEWAY | \ 3597b6ab19dSGarrett Wollman AGS_SUPPRESS | AGS_CORS_GATE) 3607b6ab19dSGarrett Wollman }; 3617b6ab19dSGarrett Wollman 3627b6ab19dSGarrett Wollman 3637b6ab19dSGarrett Wollman /* parameters for interfaces */ 364f2ca6d8aSPoul-Henning Kamp struct parm { 3657b6ab19dSGarrett Wollman struct parm *parm_next; 3662c7a9781SMark Murray char parm_name[IF_NAME_LEN+1]; 36752ad6021SGarrett Wollman naddr parm_net; 3687b6ab19dSGarrett Wollman naddr parm_mask; 3697b6ab19dSGarrett Wollman 370caa79e36SBruce M Simpson u_char parm_d_metric; 371caa79e36SBruce M Simpson u_char parm_adj_inmetric; 372caa79e36SBruce M Simpson char parm_adj_outmetric; 3737b6ab19dSGarrett Wollman u_int parm_int_state; 3742c7a9781SMark Murray int parm_rdisc_pref; /* signed IRDP preference */ 3752c7a9781SMark Murray int parm_rdisc_int; /* IRDP advertising interval */ 376a30febecSGarrett Wollman struct auth parm_auth[MAX_AUTH_KEYS]; 377f2ca6d8aSPoul-Henning Kamp }; 3787b6ab19dSGarrett Wollman 3797b6ab19dSGarrett Wollman /* authority for internal networks */ 3807b6ab19dSGarrett Wollman extern struct intnet { 3817b6ab19dSGarrett Wollman struct intnet *intnet_next; 3822c7a9781SMark Murray naddr intnet_addr; /* network byte order */ 3837b6ab19dSGarrett Wollman naddr intnet_mask; 3847b6ab19dSGarrett Wollman char intnet_metric; 3857b6ab19dSGarrett Wollman } *intnets; 3867b6ab19dSGarrett Wollman 3872c7a9781SMark Murray /* defined RIPv1 netmasks */ 3882c7a9781SMark Murray extern struct r1net { 3892c7a9781SMark Murray struct r1net *r1net_next; 3902c7a9781SMark Murray naddr r1net_net; /* host order */ 3912c7a9781SMark Murray naddr r1net_match; 3922c7a9781SMark Murray naddr r1net_mask; 3932c7a9781SMark Murray } *r1nets; 3942c7a9781SMark Murray 39552ad6021SGarrett Wollman /* trusted routers */ 39652ad6021SGarrett Wollman extern struct tgate { 39752ad6021SGarrett Wollman struct tgate *tgate_next; 39852ad6021SGarrett Wollman naddr tgate_addr; 3992c7a9781SMark Murray #define MAX_TGATE_NETS 32 4002c7a9781SMark Murray struct tgate_net { 4012c7a9781SMark Murray naddr net; /* host order */ 4022c7a9781SMark Murray naddr mask; 4032c7a9781SMark Murray } tgate_nets[MAX_TGATE_NETS]; 40452ad6021SGarrett Wollman } *tgates; 4057b6ab19dSGarrett Wollman 40652ad6021SGarrett Wollman enum output_type {OUT_QUERY, OUT_UNICAST, OUT_BROADCAST, OUT_MULTICAST, 40752ad6021SGarrett Wollman NO_OUT_MULTICAST, NO_OUT_RIPV2}; 40852ad6021SGarrett Wollman 40952ad6021SGarrett Wollman /* common output buffers */ 41052ad6021SGarrett Wollman extern struct ws_buf { 41152ad6021SGarrett Wollman struct rip *buf; 41252ad6021SGarrett Wollman struct netinfo *n; 41352ad6021SGarrett Wollman struct netinfo *base; 41452ad6021SGarrett Wollman struct netinfo *lim; 41552ad6021SGarrett Wollman enum output_type type; 416f2ca6d8aSPoul-Henning Kamp } v12buf; 4177b6ab19dSGarrett Wollman 4187b6ab19dSGarrett Wollman extern pid_t mypid; 4197b6ab19dSGarrett Wollman extern naddr myaddr; /* main address of this system */ 4207b6ab19dSGarrett Wollman 4217b6ab19dSGarrett Wollman extern int stopint; /* !=0 to stop */ 4227b6ab19dSGarrett Wollman 4237b6ab19dSGarrett Wollman extern int rip_sock; /* RIP socket */ 42449694c6dSPoul-Henning Kamp extern const struct interface *rip_sock_mcast; /* current multicast interface */ 4257b6ab19dSGarrett Wollman extern int rt_sock; /* routing socket */ 4267b6ab19dSGarrett Wollman extern int rt_sock_seqno; 4277b6ab19dSGarrett Wollman extern int rdisc_sock; /* router-discovery raw socket */ 4287b6ab19dSGarrett Wollman 4297b6ab19dSGarrett Wollman extern int supplier; /* process should supply updates */ 4307b6ab19dSGarrett Wollman extern int supplier_set; /* -s or -q requested */ 4317b6ab19dSGarrett Wollman extern int ridhosts; /* 1=reduce host routes */ 4327b6ab19dSGarrett Wollman extern int mhome; /* 1=want multi-homed host route */ 43390100551SPhilippe Charnier extern int advertise_mhome; /* 1=must continue advertising it */ 4347b6ab19dSGarrett Wollman extern int auth_ok; /* 1=ignore auth if we do not care */ 435b9f70cedSHiroki Sato extern int insecure; /* Reply to special queries or not */ 4367b6ab19dSGarrett Wollman 43752ad6021SGarrett Wollman extern struct timeval clk; /* system clock's idea of time */ 43852ad6021SGarrett Wollman extern struct timeval epoch; /* system clock when started */ 4397b6ab19dSGarrett Wollman extern struct timeval now; /* current idea of time */ 4407b6ab19dSGarrett Wollman extern time_t now_stale; 4417b6ab19dSGarrett Wollman extern time_t now_expire; 4427b6ab19dSGarrett Wollman extern time_t now_garbage; 4437b6ab19dSGarrett Wollman 4447b6ab19dSGarrett Wollman extern struct timeval age_timer; /* next check of old routes */ 4457b6ab19dSGarrett Wollman extern struct timeval no_flash; /* inhibit flash update until then */ 4467b6ab19dSGarrett Wollman extern struct timeval rdisc_timer; /* next advert. or solicitation */ 4477b6ab19dSGarrett Wollman extern int rdisc_ok; /* using solicited route */ 4487b6ab19dSGarrett Wollman 4497b6ab19dSGarrett Wollman extern struct timeval ifinit_timer; /* time to check interfaces */ 4507b6ab19dSGarrett Wollman 4517b6ab19dSGarrett Wollman extern naddr loopaddr; /* our address on loopback */ 4527b6ab19dSGarrett Wollman extern int tot_interfaces; /* # of remote and local interfaces */ 4537b6ab19dSGarrett Wollman extern int rip_interfaces; /* # of interfaces doing RIP */ 45438ae6523SPoul-Henning Kamp extern struct ifhead ifnet; /* all interfaces */ 4556b6b8280SPoul-Henning Kamp extern struct ifhead remote_if; /* remote interfaces */ 4567b6ab19dSGarrett Wollman extern int have_ripv1_out; /* have a RIPv1 interface */ 4577b6ab19dSGarrett Wollman extern int need_flash; /* flash update needed */ 4587b6ab19dSGarrett Wollman extern struct timeval need_kern; /* need to update kernel table */ 4592c7a9781SMark Murray extern u_int update_seqno; /* a route has changed */ 4607b6ab19dSGarrett Wollman 461a30febecSGarrett Wollman extern int tracelevel, new_tracelevel; 4627b6ab19dSGarrett Wollman #define MAX_TRACELEVEL 4 4637b6ab19dSGarrett Wollman #define TRACEKERNEL (tracelevel >= 4) /* log kernel changes */ 4647b6ab19dSGarrett Wollman #define TRACECONTENTS (tracelevel >= 3) /* display packet contents */ 4657b6ab19dSGarrett Wollman #define TRACEPACKETS (tracelevel >= 2) /* note packets */ 4667b6ab19dSGarrett Wollman #define TRACEACTIONS (tracelevel != 0) 4677b6ab19dSGarrett Wollman extern FILE *ftrace; /* output trace file */ 468534734edSWarner Losh extern char inittracename[PATH_MAX]; 4697b6ab19dSGarrett Wollman 4707b6ab19dSGarrett Wollman extern struct radix_node_head *rhead; 4717b6ab19dSGarrett Wollman 4727b6ab19dSGarrett Wollman 4737b6ab19dSGarrett Wollman 474f2ca6d8aSPoul-Henning Kamp void fix_sock(int, const char *); 475f2ca6d8aSPoul-Henning Kamp void fix_select(void); 476f2ca6d8aSPoul-Henning Kamp void rip_off(void); 477f2ca6d8aSPoul-Henning Kamp void rip_on(struct interface *); 4787b6ab19dSGarrett Wollman 479f2ca6d8aSPoul-Henning Kamp void bufinit(void); 480f2ca6d8aSPoul-Henning Kamp int output(enum output_type, struct sockaddr_in *, 4817b6ab19dSGarrett Wollman struct interface *, struct rip *, int); 482f2ca6d8aSPoul-Henning Kamp void clr_ws_buf(struct ws_buf *, struct auth *); 483f2ca6d8aSPoul-Henning Kamp void rip_query(void); 484f2ca6d8aSPoul-Henning Kamp void rip_bcast(int); 485f2ca6d8aSPoul-Henning Kamp void supply(struct sockaddr_in *, struct interface *, 48652ad6021SGarrett Wollman enum output_type, int, int, int); 4877b6ab19dSGarrett Wollman 488f2ca6d8aSPoul-Henning Kamp void msglog(const char *, ...) PATTRIB(1,2); 48952ad6021SGarrett Wollman struct msg_limit { 490a30febecSGarrett Wollman time_t reuse; 491a30febecSGarrett Wollman struct msg_sub { 49252ad6021SGarrett Wollman naddr addr; 49352ad6021SGarrett Wollman time_t until; 494a30febecSGarrett Wollman # define MSG_SUBJECT_N 8 495a30febecSGarrett Wollman } subs[MSG_SUBJECT_N]; 49652ad6021SGarrett Wollman }; 497f2ca6d8aSPoul-Henning Kamp void msglim(struct msg_limit *, naddr, 4982c7a9781SMark Murray const char *, ...) PATTRIB(3,4); 4997b6ab19dSGarrett Wollman #define LOGERR(msg) msglog(msg ": %s", strerror(errno)) 500f2ca6d8aSPoul-Henning Kamp void logbad(int, const char *, ...) PATTRIB(2,3); 5017b6ab19dSGarrett Wollman #define BADERR(dump,msg) logbad(dump,msg ": %s", strerror(errno)) 5027b6ab19dSGarrett Wollman #ifdef DEBUG 5037b6ab19dSGarrett Wollman #define DBGERR(dump,msg) BADERR(dump,msg) 5047b6ab19dSGarrett Wollman #else 5057b6ab19dSGarrett Wollman #define DBGERR(dump,msg) LOGERR(msg) 5067b6ab19dSGarrett Wollman #endif 507f2ca6d8aSPoul-Henning Kamp char *naddr_ntoa(naddr); 508f2ca6d8aSPoul-Henning Kamp const char *saddr_ntoa(struct sockaddr *); 5097b6ab19dSGarrett Wollman 510f2ca6d8aSPoul-Henning Kamp void *rtmalloc(size_t, const char *); 511f2ca6d8aSPoul-Henning Kamp void timevaladd(struct timeval *, struct timeval *); 512f2ca6d8aSPoul-Henning Kamp void intvl_random(struct timeval *, u_long, u_long); 513f2ca6d8aSPoul-Henning Kamp int getnet(char *, naddr *, naddr *); 514f2ca6d8aSPoul-Henning Kamp int gethost(char *, naddr *); 515f2ca6d8aSPoul-Henning Kamp void gwkludge(void); 516f2ca6d8aSPoul-Henning Kamp const char *parse_parms(char *, int); 517f2ca6d8aSPoul-Henning Kamp const char *check_parms(struct parm *); 518f2ca6d8aSPoul-Henning Kamp void get_parms(struct interface *); 5197b6ab19dSGarrett Wollman 520f2ca6d8aSPoul-Henning Kamp void lastlog(void); 521f2ca6d8aSPoul-Henning Kamp void trace_close(int); 522f2ca6d8aSPoul-Henning Kamp void set_tracefile(const char *, const char *, int); 523f2ca6d8aSPoul-Henning Kamp void tracelevel_msg(const char *, int); 524f2ca6d8aSPoul-Henning Kamp void trace_off(const char*, ...) PATTRIB(1,2); 525f2ca6d8aSPoul-Henning Kamp void set_tracelevel(void); 526f2ca6d8aSPoul-Henning Kamp void trace_flush(void); 527f2ca6d8aSPoul-Henning Kamp void trace_misc(const char *, ...) PATTRIB(1,2); 528f2ca6d8aSPoul-Henning Kamp void trace_act(const char *, ...) PATTRIB(1,2); 529f2ca6d8aSPoul-Henning Kamp void trace_pkt(const char *, ...) PATTRIB(1,2); 530f2ca6d8aSPoul-Henning Kamp void trace_add_del(const char *, struct rt_entry *); 531f2ca6d8aSPoul-Henning Kamp void trace_change(struct rt_entry *, u_int, struct rt_spare *, 5322c7a9781SMark Murray const char *); 533f2ca6d8aSPoul-Henning Kamp void trace_if(const char *, struct interface *); 534f2ca6d8aSPoul-Henning Kamp void trace_upslot(struct rt_entry *, struct rt_spare *, 5352c7a9781SMark Murray struct rt_spare *); 536f2ca6d8aSPoul-Henning Kamp void trace_rip(const char*, const char*, struct sockaddr_in *, 5377b6ab19dSGarrett Wollman struct interface *, struct rip *, int); 538f2ca6d8aSPoul-Henning Kamp char *addrname(naddr, naddr, int); 539f2ca6d8aSPoul-Henning Kamp char *rtname(naddr, naddr, naddr); 5407b6ab19dSGarrett Wollman 541f2ca6d8aSPoul-Henning Kamp void rdisc_age(naddr); 542f2ca6d8aSPoul-Henning Kamp void set_rdisc_mg(struct interface *, int); 543f2ca6d8aSPoul-Henning Kamp void set_supplier(void); 544f2ca6d8aSPoul-Henning Kamp void if_bad_rdisc(struct interface *); 545f2ca6d8aSPoul-Henning Kamp void if_ok_rdisc(struct interface *); 546f2ca6d8aSPoul-Henning Kamp void read_rip(int, struct interface *); 547f2ca6d8aSPoul-Henning Kamp void read_rt(void); 548f2ca6d8aSPoul-Henning Kamp void read_d(void); 549f2ca6d8aSPoul-Henning Kamp void rdisc_adv(void); 550f2ca6d8aSPoul-Henning Kamp void rdisc_sol(void); 5517b6ab19dSGarrett Wollman 552f2ca6d8aSPoul-Henning Kamp void sigtrace_on(int); 553f2ca6d8aSPoul-Henning Kamp void sigtrace_off(int); 5547b6ab19dSGarrett Wollman 555f2ca6d8aSPoul-Henning Kamp void flush_kern(void); 556f2ca6d8aSPoul-Henning Kamp void age(naddr); 5577b6ab19dSGarrett Wollman 558f2ca6d8aSPoul-Henning Kamp void ag_flush(naddr, naddr, void (*)(struct ag_info *)); 559f2ca6d8aSPoul-Henning Kamp void ag_check(naddr, naddr, naddr, naddr, char, char, u_int, 5607b6ab19dSGarrett Wollman u_short, u_short, void (*)(struct ag_info *)); 561f2ca6d8aSPoul-Henning Kamp void del_static(naddr, naddr, naddr, int); 562f2ca6d8aSPoul-Henning Kamp void del_redirects(naddr, time_t); 563f2ca6d8aSPoul-Henning Kamp struct rt_entry *rtget(naddr, naddr); 564f2ca6d8aSPoul-Henning Kamp struct rt_entry *rtfind(naddr); 565f2ca6d8aSPoul-Henning Kamp void rtinit(void); 566f2ca6d8aSPoul-Henning Kamp void rtadd(naddr, naddr, u_int, struct rt_spare *); 567f2ca6d8aSPoul-Henning Kamp void rtchange(struct rt_entry *, u_int, struct rt_spare *, char *); 568f2ca6d8aSPoul-Henning Kamp void rtdelete(struct rt_entry *); 569f2ca6d8aSPoul-Henning Kamp void rts_delete(struct rt_entry *, struct rt_spare *); 570f2ca6d8aSPoul-Henning Kamp void rtbad_sub(struct rt_entry *); 571f2ca6d8aSPoul-Henning Kamp void rtswitch(struct rt_entry *, struct rt_spare *); 5727b6ab19dSGarrett Wollman 5737b6ab19dSGarrett Wollman #define S_ADDR(x) (((struct sockaddr_in *)(x))->sin_addr.s_addr) 5747b6ab19dSGarrett Wollman #define INFO_DST(I) ((I)->rti_info[RTAX_DST]) 5757b6ab19dSGarrett Wollman #define INFO_GATE(I) ((I)->rti_info[RTAX_GATEWAY]) 5767b6ab19dSGarrett Wollman #define INFO_MASK(I) ((I)->rti_info[RTAX_NETMASK]) 5777b6ab19dSGarrett Wollman #define INFO_IFA(I) ((I)->rti_info[RTAX_IFA]) 5787b6ab19dSGarrett Wollman #define INFO_AUTHOR(I) ((I)->rti_info[RTAX_AUTHOR]) 5797b6ab19dSGarrett Wollman #define INFO_BRD(I) ((I)->rti_info[RTAX_BRD]) 5807b6ab19dSGarrett Wollman void rt_xaddrs(struct rt_addrinfo *, struct sockaddr *, struct sockaddr *, 5817b6ab19dSGarrett Wollman int); 5827b6ab19dSGarrett Wollman 583f2ca6d8aSPoul-Henning Kamp naddr std_mask(naddr); 584f2ca6d8aSPoul-Henning Kamp naddr ripv1_mask_net(naddr, struct interface *); 585f2ca6d8aSPoul-Henning Kamp naddr ripv1_mask_host(naddr,struct interface *); 5867b6ab19dSGarrett Wollman #define on_net(a,net,mask) (((ntohl(a) ^ (net)) & (mask)) == 0) 587f2ca6d8aSPoul-Henning Kamp int check_dst(naddr); 588f2ca6d8aSPoul-Henning Kamp struct interface *check_dup(naddr, naddr, naddr, int); 589f2ca6d8aSPoul-Henning Kamp int check_remote(struct interface *); 590f2ca6d8aSPoul-Henning Kamp void ifinit(void); 591f2ca6d8aSPoul-Henning Kamp int walk_bad(struct radix_node *, struct walkarg *); 592f2ca6d8aSPoul-Henning Kamp int if_ok(struct interface *, const char *); 593f2ca6d8aSPoul-Henning Kamp void if_sick(struct interface *); 594f2ca6d8aSPoul-Henning Kamp void if_link(struct interface *); 595f2ca6d8aSPoul-Henning Kamp struct interface *ifwithaddr(naddr addr, int bcast, int remote); 596f2ca6d8aSPoul-Henning Kamp struct interface *ifwithindex(u_short, int); 597f2ca6d8aSPoul-Henning Kamp struct interface *iflookup(naddr); 59852ad6021SGarrett Wollman 599f2ca6d8aSPoul-Henning Kamp struct auth *find_auth(struct interface *); 600f2ca6d8aSPoul-Henning Kamp void end_md5_auth(struct ws_buf *, struct auth *); 60152ad6021SGarrett Wollman 602caa79e36SBruce M Simpson #include <md5.h> 603