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

📄 dsr-dev.c

📁 DSR-UU is a DSR implementation that runs in Linux and in the ns-2 network simulator. DSR-UU imple
💻 C
📖 第 1 页 / 共 2 页
字号:
		DEBUG("Removing pack\n");		dev_remove_pack(&dsr_packet_type);		dsr_packet_type.func = NULL;	}	dev_put(dev);	dsr_node = NULL;}#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)static int __init dsr_dev_setup(struct net_device *dev)#elsestatic void __init dsr_dev_setup(struct net_device *dev)#endif{	/* Fill in device structure with ethernet-generic values. */	ether_setup(dev);	/* Initialize the device structure. */	dev->get_stats = dsr_dev_get_stats;	dev->uninit = dsr_dev_uninit;	dev->open = dsr_dev_open;	dev->stop = dsr_dev_stop;	dev->hard_start_xmit = dsr_dev_start_xmit;	dev->set_multicast_list = set_multicast_list;	dev->set_mac_address = dsr_dev_set_address;#ifdef CONFIG_NET_FASTROUTE	dev->accept_fastpath = dsr_dev_accept_fastpath;#endif	dev->tx_queue_len = 0;	dev->flags |= IFF_NOARP;	dev->flags &= ~IFF_MULTICAST;	SET_MODULE_OWNER(dev);	//random_ether_addr(dev->dev_addr);	get_random_bytes(dev->dev_addr, 6);#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	return 0;#endif}#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)static int dsr_dev_llrecv(struct sk_buff *skb,			  struct net_device *indev, 			  struct packet_type *pt)#elsestatic int dsr_dev_llrecv(struct sk_buff *skb,			  struct net_device *indev, 			  struct packet_type *pt, 			  struct net_device *orig_dev)#endif{	/* DEBUG("Packet recvd\n"); *//* 	if (do_mackill(skb->mac.raw + ETH_ALEN)) { *//* 		kfree_skb(skb); *//* 		return 0; *//* 	} */	if (skb->pkt_type == PACKET_OTHERHOST)		dsr_ip_recv(skb);	else		dev_kfree_skb_any(skb);	return 0;}int dsr_dev_deliver(struct dsr_pkt *dp){	struct sk_buff *skb = NULL;	struct ethhdr *ethh;	int len;	if (!dp)		return -1;	/* Super ugly hack to fix record route options */	if (dp->skb->nh.iph->ihl > 5) {		struct ip_options *opt = &(IPCB(dp->skb)->opt);		unsigned char *ptr = dp->skb->nh.raw;			if (opt->rr) {				struct ipopt {				u_int8_t code;				u_int8_t len;				u_int8_t off;			} *rr = (struct ipopt *)&ptr[opt->rr];						if (rr->off < 32) {								/* Remove the last recorded address since it will				 * recorded again when passed up the IP stack for the				 * second time on the virtual interface. */				rr->off -= 4;				rr->len -= 4;				opt->optlen -= 4;			}			/* ip_send_check(dp->skb->nh.iph); */		}	}	if (dp->dh.raw)		len = dsr_opt_remove(dp);	skb = dsr_skb_create(dp, dsr_dev);	if (!skb) {		DEBUG("Could not allocate skb\n");		dsr_pkt_free(dp);		return -1;	}	/* Need to make hardware header visible again since we are going down a	 * layer */	skb->mac.raw = skb->data - dsr_dev->hard_header_len;	skb->ip_summed = CHECKSUM_UNNECESSARY;		ethh = (struct ethhdr *)skb->mac.raw;	memcpy(ethh->h_dest, dsr_dev->dev_addr, ETH_ALEN);	memset(ethh->h_source, 0, ETH_ALEN);	ethh->h_proto = htons(ETH_P_IP);	dsr_node_lock(dsr_node);	dsr_node->stats.rx_packets++;	dsr_node->stats.rx_bytes += skb->len;	dsr_node_unlock(dsr_node);	netif_rx(skb);	dsr_pkt_free(dp);	return 0;}int dsr_dev_xmit(struct dsr_pkt *dp){	struct sk_buff *skb;	struct net_device *slave_dev;	struct in_addr dst;	int res = -1;	int len = 0;		if (!dp)		return -1;	if (dp->flags & PKT_REQUEST_ACK)		maint_buf_add(dp);	dsr_node_lock(dsr_node);	if (dsr_node->slave_dev)		slave_dev = dsr_node->slave_dev;	else {		dsr_node_unlock(dsr_node);		goto out_err;	}	dsr_node_unlock(dsr_node);	skb = dsr_skb_create(dp, slave_dev);	if (!skb) {		DEBUG("Could not create skb!\n");		goto out_err;	}	/* Create hardware header */	if (dsr_hw_header_create(dp, skb) < 0) {		DEBUG("Could not create hardware header\n");		dev_kfree_skb_any(skb);		goto out_err;	}		len = skb->len;	dst.s_addr = skb->nh.iph->daddr;		DEBUG("Sending %d bytes data_len=%d %s : %s\n",	      len, skb->data_len,	      print_eth(skb->mac.raw),	      print_ip(dst));			/* TODO: Should consider using ip_finish_output instead */	res = dev_queue_xmit(skb);	if (res < 0)		goto out_err;	dsr_node_lock(dsr_node);	dsr_node->stats.tx_packets++;	dsr_node->stats.tx_bytes += len;	dsr_node_unlock(dsr_node);out_err:	dsr_pkt_free(dp);	return res;}/* Main receive function for packets originated in user space */static int dsr_dev_start_xmit(struct sk_buff *skb, struct net_device *dev){	struct dsr_node *dnode = (struct dsr_node *)dev->priv;	struct ethhdr *ethh;	struct dsr_pkt *dp;#ifdef DEBUG	atomic_inc(&num_pkts);#endif	if (dnode->slave_dev == NULL) {		dev_kfree_skb_any(skb);		DEBUG("Packet dropped\n");		return 0;	}	ethh = (struct ethhdr *)skb->data;	switch (ntohs(ethh->h_proto)) {	case ETH_P_IP:		DEBUG("dst=%s len=%d\n",		      print_ip(*((struct in_addr *)&skb->nh.iph->daddr)),		      skb->len);		dp = dsr_pkt_alloc(skb);				if (!dp) {			dev_kfree_skb_any(skb);			return 0;		}					dsr_start_xmit(dp);		break;	default:		DEBUG("Unknown packet type, dropping...\n");		dev_kfree_skb_any(skb);	}	return 0;}static struct net_device_stats *dsr_dev_get_stats(struct net_device *dev){	return &(((struct dsr_node *)dev->priv)->stats);}static struct notifier_block netdev_notifier = {      notifier_call:dsr_dev_netdev_event,};/* Notifier for inetaddr addition/deletion events.  */static struct notifier_block inetaddr_notifier = {	.notifier_call = dsr_dev_inetaddr_event,};int dsr_dev_init(char *ifname){	int res = 0;	struct dsr_node *dnode;#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	dsr_dev = alloc_etherdev(sizeof(struct dsr_node));	if (!dsr_dev)		return -ENOMEM;		dsr_dev->init = dsr_dev_setup;	dev_alloc_name(dsr_dev, "dsr%d");	dsr_dev->init = &dsr_dev_setup;#else	dsr_dev = alloc_netdev(sizeof(struct dsr_node), "dsr%d", dsr_dev_setup);	if (!dsr_dev)		return -ENOMEM;#endif	dnode = dsr_node = (struct dsr_node *)dsr_dev->priv;	dsr_node_init(dnode, ifname);	if (ifname) {		memcpy(dnode->slave_ifname, ifname, IFNAMSIZ);	} else {		struct net_device *tmp_dev;				read_lock(&dev_base_lock);		for (tmp_dev = dev_base; tmp_dev != NULL; 		     tmp_dev = tmp_dev->next) {			if (tmp_dev->get_wireless_stats) {				memcpy(dnode->slave_ifname, tmp_dev->name, IFNAMSIZ);							read_unlock(&dev_base_lock);				goto dev_ok;			}		}		read_unlock(&dev_base_lock);			DEBUG("No proper slave device found\n");		res = -1;		goto cleanup_netdev;	}dev_ok:		DEBUG("Slave device is %s\n", dnode->slave_ifname);				res = register_netdev(dsr_dev);	dsr_packet_type.func = NULL;	if (res < 0)		goto cleanup_netdev;	res = register_netdevice_notifier(&netdev_notifier);	if (res < 0)		goto cleanup_netdev_register;	res = register_inetaddr_notifier(&inetaddr_notifier);	if (res < 0)		goto cleanup_netdevice_notifier;	/* We increment usage count since we hold a reference */	dev_hold(dsr_dev);	return 0;      cleanup_netdevice_notifier:	unregister_netdevice_notifier(&netdev_notifier);      cleanup_netdev_register:	unregister_netdev(dsr_dev);      cleanup_netdev:#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)	free_netdev(dsr_dev);#else	kfree(dsr_dev);#endif	return res;}void __exit dsr_dev_cleanup(void){	unregister_netdevice_notifier(&netdev_notifier);	unregister_inetaddr_notifier(&inetaddr_notifier);	unregister_netdev(dsr_dev);#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)	free_netdev(dsr_dev);#else	kfree(dsr_dev);#endif}

⌨️ 快捷键说明

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