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

📄 airo.c

📁 h内核
💻 C
📖 第 1 页 / 共 5 页
字号:
	miccntx mCtx;		// Multicast context	miccntx uCtx;		// Unicast context} mic_module;typedef struct {	unsigned int  rid: 16;	unsigned int  len: 15;	unsigned int  valid: 1;	dma_addr_t host_addr;} Rid;typedef struct {	unsigned int  offset: 15;	unsigned int  eoc: 1;	unsigned int  len: 15;	unsigned int  valid: 1;	dma_addr_t host_addr;} TxFid;typedef struct {	unsigned int  ctl: 15;	unsigned int  rdy: 1;	unsigned int  len: 15;	unsigned int  valid: 1;	dma_addr_t host_addr;} RxFid;/* * Host receive descriptor */typedef struct {	unsigned char __iomem *card_ram_off; /* offset into card memory of the						desc */	RxFid         rx_desc;		     /* card receive descriptor */	char          *virtual_host_addr;    /* virtual address of host receive					        buffer */	int           pending;} HostRxDesc;/* * Host transmit descriptor */typedef struct {	unsigned char __iomem *card_ram_off;	     /* offset into card memory of the						desc */	TxFid         tx_desc;		     /* card transmit descriptor */	char          *virtual_host_addr;    /* virtual address of host receive					        buffer */	int           pending;} HostTxDesc;/* * Host RID descriptor */typedef struct {	unsigned char __iomem *card_ram_off;      /* offset into card memory of the					     descriptor */	Rid           rid_desc;		  /* card RID descriptor */	char          *virtual_host_addr; /* virtual address of host receive					     buffer */} HostRidDesc;typedef struct {	u16 sw0;	u16 sw1;	u16 status;	u16 len;#define HOST_SET (1 << 0)#define HOST_INT_TX (1 << 1) /* Interrupt on successful TX */#define HOST_INT_TXERR (1 << 2) /* Interrupt on unseccessful TX */#define HOST_LCC_PAYLOAD (1 << 4) /* LLC payload, 0 = Ethertype */#define HOST_DONT_RLSE (1 << 5) /* Don't release buffer when done */#define HOST_DONT_RETRY (1 << 6) /* Don't retry trasmit */#define HOST_CLR_AID (1 << 7) /* clear AID failure */#define HOST_RTS (1 << 9) /* Force RTS use */#define HOST_SHORT (1 << 10) /* Do short preamble */	u16 ctl;	u16 aid;	u16 retries;	u16 fill;} TxCtlHdr;typedef struct {        u16 ctl;        u16 duration;        char addr1[6];        char addr2[6];        char addr3[6];        u16 seq;        char addr4[6];} WifiHdr;typedef struct {	TxCtlHdr ctlhdr;	u16 fill1;	u16 fill2;	WifiHdr wifihdr;	u16 gaplen;	u16 status;} WifiCtlHdr;WifiCtlHdr wifictlhdr8023 = {	.ctlhdr = {		.ctl	= HOST_DONT_RLSE,	}};#ifdef WIRELESS_EXT// Frequency list (map channels to frequencies)static const long frequency_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,				2447, 2452, 2457, 2462, 2467, 2472, 2484 };// A few details needed for WEP (Wireless Equivalent Privacy)#define MAX_KEY_SIZE 13			// 128 (?) bits#define MIN_KEY_SIZE  5			// 40 bits RC4 - WEPtypedef struct wep_key_t {	u16	len;	u8	key[16];	/* 40-bit and 104-bit keys */} wep_key_t;/* Backward compatibility */#ifndef IW_ENCODE_NOKEY#define IW_ENCODE_NOKEY         0x0800  /* Key is write only, so not present */#define IW_ENCODE_MODE  (IW_ENCODE_DISABLED | IW_ENCODE_RESTRICTED | IW_ENCODE_OPEN)#endif /* IW_ENCODE_NOKEY *//* List of Wireless Handlers (new API) */static const struct iw_handler_def	airo_handler_def;#endif /* WIRELESS_EXT */static const char version[] = "airo.c 0.6 (Ben Reed & Javier Achirica)";struct airo_info;static int get_dec_u16( char *buffer, int *start, int limit );static void OUT4500( struct airo_info *, u16 register, u16 value );static unsigned short IN4500( struct airo_info *, u16 register );static u16 setup_card(struct airo_info*, u8 *mac, int lock);static int enable_MAC( struct airo_info *ai, Resp *rsp, int lock );static void disable_MAC(struct airo_info *ai, int lock);static void enable_interrupts(struct airo_info*);static void disable_interrupts(struct airo_info*);static u16 issuecommand(struct airo_info*, Cmd *pCmd, Resp *pRsp);static int bap_setup(struct airo_info*, u16 rid, u16 offset, int whichbap);static int aux_bap_read(struct airo_info*, u16 *pu16Dst, int bytelen,			int whichbap);static int fast_bap_read(struct airo_info*, u16 *pu16Dst, int bytelen,			 int whichbap);static int bap_write(struct airo_info*, const u16 *pu16Src, int bytelen,		     int whichbap);static int PC4500_accessrid(struct airo_info*, u16 rid, u16 accmd);static int PC4500_readrid(struct airo_info*, u16 rid, void *pBuf, int len, int lock);static int PC4500_writerid(struct airo_info*, u16 rid, const void			   *pBuf, int len, int lock);static int do_writerid( struct airo_info*, u16 rid, const void *rid_data,			int len, int dummy );static u16 transmit_allocate(struct airo_info*, int lenPayload, int raw);static int transmit_802_3_packet(struct airo_info*, int len, char *pPacket);static int transmit_802_11_packet(struct airo_info*, int len, char *pPacket);static int mpi_send_packet (struct net_device *dev);static void mpi_unmap_card(struct pci_dev *pci);static void mpi_receive_802_3(struct airo_info *ai);static void mpi_receive_802_11(struct airo_info *ai);static int waitbusy (struct airo_info *ai);static irqreturn_t airo_interrupt( int irq, void* dev_id, struct pt_regs			    *regs);static int airo_thread(void *data);static void timer_func( struct net_device *dev );static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);#ifdef WIRELESS_EXTstruct iw_statistics *airo_get_wireless_stats (struct net_device *dev);static void airo_read_wireless_stats (struct airo_info *local);#endif /* WIRELESS_EXT */#ifdef CISCO_EXTstatic int readrids(struct net_device *dev, aironet_ioctl *comp);static int writerids(struct net_device *dev, aironet_ioctl *comp);int flashcard(struct net_device *dev, aironet_ioctl *comp);#endif /* CISCO_EXT */#ifdef MICSUPPORTstatic void micinit(struct airo_info *ai);static int micsetup(struct airo_info *ai);static int encapsulate(struct airo_info *ai, etherHead *pPacket, MICBuffer *buffer, int len);static int decapsulate(struct airo_info *ai, MICBuffer *mic, etherHead *pPacket, u16 payLen);#include <linux/crypto.h>#endifstruct airo_info {	struct net_device_stats	stats;	struct net_device             *dev;	/* Note, we can have MAX_FIDS outstanding.  FIDs are 16-bits, so we	   use the high bit to mark whether it is in use. */#define MAX_FIDS 6#define MPI_MAX_FIDS 1	int                           fids[MAX_FIDS];	ConfigRid config;	char keyindex; // Used with auto wep	char defindex; // Used with auto wep	struct proc_dir_entry *proc_entry;        spinlock_t aux_lock;        unsigned long flags;#define FLAG_PROMISC	8	/* IFF_PROMISC 0x100 - include/linux/if.h */#define FLAG_RADIO_OFF	0	/* User disabling of MAC */#define FLAG_RADIO_DOWN	1	/* ifup/ifdown disabling of MAC */#define FLAG_RADIO_MASK 0x03#define FLAG_ENABLED	2#define FLAG_ADHOC	3	/* Needed by MIC */#define FLAG_MIC_CAPABLE 4#define FLAG_UPDATE_MULTI 5#define FLAG_UPDATE_UNI 6#define FLAG_802_11	7#define FLAG_PENDING_XMIT 9#define FLAG_PENDING_XMIT11 10#define FLAG_MPI	11#define FLAG_REGISTERED	12#define FLAG_COMMIT	13#define FLAG_RESET	14#define FLAG_FLASHING	15#define JOB_MASK	0x1ff0000#define JOB_DIE		16#define JOB_XMIT	17#define JOB_XMIT11	18#define JOB_STATS	19#define JOB_PROMISC	20#define JOB_MIC		21#define JOB_EVENT	22#define JOB_AUTOWEP	23#define JOB_WSTATS	24	int (*bap_read)(struct airo_info*, u16 *pu16Dst, int bytelen,			int whichbap);	unsigned short *flash;	tdsRssiEntry *rssi;	struct task_struct *task;	struct semaphore sem;	pid_t thr_pid;	wait_queue_head_t thr_wait;	struct completion thr_exited;	unsigned long expires;	struct {		struct sk_buff *skb;		int fid;	} xmit, xmit11;	struct net_device *wifidev;#ifdef WIRELESS_EXT	struct iw_statistics	wstats;		// wireless stats	unsigned long		scan_timestamp;	/* Time started to scan */	struct iw_spy_data	spy_data;	struct iw_public_data	wireless_data;#endif /* WIRELESS_EXT */#ifdef MICSUPPORT	/* MIC stuff */	struct crypto_tfm	*tfm;	mic_module		mod[2];	mic_statistics		micstats;#endif	HostRxDesc rxfids[MPI_MAX_FIDS]; // rx/tx/config MPI350 descriptors	HostTxDesc txfids[MPI_MAX_FIDS];	HostRidDesc config_desc;	unsigned long ridbus; // phys addr of config_desc	struct sk_buff_head txq;// tx queue used by mpi350 code	struct pci_dev          *pci;	unsigned char		__iomem *pcimem;	unsigned char		__iomem *pciaux;	unsigned char		*shared;	dma_addr_t		shared_dma;	int			power;	SsidRid			*SSID;	APListRid		*APList;#define	PCI_SHARED_LEN		2*MPI_MAX_FIDS*PKTSIZE+RIDSIZE	char			proc_name[IFNAMSIZ];};static inline int bap_read(struct airo_info *ai, u16 *pu16Dst, int bytelen,			   int whichbap) {	return ai->bap_read(ai, pu16Dst, bytelen, whichbap);}static int setup_proc_entry( struct net_device *dev,			     struct airo_info *apriv );static int takedown_proc_entry( struct net_device *dev,				struct airo_info *apriv );#ifdef MICSUPPORT/*********************************************************************** *                              MIC ROUTINES                           * *********************************************************************** */static int RxSeqValid (struct airo_info *ai,miccntx *context,int mcast,u32 micSeq);static void MoveWindow(miccntx *context, u32 micSeq);void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen, struct crypto_tfm *);void emmh32_init(emmh32_context *context);void emmh32_update(emmh32_context *context, u8 *pOctets, int len);void emmh32_final(emmh32_context *context, u8 digest[4]);/* micinit - Initialize mic seed */static void micinit(struct airo_info *ai){	MICRid mic_rid;	clear_bit(JOB_MIC, &ai->flags);	PC4500_readrid(ai, RID_MIC, &mic_rid, sizeof(mic_rid), 0);	up(&ai->sem);	ai->micstats.enabled = (mic_rid.state & 0x00FF) ? 1 : 0;	if (ai->micstats.enabled) {		/* Key must be valid and different */		if (mic_rid.multicastValid && (!ai->mod[0].mCtx.valid ||		    (memcmp (ai->mod[0].mCtx.key, mic_rid.multicast,			     sizeof(ai->mod[0].mCtx.key)) != 0))) {			/* Age current mic Context */			memcpy(&ai->mod[1].mCtx,&ai->mod[0].mCtx,sizeof(miccntx));			/* Initialize new context */			memcpy(&ai->mod[0].mCtx.key,mic_rid.multicast,sizeof(mic_rid.multicast));			ai->mod[0].mCtx.window  = 33; //Window always points to the middle			ai->mod[0].mCtx.rx      = 0;  //Rx Sequence numbers			ai->mod[0].mCtx.tx      = 0;  //Tx sequence numbers			ai->mod[0].mCtx.valid   = 1;  //Key is now valid  			/* Give key to mic seed */			emmh32_setseed(&ai->mod[0].mCtx.seed,mic_rid.multicast,sizeof(mic_rid.multicast), ai->tfm);		}		/* Key must be valid and different */		if (mic_rid.unicastValid && (!ai->mod[0].uCtx.valid || 		    (memcmp(ai->mod[0].uCtx.key, mic_rid.unicast,			    sizeof(ai->mod[0].uCtx.key)) != 0))) {			/* Age current mic Context */			memcpy(&ai->mod[1].uCtx,&ai->mod[0].uCtx,sizeof(miccntx));			/* Initialize new context */			memcpy(&ai->mod[0].uCtx.key,mic_rid.unicast,sizeof(mic_rid.unicast));				ai->mod[0].uCtx.window  = 33; //Window always points to the middle			ai->mod[0].uCtx.rx      = 0;  //Rx Sequence numbers			ai->mod[0].uCtx.tx      = 0;  //Tx sequence numbers			ai->mod[0].uCtx.valid   = 1;  //Key is now valid				//Give key to mic seed			emmh32_setseed(&ai->mod[0].uCtx.seed, mic_rid.unicast, sizeof(mic_rid.unicast), ai->tfm);		}	} else {      /* So next time we have a valid key and mic is enabled, we will update       * the sequence number if the key is the same as before.       */		ai->mod[0].uCtx.valid = 0;		ai->mod[0].mCtx.valid = 0;	}}/* micsetup - Get ready for business */static int micsetup(struct airo_info *ai) {	int i;	if (ai->tfm == NULL)	        ai->tfm = crypto_alloc_tfm("aes", 0);        if (ai->tfm == NULL) {                printk(KERN_ERR "airo: failed to load transform for AES\n");                return ERROR;        }	for (i=0; i < NUM_MODULES; i++) {		memset(&ai->mod[i].mCtx,0,sizeof(miccntx));		memset(&ai->mod[i].uCtx,0,sizeof(miccntx));	}	return SUCCESS;}char micsnap[]= {0xAA,0xAA,0x03,0x00,0x40,0x96,0x00,0x02};/*=========================================================================== * Description: Mic a packet *     *      Inputs: etherHead * pointer to an 802.3 frame *     *     Returns: BOOLEAN if successful, otherwise false. *             PacketTxLen will be updated with the mic'd packets size. * *    Caveats: It is assumed that the frame buffer will already *             be big enough to hold the largets mic message possible. *            (No memory allocation is done here). *   *    Author: sbraneky (10/15/01) *    Merciless hacks by rwilcher (1/14/02) */static int encapsulate(struct airo_info *ai ,etherHead *frame, MICBuffer *mic, int payLen){	miccntx   *context;	// Determine correct context	// If not adhoc, always use unicast key	if (test_bit(FLAG_ADHOC, &ai->flags) && (frame->da[0] & 0x1))		context = &ai->mod[0].mCtx;	else		context = &ai->mod[0].uCtx;  	if (!context->valid)		return ERROR;	mic->typelen = htons(payLen + 16); //Length of Mic'd packet	memcpy(&mic->u.snap, micsnap, sizeof(micsnap)); // Add Snap	// Add Tx sequence	mic->seq = htonl(context->tx);	context->tx += 2;	emmh32_init(&context->seed); // Mic the packet	emmh32_update(&context->seed,frame->da,ETH_ALEN * 2); // DA,SA	emmh32_update(&context->seed,(u8*)&mic->typelen,10); // Type/Length and Snap	emmh32_update(&context->seed,(u8*)&mic->seq,sizeof(mic->seq)); //SEQ	emmh32_update(&context->seed,frame->da + ETH_ALEN * 2,payLen); //payload	emmh32_final(&context->seed, (u8*)&mic->mic);	/*    New Type/length ?????????? */	mic->typelen = 0; //Let NIC know it could be an oversized packet	return SUCCESS;}typedef enum {    NONE,    NOMIC,    NOMICPLUMMED,    SEQUENCE,    INCORRECTMIC,} mic_error;/*=========================================================================== *  Description: Decapsulates a MIC'd packet and returns the 802.3 packet *               (removes the MIC stuff) if packet is a valid packet. *       *       Inputs: etherHead  pointer to the 802.3 packet              *      *      Returns: BOOLEAN - TRUE if packet should be dropped otherwise FALSE *      *      Author: sbraneky (10/15/01) *    Merciless hacks by rwilcher (1/14/02) *--------------------------------------------------------------------------- */static int decapsulate(struct airo_info *ai, MICBuffer *mic, etherHead *eth, u16 payLen){	int      i;	u32      micSEQ;	miccntx  *context;	u8       digest[4];	mic_error micError = NONE;	// Check if the packet is a Mic'd packet	if (!ai->micstats.enabled) {		//No Mic set or Mic OFF but we received a MIC'd packet.		if (memcmp ((u8*)eth + 14, micsnap, sizeof(micsnap)) == 0) {			ai->micstats.rxMICPlummed++;			return ERROR;		}		return SUCCESS;	}	if (ntohs(mic->typelen) == 0x888E)		return SUCCESS;

⌨️ 快捷键说明

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