31#if defined (HAVE_TR_SUPPORT) && \
32 (defined (PACKET_ASSEMBLY) || defined (PACKET_DECODING))
36#include "netinet/if_tr.h"
45static int insert_source_routing (
struct trh_hdr *trh,
struct interface_info* interface);
46static void save_source_routing (
struct trh_hdr *trh,
struct interface_info* interface);
47static void expire_routes (
void);
54 struct routing_entry *next;
55 unsigned char addr[TR_ALEN];
56 unsigned char iface[5];
59 unsigned long access_time;
62static struct routing_entry *routing_info = NULL;
64static int routing_timeout = 10;
65static struct timeval routing_timer;
79 trh = (
struct trh_hdr *) &buf[*bufix];
80 if (interface -> hw_address.hlen - 1 == sizeof (trh->saddr))
81 memcpy (trh->saddr, &interface -> hw_address.hbuf [1],
84 memset (trh->saddr, 0x00, sizeof (trh->saddr));
86 if (to && to -> hlen == 7)
87 memcpy (trh->daddr, &to -> hbuf [1],
sizeof trh->daddr);
89 memset (trh->daddr, 0xff, sizeof (trh->daddr));
91 hdr_len = insert_source_routing (trh, interface);
97 llc = (
struct trllc *)(buf + *bufix + hdr_len);
98 llc->dsap = EXTENDED_SAP;
99 llc->ssap = EXTENDED_SAP;
106 hdr_len +=
sizeof(
struct trllc);
112static unsigned char tr_broadcast[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
126 struct trh_hdr *trh = (
struct trh_hdr *) buf + bufix;
130 unsigned int route_len = 0;
135 gettimeofday(&now, NULL);
137 if (routing_timer.tv_sec == 0)
138 routing_timer.tv_sec = now.tv_sec + routing_timeout;
139 else if ((now.tv_sec - routing_timer.tv_sec) > 0)
146 route_len = (ntohs(trh->rcf) & TR_RCF_LEN_MASK) >> 8;
147 llc = (
struct trllc *)(buf + bufix +
sizeof(
struct trh_hdr)-TR_MAXRIFLEN+route_len);
148 if (llc->dsap == EXTENDED_SAP
149 && llc->ssap == EXTENDED_SAP
150 && llc->llc == UI_CMD
151 && llc->protid[0] == 0
152 && llc->protid[1] == 0
153 && llc->protid[2] == 0) {
155 trh->saddr[0] |= TR_RII;
158 if (trh->saddr[0] & TR_RII)
159 route_len = (ntohs(trh->rcf) & TR_RCF_LEN_MASK) >> 8;
163 hdr_len =
sizeof (
struct trh_hdr) - TR_MAXRIFLEN + route_len;
167 llc = (
struct trllc *)(buf + bufix + hdr_len);
168 ip = (
struct ip *) (llc + 1);
173 if (llc->dsap != EXTENDED_SAP
175 ||
ip->
ip_p != IPPROTO_UDP
181 save_source_routing(trh, interface);
183 return hdr_len +
sizeof (
struct trllc);
189static int insert_source_routing (trh, interface)
193 struct routing_entry *rover;
195 unsigned int route_len = 0;
197 gettimeofday(&now, NULL);
200 if (memcmp(trh->daddr, tr_broadcast,TR_ALEN) == 0) {
201 trh->saddr[0] |= TR_RII;
202 trh->rcf = ((
sizeof(trh->rcf)) << 8) & TR_RCF_LEN_MASK;
203 trh->rcf |= (TR_RCF_FRAME2K | TR_RCF_LIMITED_BROADCAST);
204 trh->rcf = htons(trh->rcf);
207 for (rover = routing_info; rover != NULL; rover = rover->next) {
208 if (memcmp(rover->addr, trh->daddr, TR_ALEN) == 0)
214 if ((rover->rcf & TR_RCF_LEN_MASK) >> 8) {
215 u_int16_t rcf = rover->rcf;
216 memcpy(trh->rseg,rover->rseg,
sizeof(trh->rseg));
217 rcf ^= TR_RCF_DIR_BIT;
218 rcf &= ~TR_RCF_BROADCAST_MASK;
219 trh->rcf = htons(rcf);
220 trh->saddr[0] |= TR_RII;
222 rover->access_time = now.tv_sec;
226 trh->saddr[0] |= TR_RII;
227 trh->rcf = ((
sizeof(trh->rcf)) << 8) & TR_RCF_LEN_MASK;
228 trh->rcf |= (TR_RCF_FRAME2K | TR_RCF_LIMITED_BROADCAST);
229 trh->rcf = htons(trh->rcf);
234 if (trh->saddr[0] & TR_RII)
235 route_len = (ntohs(trh->rcf) & TR_RCF_LEN_MASK) >> 8;
239 return sizeof (
struct trh_hdr) - TR_MAXRIFLEN + route_len;
245static void save_source_routing(trh, interface)
249 struct routing_entry *rover;
251 unsigned char saddr[TR_ALEN];
254 gettimeofday(&now, NULL);
256 memcpy(saddr, trh->saddr,
sizeof(saddr));
260 for (rover = routing_info; rover != NULL; rover = rover->next) {
261 if (memcmp(&rover->addr[0], &saddr[0], TR_ALEN) == 0)
267 if ((trh->saddr[0] & TR_RII) &&
268 ((ntohs(trh->rcf) & TR_RCF_LEN_MASK) >> 8) > 2) {
269 rcf = ntohs(trh->rcf);
270 rcf &= ~TR_RCF_BROADCAST_MASK;
271 memcpy(rover->rseg, trh->rseg,
sizeof(rover->rseg));
274 rover->access_time = now.tv_sec;
279 rover =
dmalloc (
sizeof (
struct routing_entry),
MDL);
282 "%s: unable to save source routing information\n",
287 memcpy(rover->addr, saddr,
sizeof(rover->addr));
288 memcpy(rover->iface, interface->
name, 5);
289 rover->access_time = now.tv_sec;
290 if (trh->saddr[0] & TR_RII) {
291 if (((ntohs(trh->rcf) & TR_RCF_LEN_MASK) >> 8) > 2) {
292 rcf = ntohs(trh->rcf);
293 rcf &= ~TR_RCF_BROADCAST_MASK;
294 memcpy(rover->rseg, trh->rseg,
sizeof(rover->rseg));
300 rover->next = routing_info;
301 routing_info = rover;
309static void expire_routes()
311 struct routing_entry *rover;
312 struct routing_entry **prover = &routing_info;
315 gettimeofday(&now, NULL);
317 while((rover = *prover) != NULL) {
318 if ((now.tv_sec - rover->access_time) > routing_timeout) {
319 *prover = rover->next;
322 prover = &rover->next;
326 routing_timer.tv_sec = now.tv_sec + routing_timeout;
327 routing_timer.tv_usec = now.tv_usec;
void assemble_tr_header(struct interface_info *, unsigned char *, unsigned *, struct hardware *)
ssize_t decode_tr_header(struct interface_info *, unsigned char *, unsigned, struct hardware *)
void * dmalloc(size_t, const char *, int)
void dfree(void *, const char *, int)