【问题标题】:Linux UDP in kernel space get sockaddr_in内核空间中的 Linux UDP 获取 sockaddr_in
【发布时间】:2016-01-21 10:56:02
【问题描述】:

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

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

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

【问题讨论】:

  • 除非您的 UDP 套接字已连接,否则您无法从 sock 获取 sockaddr_in,因为 sockaddr_in 绑定到数据包,而不是套接字。添加一些有关您对数据包的了解(结构)的详细信息。
  • 感谢您的回复。我想向向我发送消息的主机发送答案。 ((我使用这部分代码:github.com/joninvski/iptables_dev_examples/blob/master/…))

标签: c linux linux-kernel


【解决方案1】:

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

您的数据包基本上包含在sk_buff 中。您可以尝试这样做以获取远程 IP:

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

ip_hdr()linux/ip.h 中。

【讨论】:

  • 完美运行!谢谢
【解决方案2】:

根据 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 是 sock 结构变量。 所以你的 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);

【讨论】:

    【解决方案3】:

    客户端地址是一个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;

    【讨论】:

    • 好的,谢谢,但是我什么时候可以得到 client_addr ?我只有指向 struct sock (回调函数 struct socket->sk->sk_data_ready ) 的指针。有什么函数可以从 sock 中获取 client_addr 吗??
    • 我认为你可以使用 csock = accept(ssock, (struct sockaddr *)&client_addr, &clen)
    • 对不起,我还是不明白....我用这个代码:github.com/joninvski/iptables_dev_examples/blob/master/… 现在我需要在第 48 行更改地址(to.sin_addr.s_addr = in_aton ("127.0.0.1");)
    • pl。检查堆栈溢出中的以下讨论是否有帮助http://stackoverflow.com/questions/3060950/how-to-get-ip-address-from-sock-structure-in-c
    猜你喜欢
    • 2017-06-07
    • 2015-08-06
    • 2012-10-09
    • 1970-01-01
    • 2019-03-24
    • 1970-01-01
    • 1970-01-01
    • 2014-11-16
    • 1970-01-01
    相关资源
    最近更新 更多