xref: /minix3/external/bsd/dhcp/dist/common/tr.c (revision 83ee113ee0d94f3844d44065af2311604e9a30ad)
1*83ee113eSDavid van Moolenbroek /*	$NetBSD: tr.c,v 1.1.1.3 2014/07/12 11:57:48 spz Exp $	*/
2*83ee113eSDavid van Moolenbroek /* tr.c
3*83ee113eSDavid van Moolenbroek 
4*83ee113eSDavid van Moolenbroek    token ring interface support
5*83ee113eSDavid van Moolenbroek    Contributed in May of 1999 by Andrew Chittenden */
6*83ee113eSDavid van Moolenbroek 
7*83ee113eSDavid van Moolenbroek /*
8*83ee113eSDavid van Moolenbroek  * Copyright (c) 2011 by Internet Systems Consortium, Inc. ("ISC")
9*83ee113eSDavid van Moolenbroek  * Copyright (c) 2004-2007,2009 by Internet Systems Consortium, Inc. ("ISC")
10*83ee113eSDavid van Moolenbroek  * Copyright (c) 1996-2003 by Internet Software Consortium
11*83ee113eSDavid van Moolenbroek  *
12*83ee113eSDavid van Moolenbroek  * Permission to use, copy, modify, and distribute this software for any
13*83ee113eSDavid van Moolenbroek  * purpose with or without fee is hereby granted, provided that the above
14*83ee113eSDavid van Moolenbroek  * copyright notice and this permission notice appear in all copies.
15*83ee113eSDavid van Moolenbroek  *
16*83ee113eSDavid van Moolenbroek  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
17*83ee113eSDavid van Moolenbroek  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
18*83ee113eSDavid van Moolenbroek  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
19*83ee113eSDavid van Moolenbroek  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20*83ee113eSDavid van Moolenbroek  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
21*83ee113eSDavid van Moolenbroek  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
22*83ee113eSDavid van Moolenbroek  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23*83ee113eSDavid van Moolenbroek  *
24*83ee113eSDavid van Moolenbroek  *   Internet Systems Consortium, Inc.
25*83ee113eSDavid van Moolenbroek  *   950 Charter Street
26*83ee113eSDavid van Moolenbroek  *   Redwood City, CA 94063
27*83ee113eSDavid van Moolenbroek  *   <info@isc.org>
28*83ee113eSDavid van Moolenbroek  *   https://www.isc.org/
29*83ee113eSDavid van Moolenbroek  */
30*83ee113eSDavid van Moolenbroek 
31*83ee113eSDavid van Moolenbroek #include <sys/cdefs.h>
32*83ee113eSDavid van Moolenbroek __RCSID("$NetBSD: tr.c,v 1.1.1.3 2014/07/12 11:57:48 spz Exp $");
33*83ee113eSDavid van Moolenbroek 
34*83ee113eSDavid van Moolenbroek #include "dhcpd.h"
35*83ee113eSDavid van Moolenbroek 
36*83ee113eSDavid van Moolenbroek #if defined (HAVE_TR_SUPPORT) && \
37*83ee113eSDavid van Moolenbroek 	(defined (PACKET_ASSEMBLY) || defined (PACKET_DECODING))
38*83ee113eSDavid van Moolenbroek #include "includes/netinet/ip.h"
39*83ee113eSDavid van Moolenbroek #include "includes/netinet/udp.h"
40*83ee113eSDavid van Moolenbroek #include "includes/netinet/if_ether.h"
41*83ee113eSDavid van Moolenbroek #include "netinet/if_tr.h"
42*83ee113eSDavid van Moolenbroek #include <sys/time.h>
43*83ee113eSDavid van Moolenbroek 
44*83ee113eSDavid van Moolenbroek /*
45*83ee113eSDavid van Moolenbroek  * token ring device handling subroutines.  These are required as token-ring
46*83ee113eSDavid van Moolenbroek  * does not have a simple on-the-wire header but requires the use of
47*83ee113eSDavid van Moolenbroek  * source routing
48*83ee113eSDavid van Moolenbroek  */
49*83ee113eSDavid van Moolenbroek 
50*83ee113eSDavid van Moolenbroek static int insert_source_routing (struct trh_hdr *trh, struct interface_info* interface);
51*83ee113eSDavid van Moolenbroek static void save_source_routing (struct trh_hdr *trh, struct interface_info* interface);
52*83ee113eSDavid van Moolenbroek static void expire_routes (void);
53*83ee113eSDavid van Moolenbroek 
54*83ee113eSDavid van Moolenbroek /*
55*83ee113eSDavid van Moolenbroek  * As we keep a list of interesting routing information only, a singly
56*83ee113eSDavid van Moolenbroek  * linked list is all we need
57*83ee113eSDavid van Moolenbroek  */
58*83ee113eSDavid van Moolenbroek struct routing_entry {
59*83ee113eSDavid van Moolenbroek         struct routing_entry *next;
60*83ee113eSDavid van Moolenbroek         unsigned char addr[TR_ALEN];
61*83ee113eSDavid van Moolenbroek         unsigned char iface[5];
62*83ee113eSDavid van Moolenbroek         u_int16_t rcf;			/* route control field */
63*83ee113eSDavid van Moolenbroek         u_int16_t rseg[8];		/* routing registers */
64*83ee113eSDavid van Moolenbroek         unsigned long access_time;	/* time we last used this entry */
65*83ee113eSDavid van Moolenbroek };
66*83ee113eSDavid van Moolenbroek 
67*83ee113eSDavid van Moolenbroek static struct routing_entry *routing_info = NULL;
68*83ee113eSDavid van Moolenbroek 
69*83ee113eSDavid van Moolenbroek static int routing_timeout = 10;
70*83ee113eSDavid van Moolenbroek static struct timeval routing_timer;
71*83ee113eSDavid van Moolenbroek 
assemble_tr_header(interface,buf,bufix,to)72*83ee113eSDavid van Moolenbroek void assemble_tr_header (interface, buf, bufix, to)
73*83ee113eSDavid van Moolenbroek 	struct interface_info *interface;
74*83ee113eSDavid van Moolenbroek 	unsigned char *buf;
75*83ee113eSDavid van Moolenbroek 	unsigned *bufix;
76*83ee113eSDavid van Moolenbroek 	struct hardware *to;
77*83ee113eSDavid van Moolenbroek {
78*83ee113eSDavid van Moolenbroek         struct trh_hdr *trh;
79*83ee113eSDavid van Moolenbroek         int hdr_len;
80*83ee113eSDavid van Moolenbroek         struct trllc *llc;
81*83ee113eSDavid van Moolenbroek 
82*83ee113eSDavid van Moolenbroek 
83*83ee113eSDavid van Moolenbroek         /* set up the token header */
84*83ee113eSDavid van Moolenbroek         trh = (struct trh_hdr *) &buf[*bufix];
85*83ee113eSDavid van Moolenbroek         if (interface -> hw_address.hlen - 1 == sizeof (trh->saddr))
86*83ee113eSDavid van Moolenbroek                 memcpy (trh->saddr, &interface -> hw_address.hbuf [1],
87*83ee113eSDavid van Moolenbroek                                     sizeof (trh->saddr));
88*83ee113eSDavid van Moolenbroek         else
89*83ee113eSDavid van Moolenbroek                 memset (trh->saddr, 0x00, sizeof (trh->saddr));
90*83ee113eSDavid van Moolenbroek 
91*83ee113eSDavid van Moolenbroek         if (to && to -> hlen == 7) /* XXX */
92*83ee113eSDavid van Moolenbroek                 memcpy (trh->daddr, &to -> hbuf [1], sizeof trh->daddr);
93*83ee113eSDavid van Moolenbroek         else
94*83ee113eSDavid van Moolenbroek                 memset (trh->daddr, 0xff, sizeof (trh->daddr));
95*83ee113eSDavid van Moolenbroek 
96*83ee113eSDavid van Moolenbroek 	hdr_len = insert_source_routing (trh, interface);
97*83ee113eSDavid van Moolenbroek 
98*83ee113eSDavid van Moolenbroek         trh->ac = AC;
99*83ee113eSDavid van Moolenbroek         trh->fc = LLC_FRAME;
100*83ee113eSDavid van Moolenbroek 
101*83ee113eSDavid van Moolenbroek         /* set up the llc header for snap encoding after the tr header */
102*83ee113eSDavid van Moolenbroek         llc = (struct trllc *)(buf + *bufix + hdr_len);
103*83ee113eSDavid van Moolenbroek         llc->dsap = EXTENDED_SAP;
104*83ee113eSDavid van Moolenbroek         llc->ssap = EXTENDED_SAP;
105*83ee113eSDavid van Moolenbroek         llc->llc = UI_CMD;
106*83ee113eSDavid van Moolenbroek         llc->protid[0] = 0;
107*83ee113eSDavid van Moolenbroek         llc->protid[1] = 0;
108*83ee113eSDavid van Moolenbroek         llc->protid[2] = 0;
109*83ee113eSDavid van Moolenbroek         llc->ethertype = htons(ETHERTYPE_IP);
110*83ee113eSDavid van Moolenbroek 
111*83ee113eSDavid van Moolenbroek         hdr_len += sizeof(struct trllc);
112*83ee113eSDavid van Moolenbroek 
113*83ee113eSDavid van Moolenbroek         *bufix += hdr_len;
114*83ee113eSDavid van Moolenbroek }
115*83ee113eSDavid van Moolenbroek 
116*83ee113eSDavid van Moolenbroek 
117*83ee113eSDavid van Moolenbroek static unsigned char tr_broadcast[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
118*83ee113eSDavid van Moolenbroek 
119*83ee113eSDavid van Moolenbroek /*
120*83ee113eSDavid van Moolenbroek  * decoding the token header is a bit complex as you can see here. It is
121*83ee113eSDavid van Moolenbroek  * further complicated by the linux kernel stripping off some valuable
122*83ee113eSDavid van Moolenbroek  * information (see comment below) even though we've asked for the raw
123*83ee113eSDavid van Moolenbroek  * packets.
124*83ee113eSDavid van Moolenbroek  */
decode_tr_header(interface,buf,bufix,from)125*83ee113eSDavid van Moolenbroek ssize_t decode_tr_header (interface, buf, bufix, from)
126*83ee113eSDavid van Moolenbroek         struct interface_info *interface;
127*83ee113eSDavid van Moolenbroek         unsigned char *buf;
128*83ee113eSDavid van Moolenbroek         unsigned bufix;
129*83ee113eSDavid van Moolenbroek         struct hardware *from;
130*83ee113eSDavid van Moolenbroek {
131*83ee113eSDavid van Moolenbroek         struct trh_hdr *trh = (struct trh_hdr *) buf + bufix;
132*83ee113eSDavid van Moolenbroek         struct trllc *llc;
133*83ee113eSDavid van Moolenbroek 	struct ip *ip;
134*83ee113eSDavid van Moolenbroek 	struct udphdr *udp;
135*83ee113eSDavid van Moolenbroek         unsigned int route_len = 0;
136*83ee113eSDavid van Moolenbroek         ssize_t hdr_len;
137*83ee113eSDavid van Moolenbroek         struct timeval now;
138*83ee113eSDavid van Moolenbroek 
139*83ee113eSDavid van Moolenbroek         /* see whether any source routing information has expired */
140*83ee113eSDavid van Moolenbroek         gettimeofday(&now, NULL);
141*83ee113eSDavid van Moolenbroek 
142*83ee113eSDavid van Moolenbroek 	if (routing_timer.tv_sec == 0)
143*83ee113eSDavid van Moolenbroek                 routing_timer.tv_sec = now.tv_sec + routing_timeout;
144*83ee113eSDavid van Moolenbroek         else if ((now.tv_sec - routing_timer.tv_sec) > 0)
145*83ee113eSDavid van Moolenbroek                 expire_routes();
146*83ee113eSDavid van Moolenbroek 
147*83ee113eSDavid van Moolenbroek         /* the kernel might have stripped off the source
148*83ee113eSDavid van Moolenbroek          * routing bit. We try a heuristic to determine whether
149*83ee113eSDavid van Moolenbroek          * this is the case and put it back on if so
150*83ee113eSDavid van Moolenbroek          */
151*83ee113eSDavid van Moolenbroek         route_len = (ntohs(trh->rcf) & TR_RCF_LEN_MASK) >> 8;
152*83ee113eSDavid van Moolenbroek         llc = (struct trllc *)(buf + bufix + sizeof(struct trh_hdr)-TR_MAXRIFLEN+route_len);
153*83ee113eSDavid van Moolenbroek         if (llc->dsap == EXTENDED_SAP
154*83ee113eSDavid van Moolenbroek                         && llc->ssap == EXTENDED_SAP
155*83ee113eSDavid van Moolenbroek                         && llc->llc == UI_CMD
156*83ee113eSDavid van Moolenbroek                         && llc->protid[0] == 0
157*83ee113eSDavid van Moolenbroek                         && llc->protid[1] == 0
158*83ee113eSDavid van Moolenbroek                         && llc->protid[2] == 0) {
159*83ee113eSDavid van Moolenbroek                 /* say there is source routing information present */
160*83ee113eSDavid van Moolenbroek                 trh->saddr[0] |= TR_RII;
161*83ee113eSDavid van Moolenbroek         }
162*83ee113eSDavid van Moolenbroek 
163*83ee113eSDavid van Moolenbroek 	if (trh->saddr[0] & TR_RII)
164*83ee113eSDavid van Moolenbroek                 route_len = (ntohs(trh->rcf) & TR_RCF_LEN_MASK) >> 8;
165*83ee113eSDavid van Moolenbroek         else
166*83ee113eSDavid van Moolenbroek                 route_len = 0;
167*83ee113eSDavid van Moolenbroek 
168*83ee113eSDavid van Moolenbroek         hdr_len = sizeof (struct trh_hdr) - TR_MAXRIFLEN + route_len;
169*83ee113eSDavid van Moolenbroek 
170*83ee113eSDavid van Moolenbroek         /* now filter out unwanted packets: this is based on the packet
171*83ee113eSDavid van Moolenbroek          * filter code in bpf.c */
172*83ee113eSDavid van Moolenbroek         llc = (struct trllc *)(buf + bufix + hdr_len);
173*83ee113eSDavid van Moolenbroek         ip = (struct ip *) (llc + 1);
174*83ee113eSDavid van Moolenbroek         udp = (struct udphdr *) ((unsigned char*) ip + IP_HL (ip));
175*83ee113eSDavid van Moolenbroek 
176*83ee113eSDavid van Moolenbroek         /* make sure it is a snap encoded, IP, UDP, unfragmented packet sent
177*83ee113eSDavid van Moolenbroek          * to our port */
178*83ee113eSDavid van Moolenbroek         if (llc->dsap != EXTENDED_SAP
179*83ee113eSDavid van Moolenbroek                         || ntohs(llc->ethertype) != ETHERTYPE_IP
180*83ee113eSDavid van Moolenbroek                         || ip->ip_p != IPPROTO_UDP
181*83ee113eSDavid van Moolenbroek                         || (ntohs (ip->ip_off) & IP_OFFMASK) != 0
182*83ee113eSDavid van Moolenbroek                         || udp->uh_dport != local_port)
183*83ee113eSDavid van Moolenbroek                 return -1;
184*83ee113eSDavid van Moolenbroek 
185*83ee113eSDavid van Moolenbroek         /* only save source routing information for packets from valued hosts */
186*83ee113eSDavid van Moolenbroek         save_source_routing(trh, interface);
187*83ee113eSDavid van Moolenbroek 
188*83ee113eSDavid van Moolenbroek         return hdr_len + sizeof (struct trllc);
189*83ee113eSDavid van Moolenbroek }
190*83ee113eSDavid van Moolenbroek 
191*83ee113eSDavid van Moolenbroek /* insert_source_routing inserts source route information into the token ring
192*83ee113eSDavid van Moolenbroek  * header
193*83ee113eSDavid van Moolenbroek  */
insert_source_routing(trh,interface)194*83ee113eSDavid van Moolenbroek static int insert_source_routing (trh, interface)
195*83ee113eSDavid van Moolenbroek         struct trh_hdr *trh;
196*83ee113eSDavid van Moolenbroek         struct interface_info* interface;
197*83ee113eSDavid van Moolenbroek {
198*83ee113eSDavid van Moolenbroek 	struct routing_entry *rover;
199*83ee113eSDavid van Moolenbroek         struct timeval now;
200*83ee113eSDavid van Moolenbroek         unsigned int route_len = 0;
201*83ee113eSDavid van Moolenbroek 
202*83ee113eSDavid van Moolenbroek         gettimeofday(&now, NULL);
203*83ee113eSDavid van Moolenbroek 
204*83ee113eSDavid van Moolenbroek 	/* single route broadcasts as per rfc 1042 */
205*83ee113eSDavid van Moolenbroek 	if (memcmp(trh->daddr, tr_broadcast,TR_ALEN) == 0) {
206*83ee113eSDavid van Moolenbroek 		trh->saddr[0] |= TR_RII;
207*83ee113eSDavid van Moolenbroek 		trh->rcf = ((sizeof(trh->rcf)) << 8) & TR_RCF_LEN_MASK;
208*83ee113eSDavid van Moolenbroek                 trh->rcf |= (TR_RCF_FRAME2K | TR_RCF_LIMITED_BROADCAST);
209*83ee113eSDavid van Moolenbroek 		trh->rcf = htons(trh->rcf);
210*83ee113eSDavid van Moolenbroek 	} else {
211*83ee113eSDavid van Moolenbroek 		/* look for a routing entry */
212*83ee113eSDavid van Moolenbroek                 for (rover = routing_info; rover != NULL; rover = rover->next) {
213*83ee113eSDavid van Moolenbroek                         if (memcmp(rover->addr, trh->daddr, TR_ALEN) == 0)
214*83ee113eSDavid van Moolenbroek                                 break;
215*83ee113eSDavid van Moolenbroek                 }
216*83ee113eSDavid van Moolenbroek 
217*83ee113eSDavid van Moolenbroek 		if (rover != NULL) {
218*83ee113eSDavid van Moolenbroek                         /* success: route that frame */
219*83ee113eSDavid van Moolenbroek                         if ((rover->rcf & TR_RCF_LEN_MASK) >> 8) {
220*83ee113eSDavid van Moolenbroek                                 u_int16_t rcf = rover->rcf;
221*83ee113eSDavid van Moolenbroek 				memcpy(trh->rseg,rover->rseg,sizeof(trh->rseg));
222*83ee113eSDavid van Moolenbroek 				rcf ^= TR_RCF_DIR_BIT;
223*83ee113eSDavid van Moolenbroek 				rcf &= ~TR_RCF_BROADCAST_MASK;
224*83ee113eSDavid van Moolenbroek                                 trh->rcf = htons(rcf);
225*83ee113eSDavid van Moolenbroek 				trh->saddr[0] |= TR_RII;
226*83ee113eSDavid van Moolenbroek 			}
227*83ee113eSDavid van Moolenbroek 			rover->access_time = now.tv_sec;
228*83ee113eSDavid van Moolenbroek 		} else {
229*83ee113eSDavid van Moolenbroek                         /* we don't have any routing information so send a
230*83ee113eSDavid van Moolenbroek                          * limited broadcast */
231*83ee113eSDavid van Moolenbroek                         trh->saddr[0] |= TR_RII;
232*83ee113eSDavid van Moolenbroek                         trh->rcf = ((sizeof(trh->rcf)) << 8) & TR_RCF_LEN_MASK;
233*83ee113eSDavid van Moolenbroek                         trh->rcf |= (TR_RCF_FRAME2K | TR_RCF_LIMITED_BROADCAST);
234*83ee113eSDavid van Moolenbroek                         trh->rcf = htons(trh->rcf);
235*83ee113eSDavid van Moolenbroek 		}
236*83ee113eSDavid van Moolenbroek 	}
237*83ee113eSDavid van Moolenbroek 
238*83ee113eSDavid van Moolenbroek 	/* return how much of the header we've actually used */
239*83ee113eSDavid van Moolenbroek 	if (trh->saddr[0] & TR_RII)
240*83ee113eSDavid van Moolenbroek                 route_len = (ntohs(trh->rcf) & TR_RCF_LEN_MASK) >> 8;
241*83ee113eSDavid van Moolenbroek         else
242*83ee113eSDavid van Moolenbroek                 route_len = 0;
243*83ee113eSDavid van Moolenbroek 
244*83ee113eSDavid van Moolenbroek         return sizeof (struct trh_hdr) - TR_MAXRIFLEN + route_len;
245*83ee113eSDavid van Moolenbroek }
246*83ee113eSDavid van Moolenbroek 
247*83ee113eSDavid van Moolenbroek /*
248*83ee113eSDavid van Moolenbroek  * save any source routing information
249*83ee113eSDavid van Moolenbroek  */
save_source_routing(trh,interface)250*83ee113eSDavid van Moolenbroek static void save_source_routing(trh, interface)
251*83ee113eSDavid van Moolenbroek         struct trh_hdr *trh;
252*83ee113eSDavid van Moolenbroek         struct interface_info *interface;
253*83ee113eSDavid van Moolenbroek {
254*83ee113eSDavid van Moolenbroek         struct routing_entry *rover;
255*83ee113eSDavid van Moolenbroek         struct timeval now;
256*83ee113eSDavid van Moolenbroek         unsigned char saddr[TR_ALEN];
257*83ee113eSDavid van Moolenbroek         u_int16_t rcf = 0;
258*83ee113eSDavid van Moolenbroek 
259*83ee113eSDavid van Moolenbroek         gettimeofday(&now, NULL);
260*83ee113eSDavid van Moolenbroek 
261*83ee113eSDavid van Moolenbroek         memcpy(saddr, trh->saddr, sizeof(saddr));
262*83ee113eSDavid van Moolenbroek         saddr[0] &= 0x7f;   /* strip off source routing present flag */
263*83ee113eSDavid van Moolenbroek 
264*83ee113eSDavid van Moolenbroek         /* scan our table to see if we've got it */
265*83ee113eSDavid van Moolenbroek         for (rover = routing_info; rover != NULL; rover = rover->next) {
266*83ee113eSDavid van Moolenbroek                 if (memcmp(&rover->addr[0], &saddr[0], TR_ALEN) == 0)
267*83ee113eSDavid van Moolenbroek                         break;
268*83ee113eSDavid van Moolenbroek         }
269*83ee113eSDavid van Moolenbroek 
270*83ee113eSDavid van Moolenbroek         /* found an entry so update it with fresh information */
271*83ee113eSDavid van Moolenbroek         if (rover != NULL) {
272*83ee113eSDavid van Moolenbroek                 if ((trh->saddr[0] & TR_RII) &&
273*83ee113eSDavid van Moolenbroek 		    ((ntohs(trh->rcf) & TR_RCF_LEN_MASK) >> 8) > 2) {
274*83ee113eSDavid van Moolenbroek                         rcf = ntohs(trh->rcf);
275*83ee113eSDavid van Moolenbroek                         rcf &= ~TR_RCF_BROADCAST_MASK;
276*83ee113eSDavid van Moolenbroek                         memcpy(rover->rseg, trh->rseg, sizeof(rover->rseg));
277*83ee113eSDavid van Moolenbroek                 }
278*83ee113eSDavid van Moolenbroek                 rover->rcf = rcf;
279*83ee113eSDavid van Moolenbroek                 rover->access_time = now.tv_sec;
280*83ee113eSDavid van Moolenbroek                 return;     /* that's all folks */
281*83ee113eSDavid van Moolenbroek         }
282*83ee113eSDavid van Moolenbroek 
283*83ee113eSDavid van Moolenbroek         /* no entry found, so create one */
284*83ee113eSDavid van Moolenbroek         rover = dmalloc (sizeof (struct routing_entry), MDL);
285*83ee113eSDavid van Moolenbroek         if (rover == NULL) {
286*83ee113eSDavid van Moolenbroek                 fprintf(stderr,
287*83ee113eSDavid van Moolenbroek 			"%s: unable to save source routing information\n",
288*83ee113eSDavid van Moolenbroek 			__FILE__);
289*83ee113eSDavid van Moolenbroek                 return;
290*83ee113eSDavid van Moolenbroek         }
291*83ee113eSDavid van Moolenbroek 
292*83ee113eSDavid van Moolenbroek         memcpy(rover->addr, saddr, sizeof(rover->addr));
293*83ee113eSDavid van Moolenbroek         memcpy(rover->iface, interface->name, 5);
294*83ee113eSDavid van Moolenbroek         rover->access_time = now.tv_sec;
295*83ee113eSDavid van Moolenbroek         if (trh->saddr[0] & TR_RII) {
296*83ee113eSDavid van Moolenbroek                 if (((ntohs(trh->rcf) & TR_RCF_LEN_MASK) >> 8) > 2) {
297*83ee113eSDavid van Moolenbroek                         rcf = ntohs(trh->rcf);
298*83ee113eSDavid van Moolenbroek                         rcf &= ~TR_RCF_BROADCAST_MASK;
299*83ee113eSDavid van Moolenbroek                         memcpy(rover->rseg, trh->rseg, sizeof(rover->rseg));
300*83ee113eSDavid van Moolenbroek                 }
301*83ee113eSDavid van Moolenbroek                 rover->rcf = rcf;
302*83ee113eSDavid van Moolenbroek         }
303*83ee113eSDavid van Moolenbroek 
304*83ee113eSDavid van Moolenbroek         /* insert into list */
305*83ee113eSDavid van Moolenbroek         rover->next = routing_info;
306*83ee113eSDavid van Moolenbroek         routing_info = rover;
307*83ee113eSDavid van Moolenbroek 
308*83ee113eSDavid van Moolenbroek         return;
309*83ee113eSDavid van Moolenbroek }
310*83ee113eSDavid van Moolenbroek 
311*83ee113eSDavid van Moolenbroek /*
312*83ee113eSDavid van Moolenbroek  * get rid of old routes
313*83ee113eSDavid van Moolenbroek  */
expire_routes()314*83ee113eSDavid van Moolenbroek static void expire_routes()
315*83ee113eSDavid van Moolenbroek {
316*83ee113eSDavid van Moolenbroek         struct routing_entry *rover;
317*83ee113eSDavid van Moolenbroek         struct routing_entry **prover = &routing_info;
318*83ee113eSDavid van Moolenbroek         struct timeval now;
319*83ee113eSDavid van Moolenbroek 
320*83ee113eSDavid van Moolenbroek         gettimeofday(&now, NULL);
321*83ee113eSDavid van Moolenbroek 
322*83ee113eSDavid van Moolenbroek         while((rover = *prover) != NULL) {
323*83ee113eSDavid van Moolenbroek                 if ((now.tv_sec - rover->access_time) > routing_timeout) {
324*83ee113eSDavid van Moolenbroek                         *prover = rover->next;
325*83ee113eSDavid van Moolenbroek                         dfree (rover, MDL);
326*83ee113eSDavid van Moolenbroek                 } else
327*83ee113eSDavid van Moolenbroek                         prover = &rover->next;
328*83ee113eSDavid van Moolenbroek         }
329*83ee113eSDavid van Moolenbroek 
330*83ee113eSDavid van Moolenbroek         /* Reset the timer */
331*83ee113eSDavid van Moolenbroek         routing_timer.tv_sec = now.tv_sec + routing_timeout;
332*83ee113eSDavid van Moolenbroek         routing_timer.tv_usec = now.tv_usec;
333*83ee113eSDavid van Moolenbroek }
334*83ee113eSDavid van Moolenbroek 
335*83ee113eSDavid van Moolenbroek #endif
336