📄 ndrv.c
字号:
/* * \brief this file implements two drivers to simulate ethernet layer communication * * Drivers are run under linux 2.4 kernel: * snic --- part of the NIC simulator * shost --- simuates a network host * * The way the whole platform works goes as follows: * QF-NET<->NIC simulator<->snic(driver)<--->shost(driver)<->linux TCP/IP stack */#ifndef __KERNEL__#define __KERNEL__#endif#ifndef MODULE#define MODULE#endif#include <linux/config.h>#include <linux/module.h>#include <asm/byteorder.h>#include <asm/uaccess.h>#include <linux/sched.h>#include <linux/kernel.h> /* printk() */#include <linux/slab.h> /* kmalloc() */#include <linux/errno.h> /* error codes */#include <linux/types.h> /* size_t */#include <linux/interrupt.h> /* mark_bh */#include <linux/in.h>#include <linux/netdevice.h> /* struct device, and other headers */#include <linux/etherdevice.h> /* eth_type_trans */#include <linux/if_arp.h> /*struct arphdr */#include <linux/ip.h> /*struct iphdr */#include <linux/icmp.h> /*struct icmphdr*/#include <linux/tcp.h> /* struct tcphdr*/#include <linux/skbuff.h>#include "nspy.h"//...................................................................MODULE_LICENSE("GPL");MODULE_AUTHOR("Aaron Hua");//.................................................................../// private struct to do the driver statisticsstruct snic_priv { struct net_device_stats stats; int irq_status; int rx_packetlen; u8 *rx_packetdata; int tx_packetlen; u8 *tx_packetdata;// struct sk_buff *skbtx;// struct sk_buff *skbrx; spinlock_t lock;};//.................................................................../// NIC simulator functionsstatic int snic_open(struct net_device *);static int snic_stop(struct net_device *);static int snic_xmit(struct sk_buff *, struct net_device *);static void snic_recv(struct sk_buff *, struct net_device *);static int snic_config(struct net_device *,struct ifmap *);static int snic_ioctl(struct net_device *,struct ifreq *, int);static int snic_init(struct net_device *);static void snic_uninit(struct net_device *);//.................................................................../// host simulator functionsstatic int shost_open(struct net_device *);static int shost_stop(struct net_device *);static int shost_xmit(struct sk_buff *, struct net_device *);static void shost_recv(struct sk_buff *, struct net_device *);static struct net_device_stats * shost_stats();static int shost_init(struct net_device *);static void shost_uninit(struct net_device *);//.................................................................../// simulated net interface controller (kernel part)static struct net_device snic = { name: "snic", init: snic_init, uninit:snic_uninit, };/// simulated peer host in the same lan static struct net_device shost = { name: "shost", init: shost_init, uninit:shost_uninit, };//.................................................................../// called at IFCONFIG interface UPstatic int snic_open(struct net_device *dev){ printk("snic opened\n"); return 0;}//.................................................................../// called at IFCONFIG interface DOWNstatic int snic_stop(struct net_device *dev){ printk("snic stoped\n"); return 0;}//.................................................................../// called when the higher layer pass down a packetstatic int snic_xmit(struct sk_buff *skb, struct net_device *dev){ printk("snic send\n"); // spy_eth((struct ethhdr*)skb->data); // ethernet frame from the user-level NIC simulator shost_recv(skb, &shost); return 0; // no error should occur in transmitting}//.................................................................../// device receives an ingressing packetstatic void snic_recv(struct sk_buff *skb, struct net_device *dev){ // pass to the usr-level NIC simlulator directly printk("snic recv\n"); // spy_all(skb); // the packet should be left untouched by the kernel skb->dev = dev; skb->protocol = 0; netif_rx(skb); return;}//.................................................................../// interact with ifconfigstatic int snic_config(struct net_device *dev,struct ifmap *map){ return 0;}//.................................................................../// private control commands to this device /// further control might be nedded to simulate specific NIC featurestatic int snic_ioctl( struct net_device *dev, struct ifreq *ifr, int cmd){ return 0;}//.................................................................../// creator, called at registering the devicestatic int snic_init(struct net_device *dev){ SET_MODULE_OWNER(dev); ether_setup(dev); // assign some of the fields // our specif functions dev->open = snic_open; dev->stop = snic_stop; dev->hard_start_xmit = snic_xmit; dev->set_config = snic_config; dev->do_ioctl = snic_ioctl; // Disable neighbour function, dev->change_mtu = NULL; dev->rebuild_header = NULL; dev->hard_header_cache = NULL; // Disable caching dev->header_cache_update = NULL; dev->flags |= IFF_NOARP; // DISABLE hard_header & hard_header_parsee and pass it // WITHOUT using eth_type_trans(), we make the frame // content invisible to linux kernel. // The frame will be directly passed to the raw socket // without being touched by the kernel. dev->hard_header = NULL; dev->hard_header_parse = NULL; // also OK without priv data dev->priv = kmalloc(sizeof(struct snic_priv), GFP_KERNEL); if (dev->priv == NULL) { return -ENOMEM; } memset(dev->priv, 0, sizeof(struct snic_priv)); printk("snic setup\n"); return 0;}//.................................................................../// destructor, called at unregistering the devicestatic void snic_uninit(struct net_device *dev){ if( NULL != dev->priv ) // we may have failed at kmalloc { kfree(dev->priv); } return;}//.................................................................../// called at IFCONFIG interface UPstatic int shost_open(struct net_device *dev){ printk("shost opened\n"); return 0;}//.................................................................../// called at IFCONFIG interface DOWNstatic int shost_stop(struct net_device *dev){ printk("shost stoped\n"); return 0;}//.................................................................../// called when the higher layer pass down a packetstatic int shost_xmit(struct sk_buff *skb, struct net_device *dev){ printk("shost send\n"); // eth header has been appended by the kernal snic_recv(skb, &snic); return 0; // no error should occur in transmitting}//.................................................................../// device receives an ingressing packetstatic void shost_recv(struct sk_buff *skb, struct net_device *dev){ printk("shost recv\n");// spy_all(skb); // extract the payload and pass it the the upper layer skb->dev = dev; skb->protocol = eth_type_trans(skb, dev);// skb->ip_summed = CHECKSUM_UNNECESSARY; /* don't check it */// priv->stats.rx_packets++; netif_rx(skb); return;}//.................................................................../// get specific status from the host/// we may need to further inspect the communication static struct net_device_stats * shost_stats(){ return 0;}//.................................................................../// creator, called at registering the devicestatic int shost_init(struct net_device *dev){ SET_MODULE_OWNER(dev); ether_setup(dev); // assign some of the fields dev->open = shost_open; dev->stop = shost_stop; dev->hard_start_xmit = shost_xmit; dev->get_stats = shost_stats; ////////////////////////////////// dev->flags |= IFF_NOARP; // OK without priv data dev->priv = kmalloc(sizeof(struct snic_priv), GFP_KERNEL); if (dev->priv == NULL) { return -ENOMEM; } memset(dev->priv, 0, sizeof(struct snic_priv)); printk("driver setup\n"); return 0;}//.................................................................../// destructor, called at unregistering the devicestatic void shost_uninit(struct net_device *dev){ if( NULL != dev->priv ) // we may have failed at kmalloc { kfree(dev->priv); } return;}//.................................................................../// routines done at loading and unloading the module/// probe for the virtual net devices needed by the simulator int vdev_probe(void){ if( register_netdev(&snic) ) { printk("register NIC simulator %s fail\n", snic.name ); goto FAIL_RET; } if( register_netdev(&shost) ) { printk("register host simulator %s fail\n", shost.name ); goto FAIL_CLEAN; } return 0; FAIL_CLEAN: unregister_netdev(&snic);FAIL_RET: return -ENODEV;}//...................................................................void vdev_cleanup(void){ unregister_netdev(&snic); unregister_netdev(&shost);}//---module_init(vdev_probe);module_exit(vdev_cleanup);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -