如何在C和libpcap中构建TCP伪头和相关数据以进行校验和验证?

发布于 2024-09-25 23:43:44 字数 2516 浏览 10 评论 0原文

我正在尝试使用伪 tcp 标头、tcp 标头和要发送到校验和函数进行验证的 tcp 数据来构建正确的数据结构。我无法弄清楚我的代码中做错了什么。 以下代码是我的函数,它构建数据结构,然后将其发送到另一个函数进行检查。

void print_inner_ip_header(const u_char* pkt_data, struct ip_header* header)
{
   switch(header->protocol)
   {
      case(ICMP):
      {
         print_icmp_header((struct icmp_header*)(pkt_data+ETHERNET_HEADER_SIZE+sizeof(struct ip_header)));
         break;
      }
      case(TCP):
      {
         struct pseudo_tcp_header ps_tcp_header;
         ps_tcp_header.source = header->source;
         ps_tcp_header.protocol = 6;
         ps_tcp_header.dest = header->dest;
         ps_tcp_header.reserved = 0;
         ps_tcp_header.tcp_size = htons(sizeof(struct tcp_header) + header->total_length - (header->length & 0x0F)*4);

         int len = sizeof(struct pseudo_tcp_header) + ps_tcp_header.tcp_size;
         u_short ps_tcp[len];

         memcpy(ps_tcp, &ps_tcp_header, sizeof(struct pseudo_tcp_header));
         memcpy(ps_tcp+sizeof(struct pseudo_tcp_header), (pkt_data+ETHERNET_HEADER_SIZE+sizeof(struct ip_header)), ps_tcp_header.tcp_size);

         print_tcp_header(pkt_data, (struct tcp_header*)(pkt_data+ETHERNET_HEADER_SIZE+sizeof(struct ip_header)), ps_tcp, len);
         break;
      }
      case(UDP):
      {
         print_udp_header((struct udp_header*)(pkt_data+ETHERNET_HEADER_SIZE+sizeof(struct ip_header)));
         break;
      }
      default:
      {
         break;
      }
   }
}


void print_tcp_header(const u_char* pkt_data, const struct tcp_header* header, u_short* ps_tcp, int len)
{
   u_short checksum = header->checksum;
   int check = in_cksum((unsigned short *)ps_tcp, len);
   char* checksum_str = "Correct";

   printf("CHECK VALUE: %d", check);
   if(check)
   {
      checksum_str = "Incorrect";
   }

   printf("\n\tTCP Header");
   printf("\n\t\tSource Port: %d", ntohs(header->source_port));
   printf("\n\t\tDestination Port: %d", ntohs(header->dest_port));
   printf("\n\t\tSequence Number: %u", ntohl(header->seq_num));
   printf("\n\t\tACK Number: %u", ntohl(header->ack_num));
   print_tcp_header_flags(header->flags);
   printf("\n\t\tWindow Size: %d", ntohs(header->win_size));
    printf("\n\t\tChecksum: %s (%#x)\n", checksum_str, ntohs(checksum));
}

任何帮助将不胜感激,因为我花了很多时间试图找出我做错了什么。

谢谢,

编辑:这是我的伪标题

struct pseudo_tcp_header
{
   struct in_addr source, dest;
   u_char reserved;
   u_char protocol;
   u_short tcp_size;
};

I'm trying to build up the proper data structure using a pseudo tcp header, tcp header, and tcp data to be sent to a check sum function to be verified. I cannot figure out what I'm doing wrong in my code.
The following code is my function that builds up the data structure and then sends it to another function to be checked.

void print_inner_ip_header(const u_char* pkt_data, struct ip_header* header)
{
   switch(header->protocol)
   {
      case(ICMP):
      {
         print_icmp_header((struct icmp_header*)(pkt_data+ETHERNET_HEADER_SIZE+sizeof(struct ip_header)));
         break;
      }
      case(TCP):
      {
         struct pseudo_tcp_header ps_tcp_header;
         ps_tcp_header.source = header->source;
         ps_tcp_header.protocol = 6;
         ps_tcp_header.dest = header->dest;
         ps_tcp_header.reserved = 0;
         ps_tcp_header.tcp_size = htons(sizeof(struct tcp_header) + header->total_length - (header->length & 0x0F)*4);

         int len = sizeof(struct pseudo_tcp_header) + ps_tcp_header.tcp_size;
         u_short ps_tcp[len];

         memcpy(ps_tcp, &ps_tcp_header, sizeof(struct pseudo_tcp_header));
         memcpy(ps_tcp+sizeof(struct pseudo_tcp_header), (pkt_data+ETHERNET_HEADER_SIZE+sizeof(struct ip_header)), ps_tcp_header.tcp_size);

         print_tcp_header(pkt_data, (struct tcp_header*)(pkt_data+ETHERNET_HEADER_SIZE+sizeof(struct ip_header)), ps_tcp, len);
         break;
      }
      case(UDP):
      {
         print_udp_header((struct udp_header*)(pkt_data+ETHERNET_HEADER_SIZE+sizeof(struct ip_header)));
         break;
      }
      default:
      {
         break;
      }
   }
}


void print_tcp_header(const u_char* pkt_data, const struct tcp_header* header, u_short* ps_tcp, int len)
{
   u_short checksum = header->checksum;
   int check = in_cksum((unsigned short *)ps_tcp, len);
   char* checksum_str = "Correct";

   printf("CHECK VALUE: %d", check);
   if(check)
   {
      checksum_str = "Incorrect";
   }

   printf("\n\tTCP Header");
   printf("\n\t\tSource Port: %d", ntohs(header->source_port));
   printf("\n\t\tDestination Port: %d", ntohs(header->dest_port));
   printf("\n\t\tSequence Number: %u", ntohl(header->seq_num));
   printf("\n\t\tACK Number: %u", ntohl(header->ack_num));
   print_tcp_header_flags(header->flags);
   printf("\n\t\tWindow Size: %d", ntohs(header->win_size));
    printf("\n\t\tChecksum: %s (%#x)\n", checksum_str, ntohs(checksum));
}

Any help would be appreciated because I've spent numerous hours trying to figure out what I'm doing wrong.

Thanks,

edit: here is my pseudo header

struct pseudo_tcp_header
{
   struct in_addr source, dest;
   u_char reserved;
   u_char protocol;
   u_short tcp_size;
};

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦里泪两行 2024-10-02 23:43:44

我看到的最基本的问题是以下组合:

     u_short ps_tcp[len];

添加

     memcpy(ps_tcp+sizeof(struct pseudo_tcp_header), ...);

ps_tcp 将添加 sizeof(u_short) 单位,而不是字节。

The most fundamental problem I can see is the combination of:

     u_short ps_tcp[len];

with

     memcpy(ps_tcp+sizeof(struct pseudo_tcp_header), ...);

Adding to ps_tcp will add units of sizeof(u_short), not bytes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文