13. Linux Kernel Driver Program: 7_Network device driver
/* * Building a Basic Network Driver Stub * * Write a basic network device driver. * * It should register itself upon loading, and unregister upon * removal. * * Supply minimal open() and stop() methods. * * You should be able to exercise it with: * * insmod lab1_network.ko * ifconfig mynet0 up 192.168.3.197 * ifconfig mynet0 * * Make sure your chosen address is not being used by anything else. * * Warning: Depending on kernel version, your stub driver may crash if * you try to bring it up or ping it. If you put in a trivial * transmit function, such as * * static int stub_start_xmit (struct sk_buff *skb, struct net_device *dev) * { * dev_kfree_skb (skb); * return 0; * } * this should avoid the problems. * @*/ #include <linux/module.h> #include <linux/netdevice.h> #include <linux/init.h> static struct net_device *dev; static int my_open(struct net_device *dev) { pr_info("Hit: my_open(%s)\n", dev->name); /* start up the transmission queue */ netif_start_queue(dev); return 0; } static int my_close(struct net_device *dev) { pr_info("Hit: my_close(%s)\n", dev->name); /* shutdown the transmission queue */ netif_stop_queue(dev); return 0; } /* Note this method is only needed on some; without it module will fail upon removal or use. At any rate there is a memory leak whenever you try to send a packet through in any case*/ static int stub_start_xmit(struct sk_buff *skb, struct net_device *dev) { dev_kfree_skb(skb); return 0; } static struct net_device_ops ndo = { .ndo_open = my_open, .ndo_stop = my_close, .ndo_start_xmit = stub_start_xmit, }; static void my_setup(struct net_device *dev) { int j; pr_info("my_setup(%s)\n", dev->name); /* Fill in the MAC address with a phoney */ for (j = 0; j < ETH_ALEN; ++j) { dev->dev_addr[j] = (char)j; } ether_setup(dev); dev->netdev_ops = &ndo; } static int __init my_init(void) { pr_info("Loading stub network module:...."); dev = alloc_netdev(0, "mynet%d", my_setup); if (register_netdev(dev)) { pr_info(" Failed to register\n"); free_netdev(dev); return -1; } pr_info("Succeeded in loading %s!\n\n", dev_name(&dev->dev)); return 0; } static void __exit my_exit(void) { pr_info("Unloading stub network module\n\n"); unregister_netdev(dev); free_netdev(dev); } module_init(my_init); module_exit(my_exit); MODULE_AUTHOR("Bill Shubert"); MODULE_AUTHOR("Jerry Cooperstein"); MODULE_AUTHOR("Tatsuo Kawasaki"); MODULE_DESCRIPTION("LDD:2.0 s_24/lab1_network.c"); MODULE_LICENSE("GPL v2");