patch-1.3.42 linux/net/ethernet/eth.c
Next file: linux/net/ipv4/Config.in
Previous file: linux/net/core/dev.c
Back to the patch index
Back to the overall index
- Lines: 102
- Date:
Thu Nov 16 08:23:49 1995
- Orig file:
v1.3.41/linux/net/ethernet/eth.c
- Orig date:
Tue Oct 10 18:46:39 1995
diff -u --recursive --new-file v1.3.41/linux/net/ethernet/eth.c linux/net/ethernet/eth.c
@@ -89,7 +89,7 @@
int eth_header(struct sk_buff *skb, struct device *dev, unsigned short type,
void *daddr, void *saddr, unsigned len)
{
- struct ethhdr *eth = (struct ethhdr *)skb_push(skb,14);
+ struct ethhdr *eth = (struct ethhdr *)skb_push(skb,ETH_HLEN);
/*
* Set the protocol type. For a packet of type ETH_P_802_3 we put the length
@@ -175,7 +175,7 @@
unsigned char *rawp;
skb->mac.raw=skb->data;
- skb_pull(skb,14);
+ skb_pull(skb,dev->hard_header_len);
eth= skb->mac.ethernet;
if(*eth->h_dest&1)
@@ -218,28 +218,48 @@
}
/*
- * Header caching for ethernet. Try to find and cache a header to avoid arp overhead.
+ * Upper level calls this function to bind hardware header cache entry.
+ * If the call is successful, then corresponding Address Resolution Protocol
+ * (maybe, not ARP) takes responsibility for updating cache content.
*/
-
-void eth_header_cache(struct device *dev, struct sock *sk, unsigned long saddr, unsigned long daddr)
+
+void eth_header_cache_bind(struct hh_cache ** hhp, struct device *dev,
+ unsigned short htype, __u32 daddr)
{
- int v=arp_find_cache(sk->ip_hcache_data, daddr, dev);
- if(v!=1)
- sk->ip_hcache_state=0; /* Try when arp resolves */
- else
+ struct hh_cache *hh;
+
+ if (htype != ETH_P_IP)
+ {
+ printk("eth_header_cache_bind: %04x cache is not implemented\n", htype);
+ return;
+ }
+ if (arp_bind_cache(hhp, dev, htype, daddr))
+ return;
+ if ((hh=*hhp) != NULL)
+ {
+ memcpy(hh->hh_data+6, dev->dev_addr, ETH_ALEN);
+ hh->hh_data[12] = htype>>8;
+ hh->hh_data[13] = htype&0xFF;
+ }
+}
+
+/*
+ * Called by Address Resolution module to notify changes in address.
+ */
+
+void eth_header_cache_update(struct hh_cache *hh, struct device *dev, unsigned char * haddr)
+{
+ if (hh->hh_type != ETH_P_IP)
{
- memcpy(sk->ip_hcache_data+6, dev->dev_addr, ETH_ALEN);
- sk->ip_hcache_data[12]=ETH_P_IP>>8;
- sk->ip_hcache_data[13]=ETH_P_IP&0xFF;
- sk->ip_hcache_state=1;
- sk->ip_hcache_stamp=arp_cache_stamp;
- sk->ip_hcache_ver=&arp_cache_stamp;
+ printk("eth_header_cache_update: %04x cache is not implemented\n", hh->hh_type);
+ return;
}
+ memcpy(hh->hh_data, haddr, ETH_ALEN);
+ hh->hh_uptodate = 1;
}
/*
* Copy from an ethernet device memory space to an sk_buff while checksumming if IP
- * The magic "34" is Rx_addr+Tx_addr+type_field+sizeof(struct iphdr) == 6+6+2+20.
*/
void eth_copy_and_sum(struct sk_buff *dest, unsigned char *src, int length, int base)
@@ -261,13 +281,15 @@
* We have to use the smaller of length and ip_length because it
* can happen that ip_length > length.
*/
- memcpy(dest->data,src,34); /* ethernet is always >= 34 */
- length -= 34;
- iph=(struct iphdr*)(src+14); /* 14 = Rx_addr+Tx_addr+type_field */
+ memcpy(dest->data,src,sizeof(struct iphdr)+ETH_HLEN); /* ethernet is always >= 34 */
+ length -= sizeof(struct iphdr) + ETH_HLEN;
+ iph=(struct iphdr*)(src+ETH_HLEN);
ip_length = ntohs(iph->tot_len) - sizeof(struct iphdr);
- if (ip_length <= length)
+
+ /* Also watch out for bogons - min IP size is 8 (rfc-1042) */
+ if ((ip_length <= length) && (ip_length > 7))
length=ip_length;
- dest->csum=csum_partial_copy(src+34,dest->data+34,length,base);
+ dest->csum=csum_partial_copy(src+sizeof(struct iphdr)+ETH_HLEN,dest->data+sizeof(struct iphdr)+ETH_HLEN,length,base);
dest->ip_summed=1;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this