#include #include /* List of sk_buffs waiting to be freed. */ static struct sk_buff_head skb_done_list; struct net_device *search_netdev (char *name) { struct net_device *dev; struct net_device *found = NULL; struct net *net; printk("search device %s\n", name); read_lock(&dev_base_lock); for_each_net(net) { for_each_netdev(net, dev) { printk("there is device %s, base addr: %x\n", dev->name, dev->base_addr); if (!strcmp (name, dev->name)) { found = dev; goto end; } } } end: read_unlock(&dev_base_lock); return found; } int linux_pkg_xmit (char *pkg_data, int len, void *del_data, int (*del_func) (struct sk_buff *, void *), struct net_device *dev) { struct sk_buff *skb; if (len == 0 || len > dev->mtu + dev->hard_header_len) return EINVAL; /* Allocate a sk_buff. */ skb = dev_alloc_skb (len); if (!skb) return ENOMEM; skb->del_data = del_data; skb->pre_del_func = del_func; /* Copy user data. This is only required if it spans multiple pages. */ skb->len = len; skb->tail = skb->data + len; memcpy (skb->data, pkg_data, len); skb->dev = dev; return dev_queue_xmit(skb); } char *netdev_addr(struct net_device *dev) { return dev->dev_addr; } int netdev_flags(struct net_device *dev) { return dev->flags; } char *netdev_name (struct net_device *dev) { return dev->name; } unsigned int netdev_mtu (struct net_device *dev) { return dev->mtu; } unsigned short netdev_header_len (struct net_device *dev) { return dev->hard_header_len; } unsigned short netdev_type (struct net_device *dev) { return dev->type; } unsigned char netdev_addr_len (struct net_device *dev) { return dev->addr_len; } void *skb_reply(struct sk_buff *skb) { return skb->del_data; } void skb_done_head_init() { skb_queue_head_init (&skb_done_list); } struct sk_buff *skb_done_dequeue() { return skb_dequeue (&skb_done_list); } void skb_done_queue(struct sk_buff *skb) { skb_queue_tail (&skb_done_list, skb); }