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");