在C程序一个UDP数据有效载荷寻找八位 [英] Finding Octet in a UDP data payload in C program

查看:322
本文介绍了在C程序一个UDP数据有效载荷寻找八位的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想通过端口值为6343。【在code我现在用的就是捕捉数据包使用C程序来收集UDP数据有效载荷信息如下:

 #包括LT&;&stdio.h中GT; //对于标准的东西
#包括LT&;&stdlib.h中GT; //的malloc
#包括LT&;&string.h中GT; // memset的
#包括LT&; netinet / ip_icmp.h> //提供的声明ICMP头
#包括LT&; netinet / udp.h> //提供对UDP报头的声明
#包括LT&; netinet / tcp.h中> //提供的声明TCP报头
#包括LT&; netinet / ip.h> //提供的声明IP报头
#包括LT&; SYS / socket.h中>
#包括LT&; ARPA / inet.h>
#包括LT&;净/ ethernet.h>
#包括LT&; netinet / if_ether.h>
#定义端口6343 //定义端口连接
ETH_P_IP的#define值为0x0800无效ProcessPacket(无符号字符*,INT);
无效print_ethernet_header(无符号字符*,INT);
无效print_ip_header(无符号字符*,INT);
无效print_udp_packet(无符号字符*,INT);
无效Dataint(无符号字符*,INT);
无效打印(const int的* const int的);
INT sockt;
INT I,J;
结构SOCKADDR_IN来源,DEST;常量MAX_HEADER_SIZE = 256; / *最大采样头的大小。 * /结构sampled_header {
header_protocol协议; / *采样头的格式* /
无符号整型帧_; / *原始数据包的长度之前
                                  采样* /
不透明的头{} MAX_HEADER_SIZE; / *头字节* /
}/ *数据包的IP版本4数据* /结构sampled_ipv4 {
unsigned int类型的长度; / *该IP包的长度不包括
                           下层封装* /
unsigned int类型的协议; / * IP协议类型
                           (例如,TCP = 6,UDP = 17)* /
ip_v4 src_ip; / *源IP地址* /
ip_v4 dst_ip; / *目标IP地址* /
无符号整型src_port; / * TCP / UDP源端口号或
                           相当于* /
无符号整型dst_port; / * TCP / UDP目的端口号或
                           相当于* /
无符号整型tcp_flags; / * TCP标志* /
unsigned int类型TOS; / * IP服务类型* /
}
/ *分组IP版本6的数据* /结构sampled_ipv6 {
unsigned int类型的长度; / *该IP包的长度不包括
                           下层封装* /
unsigned int类型的协议; / * IP下一个头
                           (例如,TCP = 6,UDP = 17)* /
ip_v6 src_ip; / *源IP地址* /
ip_v6 dst_ip; / *目标IP地址* /
无符号整型src_port; / * TCP / UDP源端口号或
                           相当于* /
无符号整型dst_port; / * TCP / UDP目的端口号或
                           相当于* /
无符号整型tcp_flags; / * TCP标志* /
无符号整型优先; / * IP优先级* /
}结构extended_switch {
无符号整型src_vlan; / *传入帧*的802.1Q VLAN ID /
无符号整型src_priority; / *传入的802.1p优先级
                             帧* /
无符号整型dst_vlan; / *传出帧*的802.1Q VLAN ID /
无符号整型dst_priority; / *传出的802.1p优先级
                             帧* /
} 诠释的main()
 {INT saddr_size,DATA_SIZE,数据大小;
结构SOCKADDR_IN SADDR;
结构SOCKADDR_IN DADDR;
struct in_addr,这个地址;
INT协议= 17;
无符号字符*缓冲=(无符号字符*)malloc的(65535); //它的大! malloc分配的内存大小字节的块,指针返回块的开头//创建一个套接字sockt =插座(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
如果(sockt℃,)
{
    的printf(套接字错误。\\ n);
    返回1;
}
memset的((字符*)及DADDR,0,sizeof的(DADDR));// prepare的SOCKADDR_IN结构
saddr.sin_family = AF_INET;
daddr.sin_family = AF_INET;
daddr.sin_addr.s_addr = htonl(INADDR_ANY);
daddr.sin_port = htons(PORT);
saddr.sin_port = htons(PORT);
//绑定插座如果(绑定(sockt,(结构sockaddr *)及DADDR,sizeof的(DADDR))小于0)
{
  的printf(绑定失败);
  返回1;
}
的printf(绑定完成);而(1)
{
saddr_size = sizeof的SADDR;
的printf(等待数据... \\ n);//接收数据包数据大小= recvfrom的(sockt,缓冲,65535,0,(结构sockaddr *)及SADDR(socklen_t的*)及saddr_size);
DATA_SIZE = recvfrom的(sockt,缓冲器,65535,0,NULL,NULL);
如果(DATA_SIZE℃,)
{
  的printf(数据包没有收到\\ n);
  返回1;
}
的printf(,还有ntohs(daddr.sin_port)从数据包%d个\\ n到达);
的printf(数据包收到:%lu个字节\\ n,数据大小);ProcessPacket(缓冲,DATA_SIZE);}
关闭(sockt);
的printf(成品);
返回0;
}
无效ProcessPacket(无符号字符*缓冲区,INT LEN)
{
  print_udp_packet(缓冲,LEN);}无效print_ethernet_header(无符号字符*缓冲区,INT LEN)
{
  结构ethhdr * ETH =(结构ethhdr *)缓冲区;
  的printf(以太网头\\ n);
  的printf(--------------------------------------- \\ n);
  的printf(以太网报头长度:%u字节\\ n的sizeof(ETH));
  输出(目的MAC:。。%.2X - %2X - %2X - %2X - %2X - %2X \\ N,乙 - > h_dest [0],乙 - > h_dest [1] ,乙 - > h_dest [2],乙 - > h_dest [3],乙 - > h_dest [4],乙 - > h_dest [5]);
  输出(源MAC:。。%.2X - %2X - %2X - %2X - %2X - %2X \\ N,乙 - > h_source [0],乙 - > h_source [1] ,乙 - > h_source [2],乙 - > h_source [3],乙 - > h_source [4],乙 - > h_source [5]);
  的printf(以太网类型:%U \\ N,乙 - > h_proto);
  的printf(--------------------------------------- \\ n);
  }  无效print_ip_header(无符号字符*缓冲区,INT LEN)
  {
  // print_ethernet_header(缓冲,LEN);  结构iphdr * IPH =(结构iphdr *)(缓冲+的sizeof(结构ethhdr));
  无符号短iphdrlen = iph->国际人道法* 4;  memset的(安培;源,0,sizeof的(源));
  source.sin_addr.s_addr = IPH - > SADDR;
  memset的(安培; DEST,0,sizeof的(目标));
  dest.sin_addr.s_addr = iph-> DADDR;  的printf(IP报头\\ n);
  的printf(--------------------------------------- \\ n);
  的printf(IP长度:%d个\\ N,还有ntohs(iph-> tot_len));
  的printf(源IP:%S \\ n,INET_NTOA(source.sin_addr));
  输出(目标IP:%S \\ n,INET_NTOA(dest.sin_addr));
  的printf(协议:%d个\\ N,iph->协议);
  的printf(服务类型:%d个\\ N,htons(iph-> TOS));
  的printf(--------------------------------------- \\ n);
  }
  无效print_udp_packet(无符号字符*缓冲区,INT LEN)
  {
  结构SOCKADDR_IN SADDR;
  结构SOCKADDR_IN DADDR;
  无符号短iphdrlen;
  无符号字符*载荷=(无符号字符*)malloc的(1024);
  结构iphdr * IPH =(结构iphdr *)(缓冲+的sizeof(结构ethhdr));
  iphdrlen = iph->国际人道法* 4;   结构udphdr * UDPH =(结构udphdr *)(缓冲+的sizeof(结构iphdr)+的sizeof(结构ethhdr));   INT header_size = sizeof的(结构ethhdr)+ iphdrlen + sizeof的UDPH;   print_ip_header(缓冲,LEN);   的printf(UDP包头\\ n);
   的printf(--------------------------------------- \\ n);
   的printf(UDP长度:%d个\\ N,还有ntohs(udph-> LEN));
   //输出(UDP长度:%d个\\ N,还有ntohs(的sizeof(结构udphdr)));
   的printf(源端口数:%d \\ n,还有ntohs(udph->源));
   的printf(目的端口数:%d \\ n,还有ntohs(udph-> DEST));
   的printf(源端口数:%d \\ n,还有ntohs(saddr.sin_port));
   的printf(目的端口数:%d \\ n,还有ntohs(daddr.sin_port));
   的printf(--------------------------------------- \\ n);   的printf(数据有效载荷\\ n);
   // PrintData(缓冲区+ header_size,LEN - header_size);
   Dataint(缓冲,LEN);
   的printf(-------------------------------------------- \\ n );
   }  无效Dataint(无符号字符*缓冲区,INT LEN)
  {  INT I,J;
  I = 0;
  对于(i = 0; I< = LEN;我++)
  {
    如果(i = 0&安培;!&安培; I%16 == 0)//输出与空间的每个六角线
    {
        的printf();
    }     //打印在整整个数据
      如果(I%16 == 0)
        的printf(); //打印进制线的第一元件
        的printf(%D(无符号整数)缓冲器[I]);    //打印最后空间
    如果(我== LEN-1)
    {
        为(J = 0; J< 16-I%16; J ++)
        的printf();    }
   }
  }

我有负载转换成整数形式,如下所示:

  0 0 0 5 0 0 0 1 147 188 192 6 0 0 0 0 0 50 170 143 37 107 3 154 0 0 0 6 0 0 0 1 0 0 0 208 1 30 136 36 0 0 0 29 0 0 1 0 236 205 212 188 0 22 44 215 0 0 0 29 0 0 0 40 0​​ 0 0 2 0 0 0 1 0 0 0 144 0 0 0 1 0 0 5 238 0 0 0 4 0 0 0 128 240 146 28 72 194 0 0 14 12 48 199 199 8 0 69 0 5 220 65 28 64 0 47 6 24 125 193 104 215 69 147 188 192 24 0 80 142 152 237 55 211 205 114 104 162 142 128 16 0 54 188 178 0 0 1 1 8 10 139 71 198 30 37 2 188 177 205 144 135 164 154 194 155 33 30 238 48 113 112 179 62 180 223 221 169 24 234 48 163 41 188 139 148 98 130 255 16 229 123 58 202 165 56 101 14 217 132 108 10 156 47 29 77 156 220 141 202 248 196 75 240 252 232 27 19 140 52 187 0 0 3 233 0 0 0 16 0 0 0 3 0 0 0 2 0 0 0 2 255 255 255 255 0 0 0 1 0 0 0 208 1 30 136 37 0 0 0 29 0 0 1 0 236 205 214 47 0 22 44 215 0 0 0 29 0 0 0 40 0​​ 0 0 2 0 0 0 1 0 0 0 144 0 0 0 1 0 0 5 238 0 0 0 4 0 0 0 128 240 146 28 72 194 0 0 14 12 48 199 199 8 0 69 0 5 220 65 243 64 0 47 6 23 166 193 104 215 69 147 188 192 24 0 80 142 152 237 60 147 229 114 104 162 142 128 16 0 54 13 151 0 0 1 1 8 10 139 71 198 66 37 2 188 213 16 243 209 241 120 208 124 252 85 108 101 62 10 255 21 98 62 58 136 127 106 62 238 76 85 231 227 224 70 62 31 217 151 211 47 106 246 111 160 87 164 114 43 83 45 230 197 131 18 49 110 159 251 162 207 148 178 31 212 40 81 190 0 0 3 233 0 0 0 16 0 0 0 3 0 0 0 2 0 0 0 2 255 255 255 255 0 0 0 1 0 0 0 148 1 30 136 38 0 0 0 29 0 0 1 0 236 205 214 158 0 22 44 215 0 0 0 0 0 0 0 29 0 0 0 2 0 0 0 1 0 0 0 84 0 0 0 1 0 0 0 70 0 0 0 4 0 0 0 68 0 14 12 48 199 199 240 146 28 72 194 0 8 0 69 0 0 52 28 175 64 0 63 6 50 146 147 188 192 24 193 104 215 69 142 152 0 80 114 104 162 142 237 62 109 231 128 16 36 63 51 129 0 0 1 1 8 10 37 2 188 231 139 71 198 66 0 0 0 0 3 233 0 0 0 16 255 255 255 255 0 0 0 0 0 0 0 3 255 255 255 255 0 0 0 1 0 0 0 208 1 30 136 39 0 0 0 29 0 0 1 0 236 205 215 173 0 22 44 215 0 0 0 29 0 0 0 40 0​​ 0 0 2 0 0 0 1 0 0 0 144 0 0 0 1 0 0 5 238 0 0 0 4 0 0 0 128 240 146 28 72 194 0 0 14 12 48 199 199 8 0 69 0 5 220 67 10 64 0 47 6 22 143 193 104 215 69 147 188 192 24 0 80 142 152 237 66 188 223 114 104 162 142 128 16 0 54 185 33 0 0 1 1 8 10 139 71 198 102 37 2 188 248 226 4 177 86 140 52 15 181 49 144 230 162 19 81 72 179 190 46 196 123 24 85 38 153 175 213 96 59 3 73 194 138 211 35 187 143 148 46 200 190 255 249 6 223 220 57 180 2 123 223 184 204 149 28 127 218 240 134 94 247 236 103 0 0 3 233 0 0 0 16 0 0 0 3 0 0 0 2 0 0 0 2 255 255 255 255 0 0 0 1 0 0 0 208 1 30 136 40 0​​ 0 0 29 0 0 1 0 236 205 216 48 0 22 44 215 0 0 0 29 0 0 0 40 0​​ 0 0 2 0 0 0 1 0 0 0 144 0 0 0 1 0 0 5 238 0 0 0 4 0 0 0 128 240 146 28 72 194 0 0 14 12 48 199 199 8 0 69 0 5 220 67 144 64 0 47 6 22 9 193 104 215 69 147 188 192 24 0 80 142 152 237 69 173 223 114 104 162 142 128 16 0 54 47 172 0 0 1 1 8 10 139 71 198 102 37 2 188 249 253 49 241 16 12 100 96 130 25 195 170 251 218 202 149 6 45 216 81 206 145 254 7 147 240 20 103 185 112 138 115 50 158 226 156 204 78 113 98 240 114 65 240 51 253 252 102 174 242 80 12 50 241 179 148 204 90 200 196 66 118 137 0 0 3 233 0 0 0 16 0 0 0 3 0 0 0 2 0 0 0 2 255 255 255 255 0 0 0 1 0 0 0 148 1 30 136 41 0 0 0 29 0 0 1 0 236 205 217 14 0 22 44 215 0 0 0 29 0 0 0 25 0 0 0 2 0 0 0 1 0 0 0 84 0 0 0 1 0 0 0 70 0 0 0 4 0 0 0 68 240 146 28 72 194 0 0 14 12 48 199 199 8 0 69 0 0 52 174 239 0 0 48 6 219 72 216 58 210 78 147 188 194 70 1 187 179 154 222 83 63 174 28 240 175 235 128 16 5 91 120 31 0 0 1 1 8 10 94 165 224 71 49 84 232 65 0 0 0 0 3 233 0 0 0 16 0 0 0 3 0 0 0 2 0 0 0 14 255 255 255 255

这是从核心收集的sFlow数据switch.So我必须要找到以太网,IPv4的IPv6的扩展开关数据从这个有效载荷和打印。在此之前,我需要找到其中的每有效载荷中的八位位置。你能告诉我,我应该如何找到他们每个人的八位位置?

在使用上述code中的结构错误:

  udps.c:25:错误:预期'=',',',',','ip_v4'前'ASM'或'__attribute__'
udps.c:26:错误:预期'=',',',',','ip_v6'前'ASM'或'__attribute__'
udps.c:33:错误:声明指定了两个或多个数据类型
udps.c:33:错误:预期')'之前'类型'
udps.c:45:错误:'header_protocol之前的预期说明符限定符列表
udps.c:58:错误:'ip_v4之前的预期说明符限定符列表
udps.c:69:错误:声明指定了两个或多个数据类型
udps.c:74:错误:'ip_v6之前的预期说明符限定符列表
udps.c:87:错误:声明指定了两个或多个数据类型
udps.c:93:错误:声明指定了两个或多个数据类型
udps.c:93:错误:声明指定了两个或多个数据类型
udps.c:93:错误:预期')'之前'类型'
udps.c:115:错误:声明指定了两个或多个数据类型
udps.c:在函数'主':
udps.c:131:错误:不兼容的类型返回类型时,'诠释',但'结构extended_switch预期
udps.c:147:错误:不兼容的类型返回类型时,'诠释',但'结构extended_switch预期
udps.c:163:错误:不兼容的类型返回类型时,'诠释',但'结构extended_switch预期
udps.c:173:错误:不兼容的类型返回类型时,'诠释',但'结构extended_switch预期


解决方案

在使用创建类型AF_INET的插座/ SOCK_DGRAM,操作系统处理以太网,IP和UDP报头并将它们传递给你之前去除了那些。你在缓冲区看到的就是紧跟在UDP报头。

第五个参数为 recvfrom的为您提供了传入数据包的源IP和源端口。如果你想看到的不仅仅是你需要使用数据包捕获库libpcap的一样。

编辑:

看来,这个数据包包含IP地址作为sFlow的数据的一部分。您试图解析它,如果它是一个原始的以太网帧。什么,而不是你需要做的是看sFlow的数据包定义,并用它来计算出数据包是如何布局并据此分析。你并不需要使用的memcpy 来做到这一点,只需使用指针相关的结构,使其指向缓冲区中的适当位置。这是你在​​使用前相同的基本技术,只需用一组不同的结构的。

编辑2:

它看起来像我们这样过什么数据的模样。我把字节从上面列出的数据包,其读取到缓冲区,并在一个UDP数据包发送出去。我启动了Wireshark的,这给了我们这样的:

Wireshark的捕获

所以数据包包含:


  • sFlow的版本,32位(5)

  • 一个32位的int(值= 1)

  • 结构sample_datagram_v5

  • 样品的数量(32位int,值= 6)

  • 六个样本

第一个示例包括:


  • 样品类型作为 DATA_FORMAT (在此情况下的流样品)

  • 结构flow_sample

  • 流的样本数(32位int,值= 2)

第一样品中的第一流动:


  • 流量类型为 DATA_FORMAT (INT这种情况下,原始数据包样本,所以......)

  • 流量数据长度(32位int,值= 144)

  • 结构sampled_header

  • 被跳过按值
  • 4个字节的 sampled_header.stripped

  • 以太网帧头

  • IP报头(有效载荷= TCP)

  • TCP报头(端口= 80)

  • 数据字节(62)

第一样品中的第二流动


  • 流量类型为 DATA_FORMAT (INT这种情况下,延长开关数据)

  • 流量数据长度(32位int,值= 16)

  • 结构extended_switch

然后五个样品。在这种情况下,所有的样品含有一个原始数据包首标和扩展开关数据

因此​​,这应该给你的,你需要做一个更好的主意。由于每个数据包会不同,你需要找出您对我们多少样本都有。然后,对每个样品,你需要弄清楚的类型,并根据这个数字如何解析单个流。

如果你需要更多的例子我强烈建议使用Wireshark来捕获这些sFlow报,所以你可以看到究竟是什么在他们来验证您的解析器适用于所有期望的输入。

相关参考问题:<一href=\"http://stackoverflow.com/questions/31995486/use-of-memcpy-to-store-data-from-buffer-into-struct/32011201\">use中的memcpy从缓冲区中的数据存储到结构

I am trying to collect UDP data payload information using C program by capturing the packet from port 6343. The code I am using is as follows:

#include<stdio.h>             //For standard things
#include<stdlib.h>            //malloc
#include<string.h>            //memset
#include<netinet/ip_icmp.h>   //Provides declarations for icmp header
#include<netinet/udp.h>       //Provides declarations for udp header
#include<netinet/tcp.h>       //Provides declarations for tcp header
#include<netinet/ip.h>        //Provides declarations for ip header
#include<sys/socket.h>
#include<arpa/inet.h>
#include<net/ethernet.h>
#include<netinet/if_ether.h>
#define PORT 6343             // define the port to connect
#define ETH_P_IP 0x0800

void ProcessPacket(unsigned char*, int);
void print_ethernet_header(unsigned char*, int);
void print_ip_header(unsigned char* , int);
void print_udp_packet(unsigned char*, int);
void Dataint (unsigned char* , int);
void print(const int *, const int);
int sockt;
int i,j;
struct sockaddr_in source,dest; 

const MAX_HEADER_SIZE = 256;   /* The maximum sampled header size. */

struct sampled_header {
header_protocol protocol;       /* Format of sampled header */
unsigned int frame_length;      /* Original length of packet before
                                  sampling */
opaque header{MAX_HEADER_SIZE}; /* Header bytes */
}

/* Packet IP version 4 data */

struct sampled_ipv4 {
unsigned int length;     /* The length of the IP packet excluding
                           lower layer encapsulations */
unsigned int protocol;   /* IP Protocol type
                           (for example, TCP = 6, UDP = 17) */
ip_v4 src_ip;            /* Source IP Address */
ip_v4 dst_ip;            /* Destination IP Address */
unsigned int src_port;   /* TCP/UDP source port number or
                           equivalent */
unsigned int dst_port;   /* TCP/UDP destination port number or
                           equivalent */
unsigned int tcp_flags;  /* TCP flags */
unsigned int tos;        /* IP type of service */
}
/* Packet IP version 6 data */

struct sampled_ipv6 {
unsigned int length;     /* The length of the IP packet excluding
                           lower layer encapsulations */
unsigned int protocol;   /* IP next header
                           (for example, TCP = 6, UDP = 17) */
ip_v6 src_ip;            /* Source IP Address */
ip_v6 dst_ip;            /* Destination IP Address */
unsigned int src_port;   /* TCP/UDP source port number or
                           equivalent */
unsigned int dst_port;   /* TCP/UDP destination port number or
                           equivalent */
unsigned int tcp_flags;  /* TCP flags */
unsigned int priority;   /* IP priority */
}

struct extended_switch {
unsigned int src_vlan;     /* The 802.1Q VLAN id of incoming frame */
unsigned int src_priority; /* The 802.1p priority of incoming
                             frame */
unsigned int dst_vlan;     /* The 802.1Q VLAN id of outgoing frame */
unsigned int dst_priority; /* The 802.1p priority of outgoing
                             frame */
}

 int main()
 {

int saddr_size,data_size, datasize; 
struct sockaddr_in saddr;
struct sockaddr_in daddr;
struct in_addr addr;
int protocol=17;
unsigned char* buffer = (unsigned char *)malloc(65535); // Its Big ! Malloc allocates a block of size bytes of memory,returning a pointer to the begining of the block

//Create a socket

sockt = socket(AF_INET ,SOCK_DGRAM ,IPPROTO_UDP);
if(sockt < 0)
{
    printf("Socket Error\n");
    return 1;
}
memset((char *)&daddr,0,sizeof(daddr));

//prepare the sockaddr_in structure
saddr.sin_family = AF_INET;
daddr.sin_family = AF_INET;
daddr.sin_addr.s_addr = htonl(INADDR_ANY);
daddr.sin_port = htons(PORT);
saddr.sin_port = htons(PORT);
//Bind the socket

if(bind(sockt,(struct sockaddr *)&daddr, sizeof(daddr))<0)
{
  printf("bind failed");
  return 1;
}
printf("bind done");

while(1)
{
saddr_size = sizeof saddr;
printf(" waiting for data...\n");

//Receive a packet

datasize = recvfrom(sockt , buffer ,65535 , 0 , (struct sockaddr*) &saddr , (socklen_t*)&saddr_size);
data_size = recvfrom(sockt , buffer ,65535 , 0 , NULL , NULL);
if(data_size <0)
{
  printf("Packets not recieved \n");
  return 1;
}
printf("Packets arrived from %d \n",ntohs(daddr.sin_port));
printf("packet recieved : %lu bytes\n", datasize);

ProcessPacket(buffer , data_size);

}
close(sockt);
printf("Finished");
return 0;
}


void ProcessPacket(unsigned char* buffer, int len)
{
  print_udp_packet(buffer , len);

}

void print_ethernet_header(unsigned char* buffer, int len)
{
  struct ethhdr *eth = (struct ethhdr *)buffer;
  printf("Ethernet Header\n");
  printf("---------------------------------------\n");
  printf("Ethernet Header Length   : %u bytes \n",sizeof(eth));
  printf("Destination MAC : %.2X-%.2X-%.2X-%.2X-%.2X-%.2X \n", eth->h_dest[0] , eth->h_dest[1] , eth->h_dest[2] , eth->h_dest[3] , eth->h_dest[4] , eth->h_dest[5] );
  printf("Source MAC      : %.2X-%.2X-%.2X-%.2X-%.2X-%.2X \n", eth->h_source[0] , eth->h_source[1] , eth->h_source[2] , eth->h_source[3] , eth->h_source[4] , eth->h_source[5] );
  printf("Ethernet Type   : %u \n",eth->h_proto);
  printf("---------------------------------------\n");
  }

  void print_ip_header(unsigned char* buffer, int len)
  {
  //print_ethernet_header(buffer , len);

  struct iphdr *iph = (struct iphdr *)(buffer + sizeof(struct ethhdr));
  unsigned short iphdrlen = iph->ihl*4;

  memset(&source,0,sizeof(source));
  source.sin_addr.s_addr = iph ->saddr;
  memset(&dest,0,sizeof(dest));
  dest.sin_addr.s_addr = iph->daddr;

  printf("IP Header\n");
  printf("---------------------------------------\n");
  printf("IP Length        : %d\n", ntohs(iph->tot_len));
  printf("Source IP        : %s\n",inet_ntoa(source.sin_addr));
  printf("Destination IP   : %s\n",inet_ntoa(dest.sin_addr));
  printf("Protocol         : %d\n", iph->protocol);
  printf("Type Of Service  : %d\n",htons(iph->tos));
  printf("---------------------------------------\n");
  }


  void print_udp_packet(unsigned char* buffer , int len)
  {
  struct sockaddr_in saddr;
  struct sockaddr_in daddr;
  unsigned short iphdrlen;
  unsigned char* payload = (unsigned char *)malloc(1024);
  struct iphdr *iph = (struct iphdr *)(buffer+ sizeof(struct ethhdr));
  iphdrlen = iph->ihl*4;

   struct udphdr *udph = (struct udphdr*)(buffer + sizeof(struct iphdr)+sizeof(struct ethhdr));

   int header_size =  sizeof(struct ethhdr) + iphdrlen + sizeof udph;

   print_ip_header(buffer,len);

   printf("UDP Header\n");
   printf("---------------------------------------\n");
   printf("UDP Length       : %d\n", ntohs(udph->len));
   //printf("UDP Length       : %d\n", ntohs(sizeof (struct udphdr))); 
   printf("Source Port      : %d\n ",ntohs(udph->source));
   printf("Destination Port : %d\n ",ntohs(udph->dest));
   printf("Source Port      : %d\n ",ntohs(saddr.sin_port));
   printf("Destination Port : %d\n ",ntohs(daddr.sin_port)); 
   printf("---------------------------------------\n");

   printf("Data Payload\n");  
   //PrintData(buffer + header_size , len - header_size);
   Dataint(buffer ,len);
   printf("--------------------------------------------\n"); 


   }

  void Dataint (unsigned char* buffer , int len)
  {

  int i,j;
  i=0;
  for(i=0 ; i <= len ; i++)
  {
    if( i!=0 && i%16==0)   // prints every hex line with a space
    {
        printf("  ");
    } 

     // prints entire data in integer
      if(i%16==0) 
        printf("   ");                           // prints the first element of hex line                      
        printf(" %d",(unsigned int)buffer[i]);  

    //print the last spaces         
    if( i==len-1)  
    {
        for(j=0;j<16-i%16;j++) 
        printf("   ");

    }
   }
  } 

I have the payload converted to integer form as shown below:

0 0 0 5 0 0 0 1 147 188 192 6 0 0 0 0      0 50 170 143 37 107 3 154 0 0 0 6 0 0 0 1      0 0 0 208 1 30 136 36 0 0 0 29 0 0 1 0      236 205 212 188 0 22 44 215 0 0 0 29 0 0 0 40      0 0 0 2 0 0 0 1 0 0 0 144 0 0 0 1      0 0 5 238 0 0 0 4 0 0 0 128 240 146 28 72      194 0 0 14 12 48 199 199 8 0 69 0 5 220 65 28      64 0 47 6 24 125 193 104 215 69 147 188 192 24 0 80      142 152 237 55 211 205 114 104 162 142 128 16 0 54 188 178      0 0 1 1 8 10 139 71 198 30 37 2 188 177 205 144      135 164 154 194 155 33 30 238 48 113 112 179 62 180 223 221      169 24 234 48 163 41 188 139 148 98 130 255 16 229 123 58      202 165 56 101 14 217 132 108 10 156 47 29 77 156 220 141      202 248 196 75 240 252 232 27 19 140 52 187 0 0 3 233      0 0 0 16 0 0 0 3 0 0 0 2 0 0 0 2      255 255 255 255 0 0 0 1 0 0 0 208 1 30 136 37      0 0 0 29 0 0 1 0 236 205 214 47 0 22 44 215      0 0 0 29 0 0 0 40 0 0 0 2 0 0 0 1      0 0 0 144 0 0 0 1 0 0 5 238 0 0 0 4      0 0 0 128 240 146 28 72 194 0 0 14 12 48 199 199      8 0 69 0 5 220 65 243 64 0 47 6 23 166 193 104      215 69 147 188 192 24 0 80 142 152 237 60 147 229 114 104      162 142 128 16 0 54 13 151 0 0 1 1 8 10 139 71      198 66 37 2 188 213 16 243 209 241 120 208 124 252 85 108      101 62 10 255 21 98 62 58 136 127 106 62 238 76 85 231      227 224 70 62 31 217 151 211 47 106 246 111 160 87 164 114      43 83 45 230 197 131 18 49 110 159 251 162 207 148 178 31      212 40 81 190 0 0 3 233 0 0 0 16 0 0 0 3      0 0 0 2 0 0 0 2 255 255 255 255 0 0 0 1      0 0 0 148 1 30 136 38 0 0 0 29 0 0 1 0      236 205 214 158 0 22 44 215 0 0 0 0 0 0 0 29      0 0 0 2 0 0 0 1 0 0 0 84 0 0 0 1      0 0 0 70 0 0 0 4 0 0 0 68 0 14 12 48      199 199 240 146 28 72 194 0 8 0 69 0 0 52 28 175      64 0 63 6 50 146 147 188 192 24 193 104 215 69 142 152      0 80 114 104 162 142 237 62 109 231 128 16 36 63 51 129      0 0 1 1 8 10 37 2 188 231 139 71 198 66 0 0      0 0 3 233 0 0 0 16 255 255 255 255 0 0 0 0      0 0 0 3 255 255 255 255 0 0 0 1 0 0 0 208      1 30 136 39 0 0 0 29 0 0 1 0 236 205 215 173      0 22 44 215 0 0 0 29 0 0 0 40 0 0 0 2      0 0 0 1 0 0 0 144 0 0 0 1 0 0 5 238      0 0 0 4 0 0 0 128 240 146 28 72 194 0 0 14      12 48 199 199 8 0 69 0 5 220 67 10 64 0 47 6      22 143 193 104 215 69 147 188 192 24 0 80 142 152 237 66      188 223 114 104 162 142 128 16 0 54 185 33 0 0 1 1      8 10 139 71 198 102 37 2 188 248 226 4 177 86 140 52      15 181 49 144 230 162 19 81 72 179 190 46 196 123 24 85      38 153 175 213 96 59 3 73 194 138 211 35 187 143 148 46      200 190 255 249 6 223 220 57 180 2 123 223 184 204 149 28      127 218 240 134 94 247 236 103 0 0 3 233 0 0 0 16      0 0 0 3 0 0 0 2 0 0 0 2 255 255 255 255      0 0 0 1 0 0 0 208 1 30 136 40 0 0 0 29      0 0 1 0 236 205 216 48 0 22 44 215 0 0 0 29      0 0 0 40 0 0 0 2 0 0 0 1 0 0 0 144      0 0 0 1 0 0 5 238 0 0 0 4 0 0 0 128      240 146 28 72 194 0 0 14 12 48 199 199 8 0 69 0      5 220 67 144 64 0 47 6 22 9 193 104 215 69 147 188      192 24 0 80 142 152 237 69 173 223 114 104 162 142 128 16      0 54 47 172 0 0 1 1 8 10 139 71 198 102 37 2      188 249 253 49 241 16 12 100 96 130 25 195 170 251 218 202      149 6 45 216 81 206 145 254 7 147 240 20 103 185 112 138      115 50 158 226 156 204 78 113 98 240 114 65 240 51 253 252      102 174 242 80 12 50 241 179 148 204 90 200 196 66 118 137      0 0 3 233 0 0 0 16 0 0 0 3 0 0 0 2      0 0 0 2 255 255 255 255 0 0 0 1 0 0 0 148      1 30 136 41 0 0 0 29 0 0 1 0 236 205 217 14      0 22 44 215 0 0 0 29 0 0 0 25 0 0 0 2      0 0 0 1 0 0 0 84 0 0 0 1 0 0 0 70      0 0 0 4 0 0 0 68 240 146 28 72 194 0 0 14      12 48 199 199 8 0 69 0 0 52 174 239 0 0 48 6      219 72 216 58 210 78 147 188 194 70 1 187 179 154 222 83      63 174 28 240 175 235 128 16 5 91 120 31 0 0 1 1      8 10 94 165 224 71 49 84 232 65 0 0 0 0 3 233      0 0 0 16 0 0 0 3 0 0 0 2 0 0 0 14      255 255 255 255 

This is a sflow data collected from a core switch.So I have to find the Ethernet, IPv4, IPv6,extended switch data from this payload and print them. Before that I need to find the octet position of each of these in the payload. can you advise me how should I find the octet position of each of them ?

Errors while using the structs in above code:

     udps.c:25: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘ip_v4’
udps.c:26: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘ip_v6’
udps.c:33: error: two or more data types in declaration specifiers
udps.c:33: error: expected ‘)’ before ‘type’
udps.c:45: error: expected specifier-qualifier-list before ‘header_protocol’
udps.c:58: error: expected specifier-qualifier-list before ‘ip_v4’
udps.c:69: error: two or more data types in declaration specifiers
udps.c:74: error: expected specifier-qualifier-list before ‘ip_v6’
udps.c:87: error: two or more data types in declaration specifiers
udps.c:93: error: two or more data types in declaration specifiers
udps.c:93: error: two or more data types in declaration specifiers
udps.c:93: error: expected ‘)’ before ‘type’
udps.c:115: error: two or more data types in declaration specifiers
udps.c: In function ‘main’:
udps.c:131: error: incompatible types when returning type ‘int’ but ‘struct extended_switch’ was expected
udps.c:147: error: incompatible types when returning type ‘int’ but ‘struct extended_switch’ was expected
udps.c:163: error: incompatible types when returning type ‘int’ but ‘struct extended_switch’ was expected
udps.c:173: error: incompatible types when returning type ‘int’ but ‘struct extended_switch’ was expected

解决方案

When use create a socket of type AF_INET / SOCK_DGRAM, the operating system processes the Ethernet, IP, and UDP headers and strips them off before passing them to you. What you see in buffer is what immediately follows the UDP header.

The fifth parameter to recvfrom gives you the source IP and source port of the incoming packet. If you want to see more than just that you need to use a packet capture library like libpcap.

Edit:

It seems that this data packet contains IP addresses as part of sflow data. You were trying to parse it as if it was a raw Ethernet frame. What you instead need to do is look at the sflow datagram definition and use that to figure out how the packet is laid out and parse accordingly. You don't need to use memcpy to do that, just use pointers to the relevant structs to point to the proper place in the buffer. This is the same basic technique you were using before, just with a different set of structs.

Edit 2:

It looks like we're way off on what the data looks like. I took the bytes from the packet listed above, read them into a buffer and sent it out in a UDP packet. I fired up Wireshark, which gave us this:

So the packet contains:

  • The sflow version, 32-bit (5)
  • an 32 bit int (value=1)
  • a struct sample_datagram_v5
  • the number of samples (32-bit int, value=6)
  • six samples

The first sample contains:

  • The sample type as a data_format (in this case a flow sample)
  • a struct flow_sample
  • the number of flow samples (32-bit int, value=2)

The first flow in the first sample:

  • The flow type as a data_format (int this case a raw packet sample, so...)
  • the flow data length (32-bit int, value=144)
  • a struct sampled_header
  • 4 bytes that are skipped as per the value of sampled_header.stripped
  • ethernet header
  • IP header (payload=TCP)
  • TCP header (port=80)
  • data bytes (62)

The second flow in the first sample:

  • The flow type as a data_format (int this case extended switch data)
  • the flow data length (32-bit int, value=16)
  • a struct extended_switch

Then five more samples. In this case, all the samples contain a raw packet header and extended switch data.

So this should give you a better idea of what you need to do. Since each data packet will be different, you'll need to figure our how many samples you have. Then for each sample, you'll need to figure out the type, and based on that figure out how to parse the individual flows.

If you need more examples I'd strongly suggest using Wireshark to capture these sflow packets so you can see exactly what's in them to validate that your parser works for all expected input.

Related question for reference: use of memcpy to store data from buffer into struct

这篇关于在C程序一个UDP数据有效载荷寻找八位的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆