int tr_rebuild_header(struct sk_buff *skb) { struct trh_hdr *trh=(struct trh_hdr *)skb->data; struct trllc *trllc=(struct trllc *)(skb->data+sizeof(struct trh_hdr)); struct device *dev = skb->dev; /* * FIXME: We don't yet support IPv6 over token rings */ if(trllc->ethertype != htons(ETH_P_IP)) { printk("tr_rebuild_header: Don't know how to resolve type %04X addresses ?\n",(unsigned int)htons(trllc->ethertype)); return 0; } #ifdef CONFIG_INET if(arp_find(trh->daddr, skb)) { return 1; } else #endif { tr_source_route(skb,trh,dev); return 0; } }
int tr_header(struct sk_buff *skb, struct device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) { struct trh_hdr *trh=(struct trh_hdr *)skb_push(skb,dev->hard_header_len); struct trllc *trllc=(struct trllc *)(trh+1); trh->ac=AC; trh->fc=LLC_FRAME; if(saddr) memcpy(trh->saddr,saddr,dev->addr_len); else memset(trh->saddr,0,dev->addr_len); /* Adapter fills in address */ trllc->dsap=trllc->ssap=EXTENDED_SAP; trllc->llc=UI_CMD; trllc->protid[0]=trllc->protid[1]=trllc->protid[2]=0x00; trllc->ethertype=htons(type); if(daddr) { memcpy(trh->daddr,daddr,dev->addr_len); tr_source_route(trh,dev); return(dev->hard_header_len); } return -dev->hard_header_len; }
int tr_header(struct sk_buff *skb, struct device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) { struct trh_hdr *trh; int hdr_len; /* * Add the 802.2 SNAP header if IP as the IPv4 code calls * dev->hard_header directly. */ if (type == ETH_P_IP || type == ETH_P_ARP) { struct trllc *trllc=(struct trllc *)(trh+1); hdr_len = sizeof(struct trh_hdr) + sizeof(struct trllc); trh = (struct trh_hdr *)skb_push(skb, hdr_len); trllc = (struct trllc *)(trh+1); trllc->dsap = trllc->ssap = EXTENDED_SAP; trllc->llc = UI_CMD; trllc->protid[0] = trllc->protid[1] = trllc->protid[2] = 0x00; trllc->ethertype = htons(type); } else { hdr_len = sizeof(struct trh_hdr); trh = (struct trh_hdr *)skb_push(skb, hdr_len); } trh->ac=AC; trh->fc=LLC_FRAME; if(saddr) memcpy(trh->saddr,saddr,dev->addr_len); else memcpy(trh->saddr,dev->dev_addr,dev->addr_len); /* * Build the destination and then source route the frame */ if(daddr) { memcpy(trh->daddr,daddr,dev->addr_len); tr_source_route(skb,trh,dev); return(hdr_len); } return -hdr_len; }
/** * llc_mac_hdr_init - fills MAC header fields * @skb: Address of the frame to initialize its MAC header * @sa: The MAC source address * @da: The MAC destination address * * Fills MAC header fields, depending on MAC type. Returns 0, If MAC type * is a valid type and initialization completes correctly 1, otherwise. */ int llc_mac_hdr_init(struct sk_buff *skb, const unsigned char *sa, const unsigned char *da) { int rc = 0; switch (skb->dev->type) { #ifdef CONFIG_TR case ARPHRD_IEEE802_TR: { struct net_device *dev = skb->dev; struct trh_hdr *trh; skb_push(skb, sizeof(*trh)); skb_reset_mac_header(skb); trh = tr_hdr(skb); trh->ac = AC; trh->fc = LLC_FRAME; if (sa) memcpy(trh->saddr, sa, dev->addr_len); else memset(trh->saddr, 0, dev->addr_len); if (da) { memcpy(trh->daddr, da, dev->addr_len); tr_source_route(skb, trh, dev); skb_reset_mac_header(skb); } break; } #endif case ARPHRD_ETHER: case ARPHRD_LOOPBACK: { unsigned short len = skb->len; struct ethhdr *eth; skb_push(skb, sizeof(*eth)); skb_reset_mac_header(skb); eth = eth_hdr(skb); eth->h_proto = htons(len); memcpy(eth->h_dest, da, ETH_ALEN); memcpy(eth->h_source, sa, ETH_ALEN); break; } default: printk(KERN_WARNING "device type not supported: %d\n", skb->dev->type); rc = -EINVAL; } return rc; }
int tr_rebuild_header(void *buff, struct device *dev, unsigned long dest, struct sk_buff *skb) { struct trh_hdr *trh=(struct trh_hdr *)buff; struct trllc *trllc=(struct trllc *)(buff+sizeof(struct trh_hdr)); if(trllc->ethertype != htons(ETH_P_IP)) { printk("tr_rebuild_header: Don't know how to resolve type %04X addresses ?\n",(unsigned int)htons( trllc->ethertype)); return 0; } if(arp_find(trh->daddr, dest, dev, dev->pa_addr, skb)) { return 1; } else { tr_source_route(trh,dev); return 0; } }