Unable to send messages via socket (tcp/ip) from kernel- to userspace

From: fortune@gmx.de
Date: Wed Jun 21 2000 - 04:45:45 EST


Hello,

i'm using kernel version 2.2.14 and try to make a
tcp/ip socket for sending messages between a
server (located in userspace) and the client
(located in kernelspace).

There is no problem by sending from user to kernel,
but if I try to send a message back (kernel -> user),
nothing happens (0 bytes are send and nothing comes
to the userspace).

So I made some tiny codeletts for you, hoping you'll
see where the problem is.

1. start 'testserver'
2. insmod testsocket.o [output goes to /var/og/messages]

====================================================

/* testserver.c */

#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <fcntl.h>

static void err(char *msg)
{
        printf("Server ERROR(%d): %s\n", errno, msg);
        exit(1);
}

int main(int argc, char **argv)
{
        struct sockaddr_in sock, client;
        int i, s, cs, sock_len, client_len;
        char cmd[] = "this is a test";
        struct msghdr msg;
        struct iovec iov;

        printf("starting service\n");

        sock.sin_family = AF_INET;
        sock.sin_port = 3333;
        sock.sin_addr.s_addr = 0x0100007f;

        if ((s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
                err("server: socket");

        printf("Server: create socket.\n");
        sock_len = sizeof(sock);

        if (bind(s, &sock, sock_len) < 0)
                err("server: bind");

        printf("Server: bind socket.\n");

        if (listen(s, 5) < 0)
                err("server: listen");

        printf("Server: listen socket.\n");

        if ((cs = accept(s, &client, &client_len)) < 0)
                err("server: accept");

        printf("Server: accept socket.\n");
/* fcntl(cs, O_NONBLOCK); */

        msg.msg_name = NULL;
        msg.msg_namelen = 0;
        msg.msg_iov = &iov;
        msg.msg_iovlen = 1;
        msg.msg_control = NULL;
        msg.msg_controllen = 0;
        msg.msg_flags = 0;
        iov.iov_base = cmd;
        iov.iov_len = sizeof(cmd);

        if ((i = sendmsg(cs, &msg, MSG_DONTWAIT)) < 0)
                err("server: sendmsg");

        printf("Server: sendmsg(%i): '%s'.\n", i, cmd);

        if ((i = recvmsg(cs, &msg, MSG_DONTWAIT)) < 0)
                err("server: recvmsg");

        printf("Server: recvmsg(%i): '%s'.\n", i, (char *) iov.iov_base);

        return 0;
}

================================================================

/* testsocket.c */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/net.h>
#include <linux/socket.h>
#include <linux/un.h>
#include <linux/in.h>
#include <linux/malloc.h>
#include <asm/uaccess.h>

int init_module(void)
{
        printk("testsocket: init_module()\n");

        {
                struct sockaddr_in addr;
                struct socket *sock;
                struct msghdr msg;
                struct iovec iov;
                char kdata[] = ".............";
                char sdata[] = "ein neuer test";
                mm_segment_t oldfs;
                int error;
  
                error = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock);
                if (error < 0)
                        printk("testsocket: Error during creation of socket; terminating\n");

                addr.sin_family = AF_INET;
                addr.sin_addr.s_addr = 0x0100007f;
                addr.sin_port = 3333;

                error = sock->ops->connect(sock, (struct sockaddr *) &addr,
sizeof(addr), O_RDWR);
                if (error < 0)
                        printk("testsocket: Error during connect; terminating\n");

                msg.msg_name = NULL;
                msg.msg_namelen = 0;
                msg.msg_iov = &iov;
                msg.msg_iovlen = 1;
                msg.msg_control = NULL;
                msg.msg_controllen = 0;
                msg.msg_flags = 0;
                iov.iov_base = kdata;
                iov.iov_len = sizeof(kdata);

                oldfs = get_fs(); set_fs(get_ds());
                error = sock_recvmsg(sock, &msg, sizeof(msg), MSG_DONTWAIT);
                if(error < 0)
                        printk("testsocket: Error during sock_recvmsg; terminating\n");

                printk("testsocket: kdata: '%s'\n", kdata);

                iov.iov_base = sdata;
                iov.iov_len = sizeof(sdata);

                error = sock_sendmsg(sock, &msg, sizeof(msg));
                if(error < 0)
                        printk("testsocket: Error during sock_sendmsg; terminating\n");

                printk("testsocket: sendmsg(%d): '%s'\n", error, (char *) iov.iov_base);

        }

        return 0;
}

void cleanup_module(void)
{
        printk("testsocket: cleanup_module()\n");
}

===============================================================

# Makefile

CC=gcc
CFLAGS := -Wall -DLINUX
MODCFLAGS := $(CFLAGS) -DMODULE -D__KERNEL__

all: testsocket.o testserver

testsocket.o: testsocket.c /usr/include/linux/version.h
                $(CC) $(MODCFLAGS) -I/usr/src/linux/include -c testsocket.c

testserver: testserver.c
                $(CC) $(CFLAGS) -o testserver testserver.c

===================================================================

thanx a lot,

Sebastian Frankfurt

PS: Please do a CC on my e-mail: mailto: fortune@gmx.de

-- 
Sent through GMX FreeMail - http://www.gmx.net

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Fri Jun 23 2000 - 21:00:21 EST