使用UDP协议的echo核心守护进程
昨天花了半天时间写了一个使用UDP协议的echo核心守护进程,请大家指正
/* Makefile */
all:echod.o
.c.o:
gcc -I/usr/src/linux/include -O2 -c $<
clean:
rm -f *.o
/* echod.c */
#define MODULE
#define __KERNEL__
#include <linux/config.h>
#if CONFIG_MODVERSIONS
#define MODVERSIONS
#include <linux/modversions.h>
#endif
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <asm/processor.h>
#include <linux/tqueue.h>
#include <linux/interrupt.h>
#include <linux/malloc.h>
#include <linux/net.h>
#include <net/sock.h>
#include <asm/uaccess.h>
struct timer_list tm;
DECLARE_WAIT_QUEUE_HEAD(wq);
DECLARE_WAIT_QUEUE_HEAD(wm);
volatile int finish = 0;
int port = 7;
int init_sock(struct socket **s, int port)
{
struct sockaddr_in sin;
int error = 0;
error = sock_create(PF_INET, SOCK_DGRAM, IPPROTO_UDP, s);
if (error < 0) {
printk("Error during creation of socket\n");
goto out;
}
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = htons((unsigned short)port);
error = (*s) -> ops -> bind(*s, (struct sockaddr*)&sin, sizeof(sin));
if (error <0) {
printk("Error bind\n");
goto out;
}
(*s) -> sk -> reuse = 1;
out:
return error;
}
void doecho(struct socket *s)
{
struct msghdr msg;
struct iovec iov;
int len;
char *buf;
struct sockaddr_in sin;
mm_segment_t oldfs;
if (skb_queue_empty(&(s ->sk -> receive_queue)))
return;
buf = (char *)kmalloc(4096, GFP_KERNEL);
msg.msg_name = (void *)&sin;
msg.msg_namelen = sizeof(sin);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_controllen = 0;
msg.msg_flags =0;
msg.msg_iov -> iov_base = buf;
msg.msg_iov -> iov_len = (size_t) 4095;
len = 0;
oldfs = get_fs();
set_fs(get_ds());
len = sock_recvmsg(s, &msg, 4095, MSG_DONTWAIT);
buf[len] = 0;
/* printk("recv: %s : %d\n", buf, len); */
set_fs(oldfs);
if ((len < 0) || (len > 4094))
goto outdo;
oldfs = get_fs();
set_fs(get_ds());
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_iov -> iov_base = buf;
msg.msg_iov -> iov_len = len;
msg.msg_flags = MSG_NOSIGNAL;
len = sock_sendmsg(s, &msg, len);
set_fs(oldfs);
outdo:
kfree(buf);
}
int echod(void *ptr)
{
struct socket *s = NULL;
sprintf(current -> comm, "echod");
daemonize();
if (init_sock(&s, port))
return -1;
printk("echod begin\n");
while (!finish) {
doecho(s);
interruptible_sleep_on_timeout(&wq, 1);
}
sock_release(s);
printk("echod end\n");
wake_up_interruptible(&wm);
return 0;
}
void tm_timeout(unsigned long ptr)
{
printk("wait up it\n");
finish = 1;
}
MODULE_PARM(port, "i");
int init_module()
{
kernel_thread(echod, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
return 0;
}
void cleanup_module()
{
tm_timeout(0);
interruptible_sleep_on(&wm);
}
发布人:tengel 来自: