内核空间中的Linux UDP获取sockaddr_in

时间:2015-10-22 08:18:02

标签: c linux linux-kernel

我在内核空间中使用UDP。当某个数据包进入时,我将其存储在workqueue_struct上然后我处理它。 一切正常。现在我想给客户发送答案。所以,我需要来自struct sock的IPv4地址。

我找到了函数kernel_getsockname()但是这个函数没有返回sockaddr_in我需要的sock_sendmsg()

我的问题是:如何从sockaddr_in获取struct sock

3 个答案:

答案 0 :(得分:0)

客户端地址是struct sockaddr_in然后你可以从client_addr.sin_addr.s_addr获取ip地址。它将是一个32位无符号整数。

例如。

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

答案 1 :(得分:0)

根据linux内核文档,(https://www.kernel.org/doc/htmldocs/networking/API-struct-sock.html)struct sock有一个名为sk_rcv_saddr的成员,可以等同于struct cnic_sockaddr *saddr

cnic_sockaddr具有本地和远程sockaddr_in结构成员,您可以从中获取IP地址。例如,我不确定,但是......

struct cnic_sockaddr saddr = sk.sk_rcv_saddr;

其中sk是袜子结构变量。 所以你的sockaddr_in是

saddr.remote.v4

你可以这样解析它:

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);

答案 2 :(得分:0)

您需要从收到的数据包中获取源IP,因为UDP套接字本身并不包含远程端点(因为UDP是1对多)。

您的数据包基本上包含在Expression parsing failed; nested exception is org.springframework.expression.spel.SpelParseException: EL1043E:(pos 9): Unexpected token. Expected 'rparen())' but was 'identifier' 中。您可以尝试这样做以获取远程IP:

sk_buff

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