/*
* $Id: hello.c,v 1.5 2004/10/26 03:32:21 corbet Exp $
*/
#include <linux/init.h>
#include <linux/module.h>
#include <lp.h>
MODULE_LICENSE("Dual BSD/GPL");
int send = 0;
module_param(send, int, S_IRUGO);
net_device_t * NIC = NULL;
int lp_recv(sk_buff_t * skb, net_device_t * dev, packet_type_t * pt, net_device_t * d){
PDEBUG("lp_recv is being invoked\n");
return NET_RX_SUCCESS;
}
packet_type_t lp_ptype = {
.type = __constant_htons(ETH_P_LP),
.func = lp_recv,
.dev = NULL,
.af_packet_priv = NULL,
};
int lp_send_skb(sk_buff_t * skb)
{
ethhdr_t * eth = NULL;
char * dest = kmalloc(ETH_ALEN, GFP_KERNEL);
if(!dest)
{
PDEBUG("alloc dest fail");
}
dest[0] = 0x00;
dest[1] = 0x16;
dest[2] = 0x3e;
dest[3] = 0x53;
dest[4] = 0x12;
dest[5] = 0x51;
skb->data_len = 0;
skb->len = LINK_HDR + 10;
skb->tail = skb->data + LINK_HDR + 10;
skb->mac.raw = skb->nh.raw = skb->h.raw = skb->data;
skb->dev = NIC;
skb->protocol = htons(ETH_P_LP);
eth = (ethhdr_t *)skb->data;
eth->h_proto = htons(ETH_P_LP);
memcpy(eth->h_dest, dest, ETH_ALEN);
memcpy(eth->h_source, NIC->dev_addr, ETH_ALEN);
if(dev_queue_xmit(skb)){
return -1;
}
return 0;
}
static int send_init(void)
{
sk_buff_t * skb;
if(!(NIC = dev_get_by_name("eth0")))
{
PDEBUG("NIC is null\n");
return -ENODEV;
}
dev_add_pack(&lp_ptype);
PDEBUG("lp init\n");
if(send)
{
if(!(skb = alloc_skb(LINK_HDR+10, GFP_KERNEL)))
{
PDEBUG("alloc skb fail\n");
}
if(!lp_send_skb(skb))
{
PDEBUG("send success\n");
}
kfree_skb(skb);
}
return 0;
}
static void send_exit(void)
{
dev_remove_pack(&lp_ptype);
dev_put(NIC);
PDEBUG("lp exit\n");
}
module_init(send_init);
module_exit(send_exit);