patch-2.1.53 linux/net/802/tr.c
Next file: linux/net/appletalk/ddp.c
Previous file: linux/include/net/tcp.h
Back to the patch index
Back to the overall index
- Lines: 98
- Date:
Thu Sep 4 13:25:28 1997
- Orig file:
v2.1.52/linux/net/802/tr.c
- Orig date:
Tue May 13 22:41:20 1997
diff -u --recursive --new-file v2.1.52/linux/net/802/tr.c linux/net/802/tr.c
@@ -34,7 +34,7 @@
#include <linux/init.h>
#include <net/arp.h>
-static void tr_source_route(struct trh_hdr *trh, struct device *dev);
+static void tr_source_route(struct sk_buff *skb, struct trh_hdr *trh, struct device *dev);
static void tr_add_rif_info(struct trh_hdr *trh, struct device *dev);
static void rif_check_expire(unsigned long dummy);
@@ -114,7 +114,7 @@
if(daddr)
{
memcpy(trh->daddr,daddr,dev->addr_len);
- tr_source_route(trh,dev);
+ tr_source_route(skb,trh,dev);
return(dev->hard_header_len);
}
return -dev->hard_header_len;
@@ -146,7 +146,7 @@
}
else
{
- tr_source_route(trh,dev);
+ tr_source_route(skb,trh,dev);
return 0;
}
}
@@ -187,15 +187,46 @@
}
/*
- * We try to do source routing...
+ * Reformat the headers to make a "standard" frame. This is done
+ * in-place in the sk_buff.
*/
-static void tr_source_route(struct trh_hdr *trh,struct device *dev)
+void tr_reformat(struct sk_buff *skb, unsigned int hdr_len)
{
+ struct trllc *llc = (struct trllc *)(skb->data+hdr_len);
+ struct device *dev = skb->dev;
+ unsigned char *olddata = skb->data;
+ int slack;
- int i;
+ if (llc->dsap == 0xAA && llc->ssap == 0xAA)
+ {
+ slack = sizeof(struct trh_hdr) - hdr_len;
+ skb_push(skb, slack);
+ memmove(skb->data, olddata, hdr_len);
+ memset(skb->data+hdr_len, 0, slack);
+ }
+ else
+ {
+ struct trllc *local_llc;
+ slack = sizeof(struct trh_hdr) - hdr_len + sizeof(struct trllc);
+ skb_push(skb, slack);
+ memmove(skb->data, olddata, hdr_len);
+ memset(skb->data+hdr_len, 0, slack);
+ local_llc = (struct trllc *)(skb->data+dev->hard_header_len);
+ local_llc->ethertype = htons(ETH_P_TR_802_2);
+ }
+}
+
+/*
+ * We try to do source routing...
+ */
+
+static void tr_source_route(struct sk_buff *skb,struct trh_hdr *trh,struct device *dev)
+{
+ int i, slack;
unsigned int hash;
rif_cache entry;
+ unsigned char *olddata;
/*
* Broadcasts are single route as stated in RFC 1042
@@ -252,9 +283,20 @@
trh->rcf=htons((((sizeof(trh->rcf)) << 8) & TR_RCF_LEN_MASK)
| TR_RCF_FRAME2K | TR_RCF_LIMITED_BROADCAST);
trh->saddr[0]|=TR_RII;
+#if TR_SR_DEBUG
printk("no entry in rif table found - broadcasting frame\n");
+#endif
}
}
+
+ /* Compress the RIF here so we don't have to do it in the driver(s) */
+ if (!(trh->saddr[0] & 0x80))
+ slack = 18;
+ else
+ slack = 18 - ((ntohs(trh->rcf) & TR_RCF_LEN_MASK)>>8);
+ olddata = skb->data;
+ skb_pull(skb, slack);
+ memmove(skb->data, olddata, sizeof(struct trh_hdr) - slack);
}
/*
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov