1 /* 2 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 * 5 * Copyright (c) 1983, 1988, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgment: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * @(#)defs.h 8.1 (Berkeley) 6/5/93 37 * 38 * $FreeBSD: src/sbin/routed/defs.h,v 1.14 2000/08/11 08:24:38 sheldonh Exp $ 39 */ 40 41 #ifndef _DEFS_H 42 #define _DEFS_H 43 44 #pragma ident "%Z%%M% %I% %E% SMI" 45 46 /* 47 * Definitions for RIPv2 routing process. 48 * 49 * This code is based on the 4.4BSD `routed` daemon, with extensions to 50 * support: 51 * RIPv2, including variable length subnet masks. 52 * Router Discovery 53 * aggregate routes in the kernel tables. 54 * aggregate advertised routes. 55 * maintain spare routes for faster selection of another gateway 56 * when the current gateway dies. 57 * timers on routes with second granularity so that selection 58 * of a new route does not wait 30-60 seconds. 59 * tolerance of static routes. 60 * tell the kernel hop counts. 61 * use of per-interface ip_forwarding state. 62 * 63 * The vestigial support for other protocols has been removed. There 64 * is no likelihood that IETF RIPv1 or RIPv2 will ever be used with 65 * other protocols. The result is far smaller, faster, cleaner, and 66 * perhaps understandable. 67 * 68 * The accumulation of special flags and kludges added over the many 69 * years have been simplified and integrated. 70 */ 71 72 #ifdef __cplusplus 73 extern "C" { 74 #endif 75 76 #include <stdio.h> 77 #include <netdb.h> 78 #include <stdlib.h> 79 #include <unistd.h> 80 #include <errno.h> 81 #include <string.h> 82 #include <stdarg.h> 83 #include <syslog.h> 84 #include <time.h> 85 #include <md5.h> 86 #include <libintl.h> 87 #include <locale.h> 88 #include "radix.h" 89 90 #include <sys/time.h> 91 #include <sys/types.h> 92 #include <sys/param.h> 93 #include <sys/ioctl.h> 94 #include <sys/socket.h> 95 #include <sys/sysmacros.h> 96 97 #include <net/if.h> 98 #include <net/route.h> 99 #include <net/if_dl.h> 100 #include <netinet/in.h> 101 #include <arpa/inet.h> 102 #define RIPVERSION RIPv2 103 #include <protocols/routed.h> 104 105 106 #define DAY (24*60*60) 107 #define NEVER DAY /* a long time */ 108 #define EPOCH NEVER /* bias time by this to avoid <0 */ 109 110 /* 111 * Scan the kernel regularly to see if any interfaces have appeared or been 112 * turned off. 113 */ 114 #define CHECK_BAD_INTERVAL 5 /* when an interface is known bad */ 115 #define CHECK_ACT_INTERVAL 30 /* when advertising */ 116 #define CHECK_QUIET_INTERVAL 300 /* when not */ 117 118 /* 119 * Limit the seconds in the timeval structure "s" to "l" seconds, but only 120 * if l is less than the current seconds in s. This is used to shorten 121 * certain timers to ensure that scheduled events occur sooner than 122 * originally scheduled. 123 */ 124 #define LIM_SEC(s, l) ((s).tv_sec = MIN((s).tv_sec, (l))) 125 126 /* 127 * Metric used for fake default routes. It ought to be 15, but when 128 * processing advertised routes, previous versions of `routed` added 129 * to the received metric and discarded the route if the total was 16 130 * or larger. 131 */ 132 #define FAKE_METRIC (HOPCNT_INFINITY-2) 133 134 135 /* Router Discovery parameters */ 136 #define MAX_MAXADVERTISEINTERVAL 1800 137 #define MIN_MAXADVERTISEINTERVAL 4 138 #define DEF_MAXADVERTISEINTERVAL 600 139 #define DEF_PREFERENCELEVEL 0 140 #define MIN_PREFERENCELEVEL 0x80000000 141 142 #define MAX_INITIAL_ADVERT_INTERVAL 16 143 #define MAX_INITIAL_ADVERTS 3 144 #define MAX_RESPONSE_DELAY 2 145 146 #define MAX_SOLICITATION_DELAY 1 147 #define SOLICITATION_INTERVAL 3 148 #define MAX_SOLICITATIONS 3 149 150 /* 151 * convert between signed, balanced around zero, 152 * and unsigned zero-based preferences 153 */ 154 #define SIGN_PREF(p) ((p) ^ MIN_PREFERENCELEVEL) 155 #define UNSIGN_PREF(p) SIGN_PREF(p) 156 157 /* 158 * Bloated packet size for systems that simply add authentication to 159 * full-sized packets 160 */ 161 #define OVER_MAXPACKETSIZE (MAXPACKETSIZE+sizeof (struct netinfo)*2) 162 /* typical packet buffers */ 163 union pkt_buf { 164 uint8_t packet[OVER_MAXPACKETSIZE*2]; 165 struct rip rip; 166 }; 167 168 extern struct dr *drs; 169 170 /* 171 * IF_NAME_LEN is the maximum size of interface names represented within 172 * in.routed. Regular Solaris interfaces have names of at most LIFNAMESIZ 173 * characters, but in.routed has remote interfaces represented internally 174 * as "remote(<gatewayname>)", where <gatewayname> is a hostname or IP 175 * address. IF_NAME_LEN needs to be large enough to also hold such 176 * interface names as well. 177 */ 178 #define IF_NAME_LEN (MAXHOSTNAMELEN + sizeof ("remote()") + 1) 179 180 /* 181 * No more routes than this, to protect ourself in case something goes 182 * whacko and starts broadcasting zillions of bogus routes. 183 */ 184 #define MAX_ROUTES (128*1024) 185 186 enum origin { 187 RO_NONE, /* empty slot */ 188 RO_RIP, /* learnt from RIP */ 189 RO_RDISC, /* learnt from RDISC */ 190 RO_STATIC, /* learnt from kernel */ 191 RO_LOOPBCK, /* loopback route */ 192 RO_PTOPT, /* point-to-point route */ 193 RO_NET_SYN, /* fake net route for subnet */ 194 RO_IF, /* interface route */ 195 RO_FILE /* from /etc/gateways */ 196 }; 197 198 /* 199 * Main, daemon routing table structure 200 */ 201 struct rt_spare { 202 struct interface *rts_ifp; 203 uint32_t rts_gate; /* forward packets here */ 204 uint32_t rts_router; /* on this router's authority */ 205 uint8_t rts_metric; 206 enum origin rts_origin; 207 uint16_t rts_tag; 208 time_t rts_time; /* timer to junk stale routes */ 209 uint32_t rts_de_ag; /* de-aggregation level */ 210 uint16_t rts_flags; 211 }; 212 213 #define RTS_EXTERNAL 0x0001 /* handled by other routing protocol e.g. EGP */ 214 #define SPARE_INC 2 215 #define EMPTY_RT_SPARE { NULL, 0, 0, HOPCNT_INFINITY, RO_NONE, 0, 0, 0, 0 } 216 217 struct rt_entry { 218 struct radix_node rt_nodes[2]; /* radix tree glue */ 219 struct sockaddr_in rt_dst_sock; 220 time_t rt_poison_time; /* advertised metric */ 221 in_addr_t rt_mask; 222 uint32_t rt_seqno; /* when last changed */ 223 uint16_t rt_state; 224 #define RS_IF 0x0001 /* for network interface */ 225 #define RS_NET_INT 0x0002 /* authority route */ 226 #define RS_NET_SYN 0x0004 /* fake net route for subnet */ 227 #define RS_NO_NET_SYN (RS_LOCAL | RS_IF) 228 #define RS_SUBNET 0x0008 /* subnet route from any source */ 229 #define RS_LOCAL 0x0010 /* loopback for pt-to-pt */ 230 #define RS_MHOME 0x0020 /* from -m */ 231 #define RS_STATIC 0x0040 /* from the kernel */ 232 #define RS_NOPROPAGATE 0x0080 /* route which must not be propagated */ 233 #define RS_BADIF 0x0100 /* route through dead ifp */ 234 235 uint8_t rt_poison_metric; /* to notice maximum recently */ 236 uint_t rt_num_spares; 237 struct rt_spare *rt_spares; 238 }; 239 #define rt_dst rt_dst_sock.sin_addr.s_addr 240 #define rt_ifp rt_spares[0].rts_ifp 241 #define rt_gate rt_spares[0].rts_gate 242 #define rt_router rt_spares[0].rts_router 243 #define rt_metric rt_spares[0].rts_metric 244 #define rt_tag rt_spares[0].rts_tag 245 #define rt_time rt_spares[0].rts_time 246 #define rt_de_ag rt_spares[0].rts_de_ag 247 248 #define HOST_MASK 0xffffffffU 249 #define RT_ISHOST(rt) ((rt)->rt_mask == HOST_MASK) 250 251 /* 252 * Determine if a route should be aged. Age all routes that are: 253 * Not from -g, -m, nor static routes from the kernel 254 * not unbroken interface routes but not broken interfaces 255 * not learnt from RDISC or from /etc/gateways 256 * nor non-passive, remote interfaces that are not aliases 257 * (i.e. remote & metric=0) 258 */ 259 #define AGE_RT(rt_state, rts_origin, ifp) \ 260 ((!((rt_state) & (RS_MHOME | RS_STATIC | RS_NET_SYN)) && \ 261 (rts_origin != RO_RDISC) && \ 262 (rts_origin != RO_FILE)) && \ 263 (!((rt_state) & RS_IF) || \ 264 (ifp) == NULL || \ 265 (((ifp)->int_state & IS_REMOTE) && \ 266 !((ifp)->int_state & IS_PASSIVE)))) 267 268 /* 269 * true if A is better than B 270 * Better if 271 * - A is not a poisoned route 272 * - and A is not stale 273 * - and either: 274 * - A has a shorter path 275 * - or the router is speaking for itself 276 * - or B has the same metric and isn't stale 277 * - or A is a host route advertised by a system for itself 278 */ 279 #define BETTER_LINK(rt, A, B) ((A)->rts_metric < HOPCNT_INFINITY && \ 280 now_stale <= (A)->rts_time && \ 281 ((A)->rts_metric < (B)->rts_metric || \ 282 ((A)->rts_gate == (A)->rts_router && \ 283 (B)->rts_gate != (B)->rts_router) || \ 284 ((A)->rts_metric == (B)->rts_metric && \ 285 now_stale > (B)->rts_time) || \ 286 (RT_ISHOST(rt) && \ 287 (rt)->rt_dst == (A)->rts_router && \ 288 (A)->rts_metric == (B)->rts_metric))) 289 290 struct hlinkage { 291 void *hl_next; 292 void **hl_prev; 293 }; 294 295 /* 296 * A "physical_interface" represents the actual hardware. It is also 297 * a container for a list of the interfaces that have the same ifIndex 298 * number. This will consist of zero or one "main" interface plus 299 * zero or more IS_ALIAS interfaces. 300 */ 301 struct physical_interface { 302 struct hlinkage phyi_link; 303 uint32_t phyi_index; 304 struct interface *phyi_interface; 305 struct phyi_data { 306 uint32_t ipackets; /* previous network stats */ 307 uint32_t ierrors; 308 uint32_t opackets; 309 uint32_t oerrors; 310 time_t ts; /* timestamp on network stats */ 311 } phyi_data; 312 char phyi_name[IF_NAME_LEN+1]; 313 }; 314 315 /* 316 * An "interface" is similar to a kernel ifnet structure, except it also 317 * handles "logical" or "IS_REMOTE" interfaces (remote gateways). 318 */ 319 struct interface { 320 /* 321 * We keep interfaces in a variety of data structures to 322 * optimize for different types of searches. 323 */ 324 struct hlinkage int_link; 325 #define int_next int_link.hl_next 326 struct hlinkage int_ahash; /* by address */ 327 struct hlinkage int_bhash; /* by broadcast address */ 328 struct hlinkage int_nhash; /* by name */ 329 struct hlinkage int_ilist; /* ifIndex list */ 330 struct physical_interface *int_phys; /* backpointer */ 331 char int_name[IF_NAME_LEN+1]; 332 in_addr_t int_addr; /* address on this host (net order) */ 333 in_addr_t int_brdaddr; /* broadcast address (n) */ 334 in_addr_t int_dstaddr; /* other end of pt-to-pt link (n) */ 335 in_addr_t int_net; /* working network # (host order) */ 336 in_addr_t int_mask; /* working net mask (host order) */ 337 in_addr_t int_ripv1_mask; /* for inferring a mask (n) */ 338 in_addr_t int_std_addr; /* class A/B/C address (n) */ 339 in_addr_t int_std_net; /* class A/B/C network (h) */ 340 in_addr_t int_std_mask; /* class A/B/C netmask (h) */ 341 in_addr_t int_ripout_addr; /* RIP pkts sent to this addr */ 342 uint64_t int_if_flags; /* some bits copied from kernel */ 343 uint32_t int_state; 344 time_t int_act_time; /* last thought healthy (IS_REMOTE) */ 345 time_t int_query_time; /* last query (IS_REMOTE) */ 346 uint32_t int_transitions; /* times gone up-down */ 347 uint8_t int_metric; 348 uint8_t int_d_metric; /* for faked default route */ 349 #define MAX_AUTH_KEYS 5 350 struct auth { /* authentication info */ 351 time_t start, end; 352 uint16_t type; 353 /* 354 * Although the following key is just an array of bytes, 355 * in.routed is currently limited to ascii characters 356 * because of its configuration syntax and parsing. 357 */ 358 uint8_t key[RIP_AUTH_PW_LEN +1]; 359 uint8_t keyid; 360 uint8_t warnedflag; 361 } int_auth[MAX_AUTH_KEYS]; 362 /* router discovery parameters */ 363 int int_rdisc_pref; /* signed preference to advertise */ 364 uint32_t int_rdisc_int; /* MaxAdvertiseInterval */ 365 uint32_t int_rdisc_cnt; 366 struct timeval int_rdisc_timer; 367 }; 368 369 /* bits in int_state */ 370 #define IS_ALIAS 0x00000001 /* interface alias */ 371 #define IS_SUBNET 0x00000002 /* interface on subnetted network */ 372 #define IS_REMOTE 0x00000004 /* interface is not on this machine */ 373 #define IS_PASSIVE 0x00000008 /* remote and does not do RIP */ 374 #define IS_EXTERNAL 0x00000010 /* handled by EGP or something */ 375 #define IS_CHECKED 0x00000020 /* still exists */ 376 #define IS_ALL_HOSTS 0x00000040 /* in INADDR_ALLHOSTS_GROUP */ 377 #define IS_ALL_ROUTERS 0x00000080 /* in INADDR_ALLROUTERS_GROUP */ 378 #define IS_DISTRUST 0x00000100 /* ignore untrusted routers */ 379 #define IS_REDIRECT_OK 0x00000200 /* accept ICMP redirects */ 380 #define IS_BROKE 0x00000400 /* seems to be broken */ 381 #define IS_SICK 0x00000800 /* seems to be broken */ 382 #define IS_DUP 0x00001000 /* duplicates another interface */ 383 #define IS_NEED_NET_SYN 0x00002000 /* need RS_NET_SYN route */ 384 #define IS_NO_AG 0x00004000 /* do not aggregate subnets */ 385 #define IS_NO_SUPER_AG 0x00008000 /* do not aggregate networks */ 386 #define IS_NO_RIPV1_IN 0x00010000 /* no RIPv1 input at all */ 387 #define IS_NO_RIPV2_IN 0x00020000 /* no RIPv2 input at all */ 388 #define IS_NO_RIP_IN (IS_NO_RIPV1_IN | IS_NO_RIPV2_IN) 389 #define IS_RIP_IN_OFF(s) (((s) & IS_NO_RIP_IN) == IS_NO_RIP_IN) 390 #define IS_NO_RIPV1_OUT 0x00040000 /* no RIPv1 output at all */ 391 #define IS_NO_RIPV2_OUT 0x00080000 /* no RIPv2 output at all */ 392 #define IS_NO_RIP_OUT (IS_NO_RIPV1_OUT | IS_NO_RIPV2_OUT) 393 #define IS_NO_RIP (IS_NO_RIP_OUT | IS_NO_RIP_IN) 394 #define IS_RIP_OUT_OFF(s) (((s) & IS_NO_RIP_OUT) == IS_NO_RIP_OUT) 395 #define IS_RIP_OFF(s) (((s) & IS_NO_RIP) == IS_NO_RIP) 396 #define IS_NO_RIP_MCAST 0x00100000 /* broadcast RIPv2 */ 397 #define IS_NO_ADV_IN 0x00200000 /* do not listen to advertisements */ 398 #define IS_NO_SOL_OUT 0x00400000 /* send no solicitations */ 399 #define IS_SOL_OUT 0x00800000 /* send solicitations */ 400 #define GROUP_IS_SOL_OUT (IS_SOL_OUT | IS_NO_SOL_OUT) 401 #define IS_NO_ADV_OUT 0x01000000 /* do not advertise rdisc */ 402 #define IS_ADV_OUT 0x02000000 /* advertise rdisc */ 403 #define GROUP_IS_ADV_OUT (IS_NO_ADV_OUT | IS_ADV_OUT) 404 #define IS_BCAST_RDISC 0x04000000 /* broadcast instead of multicast */ 405 #define IS_NO_RDISC (IS_NO_ADV_IN | IS_NO_SOL_OUT | IS_NO_ADV_OUT) 406 #define IS_PM_RDISC 0x08000000 /* poor-man's router discovery */ 407 #define IS_NO_HOST 0x10000000 /* disallow host routes */ 408 #define IS_SUPPRESS_RDISC 0x20000000 /* don't send rdisc advs */ 409 #define IS_FLUSH_RDISC 0x40000000 /* flush client rdisc caches */ 410 411 /* 412 * passive interfaces are added through gwkludge 413 */ 414 #define IS_PASSIVE_IFP(ifp) \ 415 (((ifp)->int_state & (IS_REMOTE|IS_PASSIVE|IS_EXTERNAL|IS_ALIAS)) == \ 416 (IS_REMOTE|IS_PASSIVE)) 417 418 /* 419 * Is an IP interface up? Because of the way IPMP uses deprecated 420 * interfaces, we need to check more than the IFF_UP and IFF_RUNNING 421 * interface flags here. Basically, we do not want to use IFF_DEPRECATED 422 * interfaces unless they are also IFF_STANDBY and not IFF_INACTIVE. 423 */ 424 #define IFF_GOOD (IFF_UP|IFF_RUNNING) 425 #define IS_IFF_UP(f) \ 426 ((((f) & (IFF_GOOD|IFF_DEPRECATED)) == IFF_GOOD) || \ 427 (((f) & (IFF_GOOD|IFF_INACTIVE|IFF_STANDBY)) == \ 428 (IFF_GOOD|IFF_STANDBY))) 429 430 /* 431 * This defines interfaces that we should not use for advertising or 432 * soliciting routes by way of RIP and rdisc. Interfaces marked this 433 * way do not count for purposes of determining how many interfaces 434 * this router has. 435 */ 436 #define IS_IFF_QUIET(f) ((f) & (IFF_LOOPBACK|IFF_NORTEXCH|IFF_NOXMIT)) 437 438 /* 439 * This defines interfaces that we can use for advertising routes by way of 440 * RIP and rdisc. 441 */ 442 #define IS_IFF_ROUTING(f) \ 443 (((f) & IFF_ROUTER) && !((f) & (IFF_NORTEXCH|IFF_NOXMIT))) 444 445 /* Information for aggregating routes */ 446 #define NUM_AG_SLOTS 32 447 struct ag_info { 448 struct ag_info *ag_fine; /* slot with finer netmask */ 449 struct ag_info *ag_cors; /* more coarse netmask */ 450 in_addr_t ag_dst_h; /* destination in host byte order */ 451 in_addr_t ag_mask; 452 in_addr_t ag_gate; 453 struct interface *ag_ifp; 454 in_addr_t ag_nhop; 455 uint8_t ag_metric; /* metric to be advertised */ 456 uint8_t ag_pref; /* aggregate based on this */ 457 uint32_t ag_seqno; 458 uint16_t ag_tag; 459 uint16_t ag_state; 460 #define AGS_SUPPRESS 0x001 /* combine with coarser mask */ 461 #define AGS_AGGREGATE 0x002 /* synthesize combined routes */ 462 #define AGS_REDUN0 0x004 /* redundant, finer routes output */ 463 #define AGS_REDUN1 0x008 464 #define AG_IS_REDUN(state) (((state) & (AGS_REDUN0 | AGS_REDUN1)) \ 465 == (AGS_REDUN0 | AGS_REDUN1)) 466 #define AGS_GATEWAY 0x010 /* tell kernel RTF_GATEWAY */ 467 #define AGS_IF 0x020 /* for an interface */ 468 #define AGS_RIPV2 0x040 /* send only as RIPv2 */ 469 #define AGS_FINE_GATE 0x080 /* ignore differing ag_gate when */ 470 /* this has the finer netmask */ 471 #define AGS_CORS_GATE 0x100 /* ignore differing gate when this */ 472 /* has the coarser netmasks */ 473 #define AGS_SPLIT_HZ 0x200 /* suppress for split horizon */ 474 #define AGS_PASSIVE 0x400 /* passive "remote" interface route */ 475 #define AGS_FILE 0x800 /* from /etc/gateways */ 476 477 /* some bits are set if they are set on either route */ 478 #define AGS_AGGREGATE_EITHER (AGS_RIPV2 | AGS_GATEWAY | \ 479 AGS_SUPPRESS | AGS_CORS_GATE) 480 }; 481 482 struct khash { 483 struct khash *k_next; 484 in_addr_t k_dst; 485 in_addr_t k_mask; 486 in_addr_t k_gate; 487 struct interface *k_ifp; 488 short k_metric; 489 ushort_t k_state; /* KS_* */ 490 time_t k_keep; 491 time_t k_redirect_time; /* when redirected route 1st seen */ 492 }; 493 494 /* bit flags for k_state; shared between table.c and trace.c */ 495 #define KS_NEW 0x0001 496 #define KS_DELETE 0x0002 /* need to delete the route */ 497 #define KS_ADD 0x0004 /* add to the kernel */ 498 #define KS_CHANGE 0x0008 /* tell kernel to change the route */ 499 #define KS_DEL_ADD 0x0010 /* delete & add to change the kernel */ 500 #define KS_STATIC 0x0020 /* Static flag in kernel */ 501 #define KS_GATEWAY 0x0040 /* G flag in kernel */ 502 #define KS_DYNAMIC 0x0080 /* result of redirect */ 503 #define KS_DELETED 0x0100 /* already deleted from kernel */ 504 #define KS_PRIVATE 0x0200 /* Private flag in kernel */ 505 #define KS_CHECK 0x0400 506 #define KS_IF 0x0800 /* interface route */ 507 #define KS_PASSIVE 0x1000 /* passive remote interface route */ 508 #define KS_DEPRE_IF 0x2000 /* IPMP deprecated interface route */ 509 #define KS_FILE 0x4000 /* from /etc/gateways */ 510 511 /* default router structure */ 512 struct dr { /* accumulated advertisements */ 513 struct interface *dr_ifp; 514 in_addr_t dr_gate; /* gateway */ 515 time_t dr_ts; /* when received */ 516 time_t dr_life; /* lifetime in host byte order */ 517 uint32_t dr_recv_pref; /* received but biased preference */ 518 uint32_t dr_pref; /* preference adjusted by metric */ 519 uint32_t dr_flags; 520 #define DR_CHANGED 1 /* received new info for known dr */ 521 }; 522 523 /* parameters for interfaces */ 524 struct parm { 525 struct parm *parm_next; 526 in_addr_t parm_net; 527 in_addr_t parm_mask; 528 in_addr_t parm_ripout_addr; 529 uint32_t parm_int_state; 530 int32_t parm_rdisc_pref; /* signed IRDP preference */ 531 uint32_t parm_rdisc_int; /* IRDP advertising interval */ 532 struct auth parm_auth[MAX_AUTH_KEYS]; 533 char parm_name[IF_NAME_LEN+1]; 534 uint8_t parm_d_metric; 535 }; 536 537 /* authority for internal networks */ 538 extern struct intnet { 539 struct intnet *intnet_next; 540 in_addr_t intnet_addr; /* network byte order */ 541 in_addr_t intnet_mask; 542 int8_t intnet_metric; 543 } *intnets; 544 545 /* 546 * Defined RIPv1 netmasks. These come from ripv1_mask entries in 547 * /etc/gateways of the form: 548 * 549 * ripv1_mask=<net>/<match>,<mask> 550 * 551 * The intended use of these structures is to give RIPv1 destinations which 552 * are in <net>/<match> a netmask of <mask>, where <mask> > <match>. 553 */ 554 extern struct r1net { 555 struct r1net *r1net_next; 556 in_addr_t r1net_net; /* host order */ 557 in_addr_t r1net_match; 558 in_addr_t r1net_mask; 559 } *r1nets; 560 561 /* trusted routers */ 562 extern struct tgate { 563 struct tgate *tgate_next; 564 in_addr_t tgate_addr; 565 #define MAX_TGATE_NETS 32 566 struct tgate_net { 567 in_addr_t net; /* host order */ 568 in_addr_t mask; 569 } tgate_nets[MAX_TGATE_NETS]; 570 } *tgates; 571 572 enum output_type {OUT_QUERY, OUT_UNICAST, OUT_BROADCAST, OUT_MULTICAST, 573 NO_OUT_MULTICAST, NO_OUT_RIPV2}; 574 575 /* common output buffers */ 576 extern struct ws_buf { 577 struct rip *buf; 578 struct netinfo *n; 579 struct netinfo *base; 580 struct netinfo *lim; 581 enum output_type type; 582 } v12buf; 583 584 extern int stopint; /* !=0 to stop in.routed */ 585 586 extern int rip_sock; /* RIP socket */ 587 extern struct interface *rip_sock_interface; /* current output interface */ 588 extern int rt_sock; /* routing socket */ 589 extern int rdisc_sock; /* router-discovery raw socket */ 590 extern int rdisc_mib_sock; /* AF_UNIX mib info socket */ 591 592 extern boolean_t rip_enabled; /* is rip on? */ 593 extern boolean_t supplier; /* process should supply updates */ 594 extern boolean_t supplier_set; /* -s or -q requested */ 595 extern boolean_t save_space; /* -S option 1=treat all RIP speakers */ 596 extern boolean_t ridhosts; /* 1=reduce host routes */ 597 extern boolean_t mhome; /* 1=want multi-homed host route */ 598 extern boolean_t advertise_mhome; /* 1=must continue advertising it */ 599 extern boolean_t auth_ok; /* 1=ignore auth if we do not care */ 600 extern boolean_t no_install; /* 1=don't install in kernel */ 601 602 extern struct timeval clk; /* system clock's idea of time */ 603 extern struct timeval epoch; /* system clock when started */ 604 extern struct timeval now; /* current idea of time */ 605 extern time_t now_stale; 606 extern time_t now_expire; 607 extern time_t now_garbage; 608 609 extern struct timeval age_timer; /* next check of old routes */ 610 extern struct timeval no_flash; /* inhibit flash update until then */ 611 extern struct timeval rdisc_timer; /* next advert. or solicitation */ 612 extern boolean_t rdisc_ok; /* using solicited route */ 613 614 extern struct timeval ifscan_timer; /* time to check interfaces */ 615 616 extern in_addr_t loopaddr; /* our address on loopback */ 617 extern uint_t tot_interfaces; /* # of remote and local interfaces */ 618 extern uint_t rip_interfaces; /* # of interfaces doing RIP */ 619 extern uint_t ripout_interfaces; /* # of interfaces advertising RIP */ 620 extern uint_t fwd_interfaces; /* # of interfaces ip_forwarding=1 */ 621 extern struct interface *ifnet; /* all interfaces */ 622 extern size_t hash_table_sizes[]; /* list of primes for hash tables */ 623 extern boolean_t have_ripv1_out; /* have a RIPv1 interface */ 624 extern boolean_t need_flash; /* flash update needed */ 625 extern struct timeval need_kern; /* need to update kernel table */ 626 extern uint32_t update_seqno; /* a route has changed */ 627 extern struct interface dummy_ifp; /* wildcard interface */ 628 629 extern int tracelevel, new_tracelevel; 630 #define MAX_TRACELEVEL 5 631 #define TRACERTS (tracelevel >= 5) /* log routing socket contents */ 632 #define TRACEKERNEL (tracelevel >= 4) /* log kernel changes */ 633 #define TRACECONTENTS (tracelevel >= 3) /* display packet contents */ 634 #define TRACEPACKETS (tracelevel >= 2) /* note packets */ 635 #define TRACEACTIONS (tracelevel != 0) 636 extern FILE *ftrace; /* output trace file */ 637 extern char inittracename[MAXPATHLEN+1]; 638 639 extern struct radix_node_head *rhead; 640 641 extern void fix_sock(int, const char *); 642 extern void fix_select(void); 643 extern void rip_off(void); 644 extern void rip_on(struct interface *); 645 646 extern void bufinit(void); 647 extern int output(enum output_type, struct sockaddr_in *, 648 struct interface *, struct rip *, int); 649 extern void clr_ws_buf(struct ws_buf *, struct auth *); 650 extern void rip_query(void); 651 extern void rip_bcast(int); 652 extern void supply(struct sockaddr_in *, struct interface *, 653 enum output_type, int, int, boolean_t); 654 655 extern void msglog(const char *, ...); 656 extern void writelog(int, const char *, ...); 657 struct msg_limit { 658 time_t reuse; 659 struct msg_sub { 660 in_addr_t addr; 661 time_t until; 662 #define MSG_SUBJECT_N 8 663 } subs[MSG_SUBJECT_N]; 664 }; 665 extern void msglim(struct msg_limit *, in_addr_t, const char *, ...); 666 #define LOGERR(msg) msglog(msg ": %s", rip_strerror(errno)) 667 extern void logbad(boolean_t, const char *, ...); 668 #define BADERR(dump, msg) logbad(dump, msg ": %s", rip_strerror(errno)) 669 #ifdef DEBUG 670 #define DBGERR(dump, msg) BADERR(dump, msg) 671 #else 672 #define DBGERR(dump, msg) LOGERR(msg) 673 #endif 674 extern char *naddr_ntoa(in_addr_t); 675 extern const char *saddr_ntoa(struct sockaddr_storage *); 676 extern const char *rip_strerror(int errnum); 677 extern char *if_bit_string(uint_t, boolean_t); 678 679 extern void *rtmalloc(size_t, const char *); 680 extern void timevaladd(struct timeval *, struct timeval *); 681 extern void intvl_random(struct timeval *, ulong_t, ulong_t); 682 extern boolean_t getnet(const char *, in_addr_t *, in_addr_t *); 683 extern int gethost(char *, in_addr_t *); 684 extern void gwkludge(void); 685 extern const char *parse_parms(char *, boolean_t); 686 extern const char *insert_parm(struct parm *); 687 extern void get_parms(struct interface *); 688 689 extern void lastlog(void); 690 extern void trace_close(int); 691 extern void set_tracefile(const char *, const char *, int); 692 extern void tracelevel_msg(const char *, int); 693 extern void trace_off(const char *, ...); 694 extern void set_tracelevel(void); 695 extern void trace_flush(void); 696 extern void trace_misc(const char *, ...); 697 extern void trace_act(const char *, ...); 698 extern void trace_pkt(const char *, ...); 699 extern void trace_add_del(const char *, struct rt_entry *); 700 extern void trace_change(struct rt_entry *, uint16_t, struct rt_spare *, 701 const char *); 702 extern void trace_if(const char *, struct interface *); 703 extern void trace_khash(const struct khash *); 704 extern void trace_dr(const struct dr *); 705 extern void trace_upslot(struct rt_entry *, struct rt_spare *, 706 struct rt_spare *); 707 extern void trace_rip(const char *, const char *, struct sockaddr_in *, 708 struct interface *, struct rip *, int); 709 extern char *addrname(in_addr_t, in_addr_t, int); 710 extern char *rtname(in_addr_t, in_addr_t, in_addr_t); 711 712 extern void rdisc_age(in_addr_t); 713 extern void set_rdisc_mg(struct interface *, int); 714 extern void set_supplier(void); 715 extern void if_bad_rdisc(struct interface *); 716 extern void if_rewire_rdisc(struct interface *, struct interface *); 717 extern void if_ok_rdisc(struct interface *); 718 extern int read_rip(void); 719 extern void input_route(in_addr_t, in_addr_t, struct rt_spare *, 720 struct netinfo *, uint16_t); 721 extern void read_rt(void); 722 extern void read_d(void); 723 extern void process_d_mib_sock(void); 724 extern void rdisc_adv(boolean_t); 725 extern void rdisc_sol(void); 726 extern struct interface *receiving_interface(struct msghdr *, boolean_t); 727 extern void *find_ancillary(struct msghdr *, int); 728 extern boolean_t should_supply(struct interface *); 729 extern void rdisc_dump(void); 730 extern void rdisc_suppress(struct interface *); 731 extern void rdisc_restore(struct interface *); 732 733 extern void age_peer_info(void); 734 735 extern void sigtrace_more(int); 736 extern void sigtrace_less(int); 737 extern void sigtrace_dump(int); 738 739 extern void sync_kern(void); 740 extern void age(in_addr_t); 741 extern void kern_dump(void); 742 extern void kern_flush_ifp(struct interface *); 743 extern void kern_rewire_ifp(struct interface *, struct interface *); 744 745 extern void ag_flush(in_addr_t, in_addr_t, void (*)(struct ag_info *)); 746 extern void ag_check(in_addr_t, in_addr_t, in_addr_t, struct interface *, 747 in_addr_t, uint8_t, uint8_t, uint32_t, uint16_t, uint16_t, 748 void (*)(struct ag_info *)); 749 extern void del_static(in_addr_t, in_addr_t, in_addr_t, 750 struct interface *, int); 751 extern void del_redirects(in_addr_t, time_t); 752 extern struct rt_entry *rtget(in_addr_t, in_addr_t); 753 extern struct rt_entry *rtfind(in_addr_t); 754 extern void rtinit(void); 755 extern void rtadd(in_addr_t, in_addr_t, uint16_t, struct rt_spare *); 756 extern void rtchange(struct rt_entry *, uint16_t, struct rt_spare *, 757 char *); 758 extern void rtdelete(struct rt_entry *); 759 extern void rts_delete(struct rt_entry *, struct rt_spare *); 760 extern void rtbad_sub(struct rt_entry *, struct interface *); 761 extern void rtswitch(struct rt_entry *, struct rt_spare *); 762 763 #define S_ADDR(x) (((struct sockaddr_in *)(x))->sin_addr.s_addr) 764 #define INFO_DST(I) ((I)->rti_info[RTAX_DST]) 765 #define INFO_GATE(I) ((I)->rti_info[RTAX_GATEWAY]) 766 #define INFO_MASK(I) ((I)->rti_info[RTAX_NETMASK]) 767 #define INFO_AUTHOR(I) ((I)->rti_info[RTAX_AUTHOR]) 768 769 struct rewire_data { 770 struct interface *if_old; 771 struct interface *if_new; 772 int metric_delta; 773 }; 774 775 extern char *qstring(const uchar_t *, int); 776 extern in_addr_t std_mask(in_addr_t); 777 extern int parse_quote(char **, const char *, char *, char *, int); 778 extern in_addr_t ripv1_mask_net(in_addr_t, const struct interface *); 779 extern in_addr_t ripv1_mask_host(in_addr_t, const struct interface *); 780 #define on_net(a, net, mask) (((ntohl(a) ^ (net)) & (mask)) == 0) 781 extern boolean_t check_dst(in_addr_t); 782 extern boolean_t remote_address_ok(struct interface *, in_addr_t); 783 extern struct interface *check_dup(const char *, in_addr_t, in_addr_t, 784 in_addr_t, uint64_t, boolean_t); 785 extern boolean_t check_remote(struct interface *); 786 extern void iftbl_alloc(void); 787 extern void ifscan(void); 788 extern int walk_bad(struct radix_node *, void *); 789 extern int walk_rewire(struct radix_node *, void *); 790 extern void if_ok(struct interface *, const char *, boolean_t); 791 extern void if_sick(struct interface *, boolean_t); 792 extern void if_link(struct interface *, uint32_t); 793 extern struct interface *ifwithaddr(in_addr_t, boolean_t, boolean_t); 794 extern struct interface *ifwithindex(ulong_t, boolean_t); 795 extern struct interface *ifwithname(const char *); 796 extern struct interface *findremoteif(in_addr_t); 797 extern struct interface *findifaddr(in_addr_t); 798 extern struct interface *iflookup(in_addr_t); 799 extern struct auth *find_auth(struct interface *); 800 extern void end_md5_auth(struct ws_buf *, struct auth *); 801 extern void rip_mcast_on(struct interface *); 802 extern void rip_mcast_off(struct interface *); 803 extern void trace_dump(); 804 extern int sendtoif(int, const void *, uint_t, uint_t, struct sockaddr_in *, 805 uint_t); 806 807 #ifdef __cplusplus 808 } 809 #endif 810 811 #endif /* _DEFS_H */ 812