【问题标题】:C socket programming: Set ip header's id to 0?C 套接字编程:将 ip header 的 id 设置为 0?
【发布时间】:2017-01-21 10:55:29
【问题描述】:

我想发送原始 IP 数据包,它工作得很好,除了 IP 标头中的一个字段。

我需要将IP id设置为0。我尝试了以下方式:

    struct iphdr ip;

ip.version = 4;                               // Ipv4
ip.frag_off = 0;                              // IP Fragmentation
ip.tos     = 0;                               // Type of Service - We don't need this
ip.ttl = 64;                                  // Maxmimum value
ip.protocol = IPPROTO_UDP;                    // DHCP uses UDP
ip.check = 0;                                 // The checksum needs to be 0 before being calculated

// We don't yet have an IP Address
if((ip.saddr = inet_addr("0.0.0.0")) == -1) {
    perror("Failed to convert IP address");
    exit(1);
}

ip.daddr = inet_addr("255.255.255.255");      // we have to do a broadcast
ip.id = 0;                                    //  
ip.ihl = 5;                                   // Header length - 5 means no additional options are being sent in the IP header
ip.tot_len = sizeof(struct packet);           // The total length of the Packet

然后我创建一个带有 IP_HDRINCL 选项集的 RAW_SOCKET:

      if ((sockd = socket(AF_INET, SOCK_RAW, IPPROTO_UDP)) == -1) {
      perror("Failed to create socket");
      exit(1);
  }
int hdrincl = 1;
if (setsockopt(sockd, IPPROTO_IP, IP_HDRINCL, &hdrincl, sizeof(hdrincl)) == -1) {
    perror("Failed to set IP_HDRINCL");
    exit(1);
}

然后我创建一个缓冲区,其中包含我的 IP 标头、UDP 标头和有效负载并将其发送出去。

但是,网络堆栈不断更改 IP 标头中的我的 ID。我需要包含 IP 标头,但我还需要禁用分片和/或将 IP id 设置为 0。我该如何实现?

编辑:我在 Linux 上

【问题讨论】:

  • 您使用的是 linux 还是 windows?如果您在 Windows 上,则套接字不是这样做的方法;尝试使用 libpcap。
  • 如果您查看手册页man 7 raw,您会看到当id0 时,它会自动填写,这解释了为什么您不能使用id 0,但是我没有实际使用 id 0 的解决方案。

标签: c linux sockets networking raw-sockets


【解决方案1】:

在 linux 上,您可以使用 AF_PACKETSOCK_DGRAM 套接字而不是 AF_INETSOCK_RAW 并填写 sockaddr_ll

类似的东西:

socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_IP))

但是,为了让您的程序也可以在 Windows 上工作,您应该使用 libpcap

请记住,您应该自己解析目标的物理地址(在 linux 上,您可以尝试使用rtnetlink 接口)。

packet(7)rtnetlink(7) 上查看更多信息。如果你的项目是开源的,你可以使用my old project 来做这些事情(如需更多信息,请联系我)。

【讨论】:

    猜你喜欢
    • 2014-07-15
    • 1970-01-01
    • 2011-03-04
    • 1970-01-01
    • 1970-01-01
    • 2013-12-08
    • 2012-10-07
    • 2013-05-27
    • 1970-01-01
    相关资源
    最近更新 更多