⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rfc1201.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Linux ARCnet driver - RFC1201 (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 * * ********************** */#include <linux/module.h>#include <linux/init.h>#include <linux/if_arp.h>#include <linux/netdevice.h>#include <linux/skbuff.h>#include <linux/arcdevice.h>#define VERSION "arcnet: RFC1201 \"standard\" (`a') encapsulation support loaded.\n"static unsigned short type_trans(struct sk_buff *skb, struct net_device *dev);static void rx(struct net_device *dev, int bufnum,	       struct archdr *pkthdr, int length);static int build_header(struct sk_buff *skb, unsigned short type,			uint8_t daddr);static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,		      int bufnum);static int continue_tx(struct net_device *dev, int bufnum);struct ArcProto rfc1201_proto ={	'a',	1500,			/* could be more, but some receivers can't handle it... */	rx,	build_header,	prepare_tx,	continue_tx};void __init arcnet_rfc1201_init(void){	arc_proto_map[ARC_P_IP]	    = arc_proto_map[ARC_P_ARP]	    = arc_proto_map[ARC_P_RARP]	    = arc_proto_map[ARC_P_IPX]	    = arc_proto_map[ARC_P_NOVELL_EC]	    = &rfc1201_proto;	/* if someone else already owns the broadcast, we won't take it */	if (arc_bcast_proto == arc_proto_default)		arc_bcast_proto = &rfc1201_proto;}#ifdef MODULEint __init init_module(void){	printk(VERSION);	arcnet_rfc1201_init();	return 0;}void cleanup_module(void){	arcnet_unregister_proto(&rfc1201_proto);}#endif				/* MODULE *//* * Determine a packet's protocol ID. *  * With ARCnet we have to convert everything to Ethernet-style stuff. */static unsigned short type_trans(struct sk_buff *skb, struct net_device *dev){	struct archdr *pkt = (struct archdr *) skb->data;	struct arc_rfc1201 *soft = &pkt->soft.rfc1201;	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;	int hdr_size = ARC_HDR_SIZE + RFC1201_HDR_SIZE;	/* Pull off the arcnet header. */	skb->mac.raw = skb->data;	skb_pull(skb, hdr_size);	if (pkt->hard.dest == 0)		skb->pkt_type = PACKET_BROADCAST;	else if (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:		return htons(ETH_P_IP);	case ARC_P_ARP:		return htons(ETH_P_ARP);	case ARC_P_RARP:		return htons(ETH_P_RARP);	case ARC_P_IPX:	case ARC_P_NOVELL_EC:		return htons(ETH_P_802_3);	default:		lp->stats.rx_errors++;		lp->stats.rx_crc_errors++;		return 0;	}	return htons(ETH_P_IP);}/* packet receiver */static void rx(struct net_device *dev, int bufnum,	       struct archdr *pkthdr, int length){	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;	struct sk_buff *skb;	struct archdr *pkt = pkthdr;	struct arc_rfc1201 *soft = &pkthdr->soft.rfc1201;	int saddr = pkt->hard.source, ofs;	struct Incoming *in = &lp->rfc1201.incoming[saddr];	BUGMSG(D_DURING, "it's an RFC1201 packet (length=%d)\n", length);	if (length >= MinTU)		ofs = 512 - length;	else		ofs = 256 - length;	if (soft->split_flag == 0xFF) {		/* Exception Packet */		if (length >= 4 + RFC1201_HDR_SIZE)			BUGMSG(D_DURING, "compensating for exception packet\n");		else {			BUGMSG(D_EXTRA, "short RFC1201 exception packet from %02Xh",			       saddr);			return;		}		/* skip over 4-byte junkola */		length -= 4;		ofs += 4;		lp->hw.copy_from_card(dev, bufnum, 512 - length,				      soft, sizeof(pkt->soft));	}	if (!soft->split_flag) {	/* not split */		BUGMSG(D_RX, "incoming is not split (splitflag=%d)\n",		       soft->split_flag);		if (in->skb) {	/* already assembling one! */			BUGMSG(D_EXTRA, "aborting assembly (seq=%d) for unsplit packet (splitflag=%d, seq=%d)\n",			 in->sequence, soft->split_flag, soft->sequence);			lp->rfc1201.aborted_seq = soft->sequence;			dev_kfree_skb_irq(in->skb);			lp->stats.rx_errors++;			lp->stats.rx_missed_errors++;			in->skb = NULL;		}		in->sequence = soft->sequence;		skb = alloc_skb(length + ARC_HDR_SIZE, GFP_ATOMIC);		if (skb == NULL) {			BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n");			lp->stats.rx_dropped++;			return;		}		skb_put(skb, length + ARC_HDR_SIZE);		skb->dev = dev;		pkt = (struct archdr *) skb->data;		soft = &pkt->soft.rfc1201;		/* 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));		/*		 * ARP packets have problems when sent from some DOS systems: the		 * source address is always 0!  So we take the hardware source addr		 * (which is impossible to fumble) and insert it ourselves.		 */		if (soft->proto == ARC_P_ARP) {			struct arphdr *arp = (struct arphdr *) soft->payload;			/* make sure addresses are the right length */			if (arp->ar_hln == 1 && arp->ar_pln == 4) {				uint8_t *cptr = (uint8_t *) arp + sizeof(struct arphdr);				if (!*cptr) {	/* is saddr = 00? */					BUGMSG(D_EXTRA,					       "ARP source address was 00h, set to %02Xh.\n",					       saddr);					lp->stats.rx_crc_errors++;					*cptr = saddr;				} else {					BUGMSG(D_DURING, "ARP source address (%Xh) is fine.\n",					       *cptr);				}			} else {				BUGMSG(D_NORMAL, "funny-shaped ARP packet. (%Xh, %Xh)\n",				       arp->ar_hln, arp->ar_pln);				lp->stats.rx_errors++;				lp->stats.rx_crc_errors++;			}		}		BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx");		skb->protocol = type_trans(skb, dev);		netif_rx(skb);		dev->last_rx = jiffies;	} else {		/* split packet */		/*		 * NOTE: MSDOS ARP packet correction should only need to apply to		 * unsplit packets, since ARP packets are so short.		 *		 * My interpretation of the RFC1201 document is that if a packet is		 * received out of order, the entire assembly process should be		 * aborted.		 *		 * The RFC also mentions "it is possible for successfully received		 * packets to be retransmitted." As of 0.40 all previously received		 * packets are allowed, not just the most recent one.		 *		 * We allow multiple assembly processes, one for each ARCnet card		 * possible on the network.  Seems rather like a waste of memory,		 * but there's no other way to be reliable.		 */		BUGMSG(D_RX, "packet is split (splitflag=%d, seq=%d)\n",		       soft->split_flag, in->sequence);		if (in->skb && in->sequence != soft->sequence) {			BUGMSG(D_EXTRA, "wrong seq number (saddr=%d, expected=%d, seq=%d, splitflag=%d)\n",			       saddr, in->sequence, soft->sequence,			       soft->split_flag);			dev_kfree_skb_irq(in->skb);			in->skb = NULL;			lp->stats.rx_errors++;			lp->stats.rx_missed_errors++;			in->lastpacket = in->numpackets = 0;		}		if (soft->split_flag & 1) {	/* first packet in split */			BUGMSG(D_RX, "brand new splitpacket (splitflag=%d)\n",			       soft->split_flag);			if (in->skb) {	/* already assembling one! */				BUGMSG(D_EXTRA, "aborting previous (seq=%d) assembly "				       "(splitflag=%d, seq=%d)\n",				       in->sequence, soft->split_flag,				       soft->sequence);				lp->stats.rx_errors++;				lp->stats.rx_missed_errors++;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -