当启用或禁用网络接口时,我需要一种方法来通知我的用户空间应用程序.我希望在不诉诸民意的情况下这样做.当网络相关事件发生时,内核是否提供某种钩子来触发回调函数?
我正在尝试使用netlink套接字监视路由更改,但是如何获取更新的路由地址?
码:
#include <sys/socket.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#define ERR_RET(x) do { perror(x); return EXIT_FAILURE; } while (0);
void loop (int sock)
{
struct sockaddr_nl nladdr;
struct msghdr msg;
struct iovec iov[2];
struct nlmsghdr nlh;
char buffer[65536];
iov[0].iov_base = (void *)&nlh;
iov[0].iov_len = sizeof(nlh);
iov[1].iov_base = (void *)buffer;
iov[1].iov_len = sizeof(buffer);
msg.msg_name = (void *)&(nladdr);
msg.msg_namelen = sizeof(nladdr);
msg.msg_iov = iov;
msg.msg_iovlen = sizeof(iov)/sizeof(struct iovec);
if ( recvmsg (sock, &msg, 0) )
{
if …Run Code Online (Sandbox Code Playgroud) 我有一个守护进程,我正在努力监听UDP广播数据包,并通过UDP进行响应.当一个包进来,我想知道哪个IP地址(或NIC)的包来到TO这样我就可以与该IP地址作为源地址进行响应.(由于涉及很多痛苦的原因,我们系统的一些用户想要将同一台机器上的两个NIC连接到同一个子网.我们告诉他们不要,但是他们坚持.我不需要提醒我有多难看.)
似乎无法检查数据报并直接找出其目标地址或其所在的接口.基于大量的谷歌搜索,我发现找出数据报目标的唯一方法是每个接口有一个监听套接字,并将套接字绑定到各自的接口.
首先,我的监听套接字以这种方式创建:
s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
Run Code Online (Sandbox Code Playgroud)
要绑定套接字,我尝试的第一件事就是这个,其中nic是char*接口名称:
// Bind to a single interface
rc=setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, nic, strlen(nic));
if (rc != 0) { ... }
Run Code Online (Sandbox Code Playgroud)
这根本没有效果,并且无声地失败.ASCII名称(例如eth0)是否传递给此调用的正确名称类型?为什么会无声地失败?根据man 7 socket,"请注意,这仅适用于某些套接字类型,尤其是AF_INET套接字.数据包套接字不支持(在那里使用普通绑定(8))." 我不确定"数据包套接字"是什么意思,但这是一个AF_INET套接字.
所以接下来我尝试的是这个(基于bind vs SO_BINDTODEVICE套接字):
struct sockaddr_ll sock_address;
memset(&sock_address, 0, sizeof(sock_address));
sock_address.sll_family = PF_PACKET;
sock_address.sll_protocol = htons(ETH_P_ALL);
sock_address.sll_ifindex = if_nametoindex(nic);
rc=bind(s, (struct sockaddr*) &sock_address, sizeof(sock_address));
if (rc < 0) { ... }
Run Code Online (Sandbox Code Playgroud)
这也失败了,但这次是错误的Cannot assign requested address.我也尝试将系列更改为AF_INET,但它失败并出现相同的错误.
仍有一个选项,即将套接字绑定到特定的IP地址.我可以查找接口地址并绑定到那些地址.不幸的是,这是一个糟糕的选择,因为由于DHCP和热插拔以太网电缆,地址可以随时更改. …
我正在尝试检索IP Address程序中的本地计算机.操作系统是Ubuntu 8.10.我尝试使用gethostname()并gethostbyname()检索IP Address.我收到的答案是127.0.1.1.我了解到它似乎是一Debian件事:
这里链接的文件解释了这个想法.
我的/etc/hosts文件内容是:
127.0.0.1 localhost
127.0.1.1 mymachine
在这种情况下,有没有其他方式以编程方式(更喜欢C或C++)获取IP地址而不修改机器上的系统文件?