djkah11
djkah11

Reputation: 456

Send data from linux kernel module

I want to send some data via tcp from my linux kernel module. I have tried to use some code from http://www.avrfreaks.net/sites/default/files/tcp-server-send-recv.c , but there are too old code(it used old linux kernel api). Also, I have tried to understand https://github.com/abysamross/simple-linux-kernel-tcp-client-server/blob/master/network_server.c , but it is too sophisticated for me:)

I want only send some small data to specified ip adress via tcp. How I can do it?

Upvotes: 1

Views: 4847

Answers (2)

Daniel
Daniel

Reputation: 411

The waiting code not work, It only wakeup for timeout.

DECLARE_WAIT_QUEUE_HEAD(recv_wait);
/* wait for a response or for a timetout */
wait_event_timeout(recv_wait,\
            !skb_queue_empty(&conn_socket->sk->sk_receive_queue),\
                                                            5*HZ);

Upvotes: 0

Jaime
Jaime

Reputation: 6131

Check the client example in the same project. If you can reuse some functions, you must understand and modify the tcp_client_connect function (lines 124-198) only. In that module, the tcp_client_connect connection creates a connection when the module is loaded, and the network_client_exit closes the connection when the module is unloaded.

In the tcp_client_connect function:

  1. (line 144) It creates a socket

     struct socket *conn_socket = NULL;
    
     ret = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &conn_socket);
    
  2. Then, (lines 153 to 155 ) it creates a destination address

     struct sockaddr_in saddr;                               /* a socket address */
    
     saddr.sin_family = AF_INET;                             /* for internet */
     saddr.sin_port = htons(PORT);                           /* using the port PORT */
     saddr.sin_addr.s_addr = htonl(create_address(destip));  /* and address destip */
    
  3. (line 157) It uses that address to open the socket (to create the connection)

     int ret = -1;
    
     ret = conn_socket->ops->connect(conn_socket, (struct sockaddr *)&saddr\
                    , sizeof(saddr), O_RDWR);     
    
     /* if it gets a response and it is not "in progress" */
     if(ret && (ret != -EINPROGRESS))
     {
         /* error creating the socket*/
     }
    
  4. (lines 166 to 168) It sends a message using the socket.

    int len = 49;
    char reply[len+1];
    
    memset(&reply, 0, len+1);   /* sets 0s into all the string space */
    strcat(reply, "HOLA");      /* sets the message */
    
    tcp_client_send(conn_socket, reply, strlen(reply), MSG_DONTWAIT);
    
  5. (line 170) It waits for a message (for while)

    DECLARE_WAIT_QUEUE_HEAD(recv_wait);
    
    /* wait for a response or for a timetout */
    wait_event_timeout(recv_wait,\
                    !skb_queue_empty(&conn_socket->sk->sk_receive_queue),\
                                                                    5*HZ);
    
  6. (lines 180 to 190) It obtains the response.

    int len = 49;
    char response[len+1];
    
    /* if something has arrived */
    if(!skb_queue_empty(&conn_socket->sk->sk_receive_queue))
    {
        memset(&response, 0, len+1);
        tcp_client_receive(conn_socket, response, MSG_DONTWAIT);
    }
    

In the network_client_exit function,

  1. (lines 239 to 240) it closes the connection.

    /* if the socket has been created */
    if(conn_socket != NULL)
    {
            /* relase the socket */
            sock_release(conn_socket);
    }
    

Upvotes: 5

Related Questions