C套接字编程: Set ip header's id to 0?

标签 c linux sockets networking raw-sockets

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

我需要将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 header 、UDP header 和有效负载并将其发送出去。

但是,网络堆栈一直在更改 IP header 中的我的 ID。我需要包含 IP header ,但我还需要禁用分段和/或将 IP id 设置为 0。我该如何实现?

编辑:我在 Linux 上

最佳答案

在 Linux 上,您可以使用 AF_PACKETSOCK_DGRAM 套接字,而不是 AF_INETSOCK_RAW 并填充一个 sockaddr_ll

类似的东西:

socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_IP))

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

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

查看更多关于 packet(7)rtnetlink(7) 的信息。如果您的项目是开源的,您可以使用 my old project做其中一些事情(有关更多信息,请与我联系)。

关于C套接字编程: Set ip header's id to 0?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39476808/

相关文章:

停止使用某些 C 系统调用的编译器方法

c - GTK+动态数组

c - 编译程序时如何将两个选项传递给 GCC?

java - 我可以在单线程中使用两个套接字吗?

python - 你可以使用 python 套接字进行 docker 容器通信吗?

c - C 中的 tolower 函数不允许我转换字符串

c - 链表: Adding and removing issues

linux - 在 Bash 中,如何显示脚本输出然后恢复到之前的输出(如 less、top 或 watch)

python - 创建触发器 sys_exec 和 python

python-3.x - 如何使用套接字连接到 FTP 服务器?