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;
Many thanks!!Quote:}