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

📄 sdla_ppp.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
		/* If we get here, some higher layer thinks we've missed an		 * tx-done interrupt.		 */		printk(KERN_INFO "%s: interface %s got kicked!\n",			card->devname, dev->name);				++ppp_priv_area->if_send_stat.if_send_skb_null;			netif_wake_queue(dev);		return 0;	}	sendpacket = skb->data;	udp_type = udp_pkt_type( skb, card );	if (udp_type == UDP_PTPIPE_TYPE){		if(store_udp_mgmt_pkt(UDP_PKT_FRM_STACK, card, skb, dev,                	              ppp_priv_area)){	               	flags->imask |= PPP_INTR_TIMER;		}		++ppp_priv_area->if_send_stat.if_send_PIPE_request;		netif_start_queue(dev);		return 0;	}	/* Check for broadcast and multicast addresses 	 * If found, drop (deallocate) a packet and return.	 */	if(chk_bcast_mcast_addr(card, dev, skb)){		++card->wandev.stats.tx_dropped;		dev_kfree_skb_any(skb);		netif_start_queue(dev);		return 0;	} 	if(card->hw.type != SDLA_S514){		s508_lock(card,&smp_flags);	}    	if (test_and_set_bit(SEND_CRIT, (void*)&card->wandev.critical)) {		printk(KERN_INFO "%s: Critical in if_send: %lx\n",				card->wandev.name,card->wandev.critical);				++card->wandev.stats.tx_dropped;		++ppp_priv_area->if_send_stat.if_send_critical_non_ISR;		netif_start_queue(dev);		goto if_send_exit_crit;	}	if (card->wandev.state != WAN_CONNECTED) {		++ppp_priv_area->if_send_stat.if_send_wan_disconnected;        	++card->wandev.stats.tx_dropped;		netif_start_queue(dev);		     	} else if (!skb->protocol) {		++ppp_priv_area->if_send_stat.if_send_protocol_error;        	++card->wandev.stats.tx_errors;		netif_start_queue(dev);			} else {		/*If it's IPX change the network numbers to 0 if they're ours.*/		if( skb->protocol == htons(ETH_P_IPX) ) {			if(ppp_priv_area->enable_IPX) {				switch_net_numbers( skb->data, 					ppp_priv_area->network_number, 0);			} else {				++card->wandev.stats.tx_dropped;				netif_start_queue(dev);				goto if_send_exit_crit;			}		}		if (ppp_send(card, skb->data, skb->len, skb->protocol)) {			netif_stop_queue(dev);			++ppp_priv_area->if_send_stat.if_send_adptr_bfrs_full;			++ppp_priv_area->if_send_stat.if_send_tx_int_enabled;		} else {			++ppp_priv_area->if_send_stat.if_send_bfr_passed_to_adptr;			++card->wandev.stats.tx_packets;			card->wandev.stats.tx_bytes += skb->len;			netif_start_queue(dev);			dev->trans_start = jiffies;		}    	}	if_send_exit_crit:		if (!(err=netif_queue_stopped(dev))){      		dev_kfree_skb_any(skb);	}else{		ppp_priv_area->tick_counter = jiffies;		flags->imask |= PPP_INTR_TXRDY;	/* unmask Tx interrupts */	}		clear_bit(SEND_CRIT,&card->wandev.critical);	if(card->hw.type != SDLA_S514){			s508_unlock(card,&smp_flags);	}	return err;}/*============================================================================= * Store a UDP management packet for later processing. */static int store_udp_mgmt_pkt(char udp_pkt_src, sdla_t* card,                                struct sk_buff *skb, struct net_device* dev,                                ppp_private_area_t* ppp_priv_area ){	int udp_pkt_stored = 0;	if(!ppp_priv_area->udp_pkt_lgth && (skb->len<=MAX_LGTH_UDP_MGNT_PKT)){        	ppp_priv_area->udp_pkt_lgth = skb->len;		ppp_priv_area->udp_pkt_src = udp_pkt_src;       		memcpy(ppp_priv_area->udp_pkt_data, skb->data, skb->len);		ppp_priv_area->timer_int_enabled |= TMR_INT_ENABLED_UDP;		ppp_priv_area->protocol = skb->protocol;		udp_pkt_stored = 1;	}else{		if (skb->len > MAX_LGTH_UDP_MGNT_PKT){			printk(KERN_INFO "%s: PIPEMON UDP request too long : %i\n",				card->devname, skb->len);		}else{			printk(KERN_INFO "%s: PIPEMON UPD request already pending\n",				card->devname);		}		ppp_priv_area->udp_pkt_lgth = 0;	}	if(udp_pkt_src == UDP_PKT_FRM_STACK){		dev_kfree_skb_any(skb);	}else{                dev_kfree_skb_any(skb);	}	return(udp_pkt_stored);}/*============================================================================ * Reply to UDP Management system. * Return length of reply. */static int reply_udp( unsigned char *data, unsigned int mbox_len ) {	unsigned short len, udp_length, temp, ip_length;	unsigned long ip_temp;	int even_bound = 0;	ppp_udp_pkt_t *p_udp_pkt = (ppp_udp_pkt_t *)data; 	/* Set length of packet */	len = sizeof(ip_pkt_t)+ 	      sizeof(udp_pkt_t)+	      sizeof(wp_mgmt_t)+	      sizeof(cblock_t)+	      mbox_len;	/* fill in UDP reply */  	p_udp_pkt->wp_mgmt.request_reply = UDPMGMT_REPLY; 	/* fill in UDP length */	udp_length = sizeof(udp_pkt_t)+ 		     sizeof(wp_mgmt_t)+		     sizeof(cblock_t)+		     mbox_len;    	/* put it on an even boundary */	if ( udp_length & 0x0001 ) {		udp_length += 1;		len += 1;		even_bound=1;	} 		temp = (udp_length<<8)|(udp_length>>8);	p_udp_pkt->udp_pkt.udp_length = temp;		 	/* swap UDP ports */	temp = p_udp_pkt->udp_pkt.udp_src_port;	p_udp_pkt->udp_pkt.udp_src_port = 			p_udp_pkt->udp_pkt.udp_dst_port; 	p_udp_pkt->udp_pkt.udp_dst_port = temp;	/* add UDP pseudo header */	temp = 0x1100;	*((unsigned short *)(p_udp_pkt->data+mbox_len+even_bound)) = temp;	temp = (udp_length<<8)|(udp_length>>8);	*((unsigned short *)(p_udp_pkt->data+mbox_len+even_bound+2)) = temp; 	/* calculate UDP checksum */	p_udp_pkt->udp_pkt.udp_checksum = 0;	p_udp_pkt->udp_pkt.udp_checksum = 		calc_checksum(&data[UDP_OFFSET],udp_length+UDP_OFFSET);	/* fill in IP length */	ip_length = udp_length + sizeof(ip_pkt_t);	temp = (ip_length<<8)|(ip_length>>8);  	p_udp_pkt->ip_pkt.total_length = temp; 	/* swap IP addresses */	ip_temp = p_udp_pkt->ip_pkt.ip_src_address;	p_udp_pkt->ip_pkt.ip_src_address = p_udp_pkt->ip_pkt.ip_dst_address;	p_udp_pkt->ip_pkt.ip_dst_address = ip_temp;	/* fill in IP checksum */	p_udp_pkt->ip_pkt.hdr_checksum = 0;	p_udp_pkt->ip_pkt.hdr_checksum = calc_checksum(data,sizeof(ip_pkt_t));	return len;} /* reply_udp */unsigned short calc_checksum (char *data, int len){	unsigned short temp; 	unsigned long sum=0;	int i;	for( i = 0; i <len; i+=2 ) {		memcpy(&temp,&data[i],2);		sum += (unsigned long)temp;	}	while (sum >> 16 ) {		sum = (sum & 0xffffUL) + (sum >> 16);	}	temp = (unsigned short)sum;	temp = ~temp;	if( temp == 0 ) 		temp = 0xffff;	return temp;	}/*   If incoming is 0 (outgoing)- if the net numbers is ours make it 0   if incoming is 1 - if the net number is 0 make it ours */static void switch_net_numbers(unsigned char *sendpacket, unsigned long network_number, unsigned char incoming){	unsigned long pnetwork_number;	pnetwork_number = (unsigned long)((sendpacket[6] << 24) + 			  (sendpacket[7] << 16) + (sendpacket[8] << 8) + 			  sendpacket[9]);	if (!incoming) {		//If the destination network number is ours, make it 0		if( pnetwork_number == network_number) {			sendpacket[6] = sendpacket[7] = sendpacket[8] = 					 sendpacket[9] = 0x00;		}	} else {		//If the incoming network is 0, make it ours		if( pnetwork_number == 0) {			sendpacket[6] = (unsigned char)(network_number >> 24);			sendpacket[7] = (unsigned char)((network_number & 					 0x00FF0000) >> 16);			sendpacket[8] = (unsigned char)((network_number & 					 0x0000FF00) >> 8);			sendpacket[9] = (unsigned char)(network_number & 					 0x000000FF);		}	}	pnetwork_number = (unsigned long)((sendpacket[18] << 24) + 			  (sendpacket[19] << 16) + (sendpacket[20] << 8) + 			  sendpacket[21]);	if( !incoming ) {		//If the source network is ours, make it 0		if( pnetwork_number == network_number) {			sendpacket[18] = sendpacket[19] = sendpacket[20] = 					 sendpacket[21] = 0x00;		}	} else {		//If the source network is 0, make it ours		if( pnetwork_number == 0 ) {			sendpacket[18] = (unsigned char)(network_number >> 24);			sendpacket[19] = (unsigned char)((network_number & 					 0x00FF0000) >> 16);			sendpacket[20] = (unsigned char)((network_number & 					 0x0000FF00) >> 8);			sendpacket[21] = (unsigned char)(network_number & 					 0x000000FF);		}	}} /* switch_net_numbers *//*============================================================================ * Get ethernet-style interface statistics. * Return a pointer to struct net_device_stats. */static struct net_device_stats *if_stats(struct net_device *dev){	ppp_private_area_t *ppp_priv_area = dev->priv;	sdla_t* card;		if( ppp_priv_area == NULL )		return NULL;	card = ppp_priv_area->card;	return &card->wandev.stats;}/****** PPP Firmware Interface Functions ************************************//*============================================================================ * Read firmware code version. *	Put code version as ASCII string in str.  */static int ppp_read_version(sdla_t *card, char *str){	ppp_mbox_t *mb = card->mbox;	int err;	memset(&mb->cmd, 0, sizeof(ppp_cmd_t));	mb->cmd.command = PPP_READ_CODE_VERSION;	err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;	if (err != CMD_OK) 		ppp_error(card, err, mb);	else if (str) {		int len = mb->cmd.length;		memcpy(str, mb->data, len);		str[len] = '\0';	}	return err;}/*=========================================================================== * Set Out-Bound Authentication.*/static int ppp_set_outbnd_auth (sdla_t *card, ppp_private_area_t *ppp_priv_area){	ppp_mbox_t *mb = card->mbox;	int err;	memset(&mb->cmd, 0, sizeof(ppp_cmd_t));	memset(&mb->data, 0, (strlen(ppp_priv_area->userid) + 					strlen(ppp_priv_area->passwd) + 2 ) );	memcpy(mb->data, ppp_priv_area->userid, strlen(ppp_priv_area->userid));	memcpy((mb->data + strlen(ppp_priv_area->userid) + 1), 		ppp_priv_area->passwd, strlen(ppp_priv_area->passwd));			mb->cmd.length  = strlen(ppp_priv_area->userid) + 					strlen(ppp_priv_area->passwd) + 2 ;		mb->cmd.command = PPP_SET_OUTBOUND_AUTH;	err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;	if (err != CMD_OK)		ppp_error(card, err, mb);	return err;}/*=========================================================================== * Set In-Bound Authentication.*/static int ppp_set_inbnd_auth (sdla_t *card, ppp_private_area_t *ppp_priv_area){	ppp_mbox_t *mb = card->mbox;	int err, i;	char* user_tokens[32];	char* pass_tokens[32];	int userids, passwds;	int add_ptr;	memset(&mb->cmd, 0, sizeof(ppp_cmd_t));	memset(&mb->data, 0, 1008);	memcpy(mb->data, ppp_priv_area->sysname, 						strlen(ppp_priv_area->sysname));		/* Parse the userid string and the password string and build a string	   to copy it to the data area of the command structure.   The string	   will look like "SYS_NAME<NULL>USER1<NULL>PASS1<NULL>USER2<NULL>PASS2	   ....<NULL> " 	 */	userids = tokenize( ppp_priv_area->userid, user_tokens);	passwds = tokenize( ppp_priv_area->passwd, pass_tokens);		if (userids != passwds){		printk(KERN_INFO "%s: Number of passwords does not equal the number of user ids\n", card->devname);		return 1;		}	add_ptr = strlen(ppp_priv_area->sysname) + 1;	for (i=0; i<userids; i++){		memcpy((mb->data + add_ptr), user_tokens[i], 							strlen(user_tokens[i]));		memcpy((mb->data + add_ptr + strlen(user_tokens[i]) + 1), 					pass_tokens[i], strlen(pass_tokens[i]));		add_ptr = add_ptr + strlen(user_tokens[i]) + 1 + 						strlen(pass_tokens[i]) + 1;	}	mb->cmd.length  = add_ptr + 1;	mb->cmd.command = PPP_SET_INBOUND_AUTH;	err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;	if (err != CMD_OK)		ppp_error(card, err, mb);	return err;}/*============================================================================ * Tokenize string. *      Parse a string of the following syntax: *              <arg1>,<arg2>,... *      and fill array of tokens with pointers to string elements. * */static int tokenize (char *str, char **tokens){        int cnt = 0;

⌨️ 快捷键说明

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