- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我正在尝试使用 C 通过 sendmsg 发送原始以太网数据包。此代码成功打开原始数据包套接字,尝试用单个字节数组 (char message[]) 填充 struct iovec,然后用目标地址、地址长度和指向包含以下内容的 struct iovec 的指针填充 struct msghdr消息。 sendmsg() 为每次调用返回 EINVAL,但我不知道哪些参数无效。 (我删除了一些 perror() 调用以使这段代码更易于阅读;输出是“无效参数”。)
我还没有找到任何关于 sendmsg() 如何与原始套接字一起工作的示例,但是使用 sendto() 的类似代码可以按预期工作。在该代码中,我显式地形成了以太网帧,包括 header 和协议(protocol)信息,但据我了解,调用 sendmsg() 不是必需的吗?我还尝试让 message.iov_base 指向一个包含显式形成的以太网帧(包括 14 字节 header )的缓冲区,但 sendmsg() 对此也犹豫不决。
sendmsg() 和 sendmmsg() 可以处理原始以太网帧吗?关于使 iovec 无效的信息,我是否遗漏了什么?
30 int main(void) {
32 unsigned char dest[ETH_ALEN] = {0x11, 0x11, 0x11, 0x11, 0x11, 0x11}; // destination MAC address
33
34 // Socket variables
35 int s;
36 unsigned short protocol = htons(ETH_P_802_EX1);
38
39 // Message variables
40 char message[] = {"Test message. Test message. Test message!\n"};
41 size_t msg_len = strlen(message) + 1; // Message length includes null terminator
42 int e; // Error code
43 struct msghdr msg;
44 struct iovec msgvec;
45
46 // Setup source-side socket
47 s = socket(AF_PACKET, SOCK_RAW, protocol);
48 if (s < 0) { printf("%d: %s\n", errno, strerror(errno)); return EXIT_FAILURE; }
49
50 msgvec.iov_base = message;
51 msgvec.iov_len = msg_len;
52 memset(&msg, 0, sizeof(msg));
53 msg.msg_name = dest;
54 msg.msg_namelen = ETH_ALEN;
55 msg.msg_control = NULL;
56 msg.msg_controllen = 0;
57 msg.msg_flags = 0;
65 msg.msg_iov = &msgvec;
66 msg.msg_iovlen = 1;
67
68 for (int i=0; i<10; i++) {
69 e = sendmsg(s, &msg, 0);
73 }
79 close(s);
80 return EXIT_SUCCESS;
81 }
最佳答案
经过一些调整后,我使这段代码可以正常工作。
我没有像 sendmsg()
的手册页所暗示的那样将地址作为字节串发送,而是使用了 struct sockaddr_ll
。我还将 iovec
指向一个包含完整以太网帧(包括 header )的缓冲区。为什么手册页在 sendto
原型(prototype)中明确指定了 const struct sockaddr*
而在 msghdr
中指定了 void*
我仍然不知道定义。
我在调用 socket()
之后添加了这段代码:
39 struct sockaddr_ll address;
40 struct ifreq buffer; // To get information with ioctl()
41 char ifname[] = {"eth0"};
42 int ifindex; // Interface index, from ioctl() call
57 memset(&buffer, 0, sizeof(buffer)); // Getting interface index value
58 strncpy(buffer.ifr_name, ifname, IFNAMSIZ);
59 ioctl(s, SIOCGIFINDEX, &buffer);
60 ifindex = buffer.ifr_ifindex;
61
62 // Setup sockaddr_ll address
63 memset( (void*) &address, 0, sizeof(address) );
64 address.sll_family = PF_PACKET;
65 address.sll_ifindex = ifindex;
66 address.sll_halen = ETH_ALEN;
67 memcpy( (void*) (address.sll_addr), (void*) dest, ETH_ALEN );
并为 msghdr 结构赋值替换了这些代码行:
81 msg.msg_name = &address;
82 msg.msg_namelen = sizeof(address);
关于c - 将 sendmsg/sendmmsg 与原始以太网帧一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37976001/
在我们的服务出现一些预期的增长之后,突然间一些更新花费了非常长的时间,这些过去非常快,直到表达到大约 2MM 记录,现在它们每个需要大约 40-60 秒。 update table1 set fiel
我在服务中实现了一个传感器事件监听器,只要采样周期和最大报告延迟低于 1 秒,该监听器就可以正常工作,但一旦我将采样周期增加到超过 1 秒,传感器就根本不会更新。 我希望采样周期为 10 秒(可能是
我使用 Tkinter GUI 来启动测量和分析过程,基本上只需单击一个按钮即可开始。由于这些测量可能需要一段时间,我尝试添加一个进度条,即这个: http://tkinter.unpythonic.
我正在尝试使用套接字发送数据包,但出现错误。 invalid conversion from ‘omnetpp::cPacket*’ to ‘inet::Packet*’ [-fpermissive]
我刚刚发现 String#split 有以下奇怪的行为: "a\tb c\nd".split => ["a", "b", "c", "d"] "a\tb c\nd".split(' ') => ["a
您好,我正在尝试 ClojureScript,我正在使用 Klipse作为我的 REPL 差不多。这可能不是它的预期用途,但因为我没有做任何太复杂的事情,所以现在没问题。 我遇到的一个问题是尝试设置计
根据下面的数据,ClockKit 会生成一次 future 的 CLKComplicationTimelineEntry 项,但对于过去的时间点,会进行 24 次调用!这是为什么? 更多详情: 我注意
我有一个 MySQL 表,这个表有一个名为 datetime_utc 的 DATETIME 列。如您所料,它是 UTC 日期和时间。在我的 Bookshelf 模型中,我定义了一个虚拟 getter,
大家好,我是二哥呀! 昨天,一位球友问我能不能给他解释一下 @SpringBootApplication 注解是什么意思,还有 Spring Boot 的运行原理,于是我就带着他扒拉了一下这个注解的源
我是一名优秀的程序员,十分优秀!