send raw packet from kernel module

send raw packet from kernel module

Post by njian » Tue, 06 Apr 2004 17:46:00



I'm writing a kernel module based on kernel 2.4.20. The module constructs
and sends raw IP packets from the kernel. The approach I take is to mimic
the sys_sendto() system call. I fill in the "struct msghdr" structure and
then calls the sock_sendmsg() function. However, the
OS hangs after calling the function. Below I show the source code. Could
anyone point out the problems of the code for me?

int sendRMPacket(struct socket *sock, unsigned int src, unsigned int dst,
char *buffer,
     unsigned int len, int seq)
// buffer contains the payload of the packet, len is the length of the
payload
{
 //struct sk_buff *skb;
 struct iphdr *ip_head;
 struct sockaddr_in target;
 char *packet;
 //int sk;
 struct msghdr msg;
 int err = 5;
 struct iovec iov;
 unsigned flags = 0;
 char dst_addr[128];

 packet = (char *) kmalloc(len + sizeof(struct iphdr), GFP_ATOMIC);
 ip_head = (struct iphdr *) packet;
 ip_head->ihl = 5; /*headerlength with no options*/
 ip_head->version = 4;
 ip_head->tos = 0;
 ip_head->tot_len = htons(sizeof(struct iphdr) + len);
 ip_head->id = htons(seq);
 ip_head->frag_off = 0;
 ip_head->ttl = 255;
 ip_head->protocol = IPPROTO_RAW;
 ip_head->check = 0; /*Fill in later*/
 ip_head->saddr = src;
 ip_head->daddr = dst;
 ip_head->check = in_cksum((unsigned short *)&ip_head, sizeof(struct
iphdr));
 memcpy(packet + sizeof(struct iphdr), buffer, len);
 printk(KERN_ERR "RM Module: packet constructed.\n");

 memset(&target, 0, sizeof(target));
 target.sin_family = AF_INET;
 target.sin_port =  0;
 target.sin_addr.s_addr = dst;
 //dst_addr = (char *) kmalloc (sizeof(target), GFP_ATOMIC);
 //memset(dst_addr, 0, 128);
 memcpy(dst_addr, &target, sizeof(target));
 printk(KERN_ERR "RM Module: sockaddr_in structure filled with size: %d.\n",
sizeof(target));

 iov.iov_base = (void *)packet; //buff;
 iov.iov_len = len + sizeof(struct iphdr);
 msg.msg_name = dst_addr;
 msg.msg_namelen = sizeof(target); //dst_len;
 msg.msg_iov = &iov;
 msg.msg_iovlen = 1;
 msg.msg_control = NULL;
 msg.msg_controllen = 0;

 //if ((sock->file)->f_flags & O_NONBLOCK)
 // flags |= MSG_DONTWAIT;
 msg.msg_flags = flags;
 printk(KERN_ERR "RM Module: about to send packet %s with length %d.\n",
buffer, len + sizeof(struct iphdr));

 if ((err = sock_sendmsg(&sock, &msg, len + sizeof(struct iphdr))) < 0)
  printk(KERN_ERR "RM Module: packet sending failed.\n");

 return err;

Quote:}

Many thanks!!