/* * Linux ARCnet driver - RFC1051 ("simple" standard) packet encapsulation * * Written 1994-1999 by Avery Pennarun. * Derived from skeleton.c by Donald Becker. * * Special thanks to Contemporary Controls, Inc. (www.ccontrols.com) * for sponsoring the further development of this driver. * * ********************** * * The original copyright of skeleton.c was as follows: * * skeleton.c Written 1993 by Donald Becker. * Copyright 1993 United States Government as represented by the * Director, National Security Agency. This software may only be used * and distributed according to the terms of the GNU General Public License as * modified by SRC, incorporated herein by reference. * * ********************** * * For more details, see drivers/net/arcnet.c * * **********************
*/
MODULE_DESCRIPTION("ARCNet packet format (RFC 1051) module");
MODULE_LICENSE("GPL");
/* Determine a packet's protocol ID. * * With ARCnet we have to convert everything to Ethernet-style stuff.
*/ static __be16 type_trans(struct sk_buff *skb, struct net_device *dev)
{ struct archdr *pkt = (struct archdr *)skb->data; struct arc_rfc1051 *soft = &pkt->soft.rfc1051; int hdr_size = ARC_HDR_SIZE + RFC1051_HDR_SIZE;
/* Pull off the arcnet header. */
skb_reset_mac_header(skb);
skb_pull(skb, hdr_size);
if (pkt->hard.dest == 0) {
skb->pkt_type = PACKET_BROADCAST;
} elseif (dev->flags & IFF_PROMISC) { /* if we're not sending to ourselves :) */ if (pkt->hard.dest != dev->dev_addr[0])
skb->pkt_type = PACKET_OTHERHOST;
} /* now return the protocol number */ switch (soft->proto) { case ARC_P_IP_RFC1051: return htons(ETH_P_IP); case ARC_P_ARP_RFC1051: return htons(ETH_P_ARP);
/* up to sizeof(pkt->soft) has already been copied from the card */
memcpy(pkt, pkthdr, sizeof(struct archdr)); if (length > sizeof(pkt->soft))
lp->hw.copy_from_card(dev, bufnum, ofs + sizeof(pkt->soft),
pkt->soft.raw + sizeof(pkt->soft),
length - sizeof(pkt->soft));
if (BUGLVL(D_SKB))
arcnet_dump_skb(dev, skb, "rx");
/* set the protocol ID according to RFC1051 */ switch (type) { case ETH_P_IP:
soft->proto = ARC_P_IP_RFC1051; break; case ETH_P_ARP:
soft->proto = ARC_P_ARP_RFC1051; break; default:
arc_printk(D_NORMAL, dev, "RFC1051: I don't understand protocol %d (%Xh)\n",
type, type);
dev->stats.tx_errors++;
dev->stats.tx_aborted_errors++; return 0;
}
/* Set the source hardware address. * * This is pretty pointless for most purposes, but it can help in * debugging. ARCnet does not allow us to change the source address * in the actual packet sent.
*/
pkt->hard.source = *dev->dev_addr;
/* see linux/net/ethernet/eth.c to see where I got the following */
if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) { /* FIXME: fill in the last byte of the dest ipaddr here to * better comply with RFC1051 in "noarp" mode.
*/
pkt->hard.dest = 0; return hdr_size;
} /* otherwise, just fill it in and go! */
pkt->hard.dest = daddr;
return hdr_size; /* success */
}
staticint prepare_tx(struct net_device *dev, struct archdr *pkt, int length, int bufnum)
{ struct arcnet_local *lp = netdev_priv(dev); struct arc_hardware *hard = &pkt->hard; int ofs;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.