1

I use UDP in kernel space. When some packet is incoming, I store it on workqueue_struct and then I process it. Everything working. Now I would like send answer to client. So, I need IPv4 address from struct sock.

I found out function kernel_getsockname() but this function not return sockaddr_in which I need to sock_sendmsg().

My question is: How can I get sockaddr_in from struct sock?

m.s.
  • 16,063
  • 7
  • 53
  • 88
pou
  • 63
  • 2
  • 10
  • Unless your UDP socket is connected, you cannot get the `sockaddr_in` from the `sock`, because the `sockaddr_in` is tied to the packet, not the socket. Add some details about what you have (structs) about the packets. – ElderBug Oct 22 '15 at 08:45
  • Thank for reply. I would like send answer to the host which send me message. (( I use this part of code: https://github.com/joninvski/iptables_dev_examples/blob/master/udpFilter/udpRecvCallback.c )) – pou Oct 22 '15 at 13:28

3 Answers3

0

The client address is in is a struct sockaddr_in then you can get the ip address from client_addr.sin_addr.s_addr. It will be a 32 bit unsigned integer.

for eg.

struct sockaddr_in* clientAddr = (struct sockaddr_in*)&client_addr; int ip = clientAddr->sin_addr.s_addr;

shri
  • 856
  • 1
  • 10
  • 26
  • Ok thank, but when I can get client_addr ? I have only pointer to struct sock (callback function struct socket->sk->sk_data_ready ) . Is there some function to get client_addr from sock?? – pou Oct 22 '15 at 08:49
  • i think you can get using csock = accept(ssock, (struct sockaddr *)&client_addr, &clen) – shri Oct 22 '15 at 08:52
  • I'm sorry but I still do not get it.... I use this pease of code: https://github.com/joninvski/iptables_dev_examples/blob/master/udpFilter/udpRecvCallback.c Now i need to change address on line 48 (to.sin_addr.s_addr = in_aton("127.0.0.1"); ) – pou Oct 22 '15 at 09:03
  • pl. check if the below discussion in stack overflow can be of helphttp://stackoverflow.com/questions/3060950/how-to-get-ip-address-from-sock-structure-in-c – shri Oct 22 '15 at 09:06
0

According to linux kernel documentation, (https://www.kernel.org/doc/htmldocs/networking/API-struct-sock.html) struct sock has a member named sk_rcv_saddr which can be equated to struct cnic_sockaddr *saddr

cnic_sockaddr has local and remote sockaddr_in structure members and you can get ip address from it. For exemple, Im not sure, but...

struct cnic_sockaddr saddr = sk.sk_rcv_saddr;

where sk is sock structure variable. so your sockaddr_in is

saddr.remote.v4

and you can parse it like that:

char* parse_sinaddr(const struct in_addr saddr)
{ 
    static char ip_str[16];
    bzero(ip_str, sizeof(ip_str));
    int printed_bytes = 0;

    printed_bytes = snprintf(ip_str, sizeof(ip_str), "%d.%d.%d.%d", 
        (saddr.s_addr&0xFF), 
        ((saddr.s_addr&0xFF00)>>8), 
        ((saddr.s_addr&0xFF0000)>>16), 
        ((saddr.s_addr&0xFF000000)>>24));

    if (printed_bytes > sizeof(ip_str)) return NULL;

    return ip_str;
}


char *ip_str = parse_sinaddr(saddr.remote.v4.sin_addr.in_addr);
Sun Dro
  • 581
  • 4
  • 9
0

You need to get the source IP from the received packet because an UDP socket in itself doesn't contain the remote end point (because UDP is 1-to-many).

Your packet is essentially contained in the sk_buff. You could try do do that to get the remote IP :

struct iphdr *ip_header = ip_hdr(skb);
to.sin_addr.s_addr = ip_header->saddr;

ip_hdr() is in linux/ip.h.

ElderBug
  • 5,926
  • 16
  • 25