Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 使用UDP从和向特定端口发送单个RIPv2数据报?_C_Linux_Sockets_Bind - Fatal编程技术网

C 使用UDP从和向特定端口发送单个RIPv2数据报?

C 使用UDP从和向特定端口发送单个RIPv2数据报?,c,linux,sockets,bind,C,Linux,Sockets,Bind,我的任务是制作一个路由信息协议嗅探器和一个C/C++程序,该程序能够使用从嗅探器收集的信息发送自定义RIP条目 我在学校提供的Ubuntu Virtualbox映像中运行这两个映像,该映像通过“内部网络”选项连接到运行路由守护进程生成RIP流量的BSD映像 我到达了需要将自定义数据包发送到“路由器”的部分,但在尝试从端口520发送数据包时遇到了麻烦 我从描述RIP协议的RFC1058中收集到,为了使路由器确认新路由,RIP消息必须来自和到达端口520 我可以将数据包发送到路由器的端口520,但在

我的任务是制作一个路由信息协议嗅探器和一个C/C++程序,该程序能够使用从嗅探器收集的信息发送自定义RIP条目

我在学校提供的Ubuntu Virtualbox映像中运行这两个映像,该映像通过“内部网络”选项连接到运行路由守护进程生成RIP流量的BSD映像

我到达了需要将自定义数据包发送到“路由器”的部分,但在尝试从端口520发送数据包时遇到了麻烦

我从描述RIP协议的RFC1058中收集到,为了使路由器确认新路由,RIP消息必须来自和到达端口520

我可以将数据包发送到路由器的端口520,但在绑定失败并出现错误消息“无法分配请求的地址”后,源端口始终是系统分配的随机端口

数据包本身在WireShark中看起来很好,但源端口除外,例如60818

我在我的响应计划中做了以下工作:

#define ROUTERADDR "10.0.0.1"

int fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
struct sockaddr_in router;
router.sin_family      = AF_INET;
router.sin_port        = htons(520);
router.sin_addr.s_addr = inet_addr(ROUTERADDR);

bind    (fd, (struct sockaddr*)&router, sizeof(router));
connect (fd, (struct sockaddr*)&router, sizeof(router));

send(fd, &payload, sizeof(payload), 0);
close(fd);

绑定到<1024的端口需要root权限,除非您将可执行文件添加到CAP_NET_BIND_服务功能,如下所示

setcap 'cap_net_bind_service=+ep' /path/to/executable
代码中还有另一个问题,您试图绑定到路由器的地址。您需要绑定到特定的本地地址或INADDR_ANY,如下所示

struct sockaddr_in local, router;
local.sin_family = AF_INET;
local.sin_port = htons(520);
local.sin_addr.s_addr = htonl(INADDR_ANY);
bind    (fd, (struct sockaddr*)&local, sizeof(local));

router.sin_family      = AF_INET;
router.sin_port        = htons(520);
router.sin_addr.s_addr = inet_addr(ROUTERADDR);
connect (fd, (struct sockaddr*)&router, sizeof(router));

您应该检查系统调用的返回值,以便知道什么时候不起作用,例如在您的情况下,
bind()
调用可能会失败

在您的情况下,bind()将失败,因为您试图绑定到要发送给的远程地址上的端口,而这是无法做到的

bind()指定要使用的本地端点,因此您应该指定要从中发送的本地IP地址之一。 或者您可以使用
INADDR\u any
将套接字绑定到任何本地地址。因此,您可能希望在中创建另一个
结构sockaddr\u,并按如下方式执行:

struct sockaddr_in my_addr;
my_addr.sin_family      = AF_INET;
my_addr.sin_port        = htons(520);
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);

if (bind(fd, (struct sockaddr*)&my_addr, sizeof(my_addr)) != 0) {
   perror("bind() failed");
}

我试过这样做:
sudo setcap'cap\u net\u bind\u service=+ep'/home/isa2015/ISA/myripresponse
,效果很好,但行为没有变化。我也在用sudoThank you运行程序本身!它最终在端口520上发送。我不知道我可以绑定到不同的结构上,而不是我正在发送的结构。谢谢,我在我的代码片段中添加了错误打印,以便代码更易于理解。