当前位置:Linux教程 - Linux - 使用UDP协议的echo核心守护进程

使用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 来自: