Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/azure/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用H.248 SCTP负载创建pcap数据包_C_Libpcap - Fatal编程技术网

使用H.248 SCTP负载创建pcap数据包

使用H.248 SCTP负载创建pcap数据包,c,libpcap,C,Libpcap,我试图通过使用pcap C库创建一个包含BER格式的H.248消息的数据包,以便使用wireshark应用程序对其进行解码。我编写并运行的代码如下: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdbool.h> #include <pcap.h> #include <pcap/vlan.h> #include <net/e

我试图通过使用pcap C库创建一个包含BER格式的H.248消息的数据包,以便使用wireshark应用程序对其进行解码。我编写并运行的代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <pcap.h>
#include <pcap/vlan.h>
#include <net/ethernet.h>
#include <netinet/ip.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <linux/netdevice.h>
#include <linux/if_vlan.h>
#include <linux/if_ether.h>


#ifdef LINUX
#include <netinet/ether.h>
#endif

#define LINE_LEN 16

// chunk identifier 
#define SH_DATA 0
#define SH_INIT 1
#define SH_INIT_ACK 2
#define SH_SACK 3
#define SH_HEARTBEAT 4
#define SH_HEARTBEAT_ACK 5
#define SH_ABORT 6
#define SH_SHUTDOWN_ACK 8
#define SH_COOKIE_ECHO 10
#define SH_COOKIE_ACK 11
#define SH_ECNE 12
#define SH_CWR 13
#define SH_SHUTDOWN_COMPLETE 14

//payload protocol identifier for SCTP
#define RESERVED 0 //[RFC4960]  
#define IUA      1 //[RFC4233]  
#define M2UA     2 //[RFC3331]  
#define M3UA     3 //[RFC4666]  
#define SUA      4 //[RFC3868]  
#define M2PA     5 //[RFC4165]  
#define V5UA     6 //[RFC3807]  
#define H248     7 
#define BICC     8  
#define TALI     9 //[RFC3094]  
#define DUA     10 //[RFC4129]  
#define ASAP    11 //[RFC5352]  
#define ENRP    12 //[RFC5353]  
#define H323    13  
#define QIPC    14 //Q.2150.3       
#define SIMCO   15  
#define DDPSEGC 16   
#define DDPSSC  17      
#define S1AP    18 
#define RUA     19 
#define HNBAP   20 
#define FORCESHP 21     
#define FORCESMP 22 
#define FORCESLP 23 
#define SBCAP    24    
#define NBAP     25 
#define UNASSIGNED 26       
#define X2AP    27

u_char payload[] = {0x30, 0x82, 0x01, 0x60, 0xa1, 0x82, 0x01, 0x5c, 0x80, 0x01, 0x02,0xa1, 0x04, 0x84, 0x02, 0x24, 0x1a, 0xa2, 0x82, 0x01, 0x4f, 0xa1, 0x82, 0x01, 0x4b, 0xa0, 0x82, 0x01, 0x47, 0x80, 0x04, 0x2f, 0x00, 0x00, 0xaa, 0xa1, 0x82, 0x01, 0x3d, 0x30, 0x82, 0x01, 0x39,0x80, 0x04, 0x10, 0x00, 0x00, 0x0f, 0xa3, 0x82, 0x01, 0x2f, 0x30, 0x82, 0x01, 0x2b, 0xa0, 0x82, 0x01, 0x27, 0xa6, 0x82, 0x01, 0x23, 0xa0, 0x0a, 0x30, 0x08, 0xa0, 0x00, 0x81, 0x04, 0x28, 0x40, 0x00, 0x07, 0xa1, 0x82, 0x01, 0x13, 0x80, 0x01, 0x2f, 0xa1, 0x82, 0x01, 0x0c, 0x30, 0x2f, 0x80, 0x04, 0x00, 0x21, 0x00, 0x01, 0x81, 0x02, 0x00, 0xff, 0xa2, 0x0d, 0x30, 0x0b, 0x80, 0x02, 0x00, 0x01, 0xa1, 0x05, 0x04, 0x03, 0x0a, 0x01, 0x01, 0xa3, 0x14, 0x80, 0x08, 0x02, 0x00, 0x00, 0x07, 0x00, 0x06, 0x00, 0x05, 0x81, 0x08, 0x01, 0x08, 0x03, 0x01, 0x01, 0x02, 0x03, 0x04, 0x30, 0x81,
0xa7, 0x80, 0x04, 0x00, 0x22, 0x00, 0x01, 0xa2, 0x81, 0x9e, 0x30, 0x81, 0x9b, 0x80, 0x02, 0x00, 0x01, 0xa1, 0x81, 0x94, 0x04, 0x81, 0x91, 0x04, 0x81, 0x8e, 0x20, 0x20, 0x76, 0x3d, 0x30, 0x0d, 0x0a, 0x6f, 0x3d, 0x2d, 0x20, 0x30, 0x20, 0x30, 0x20, 0x49, 0x4e, 0x20, 0x49, 0x50, 0x34, 0x20, 0x31, 0x30, 0x2e, 0x33, 0x2e, 0x31, 0x2e, 0x34, 0x0d, 0x0a, 0x73, 0x3d, 0x2d, 0x0d, 0x0a, 0x63, 0x3d, 0x49, 0x4e, 0x20, 0x49, 0x50, 0x34, 0x20, 0x31, 0x30, 0x2e, 0x33, 0x2e, 0x31, 0x2e, 0x34, 0x0d, 0x0a, 0x74, 0x3d, 0x30, 0x20, 0x30, 0x0d, 0x0a, 0x61, 0x3d, 0x69, 0x70, 0x62, 0x63, 0x70, 0x3a, 0x31, 0x20, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x0d, 0x0a, 0x6d, 0x3d, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x20, 0x31, 0x38, 0x39, 0x34, 0x38, 0x20, 0x52, 0x54, 0x50, 0x2f, 0x41, 0x56, 0x50, 0x20, 0x39, 0x36, 0x0d, 0x0a, 0x61, 0x3d, 0x72, 0x74, 0x70, 0x6d, 0x61, 0x70, 0x3a, 0x39, 0x36, 0x20, 0x56, 0x4e, 0x44, 0x2e, 0x33, 0x47, 0x50, 0x50, 0x2e, 0x49, 0x55, 0x46, 0x50, 0x2f, 0x31, 0x36, 0x30, 0x30, 0x30, 0x0d, 0x0a, 0x30, 0x2f, 0x80, 0x04, 0x00, 0x21, 0x00, 0x02, 0x81, 0x02, 0x00, 0xff, 0xa2, 0x0d, 0x30, 0x0b, 0x80, 0x02, 0x00, 0x01, 0xa1, 0x05, 0x04, 0x03, 0x0a, 0x01, 0x01, 0xa3, 0x14, 0x80, 0x08, 0x02, 0x00, 0x00, 0x07, 0x00, 0x06, 0x00, 0x05, 0x81,
0x08, 0x01, 0x08, 0x03, 0x01, 0x01, 0x02, 0x03, 0x04};

int SCTP_payload = sizeof payload / sizeof(u_char);

struct chunk
{
  u_char        identifier; // type
  u_char        flags;
  u_short           length;
  unsigned int          seq_num;
  u_short               stream_id;
  u_short               stream_seq_num;
  unsigned int      payload_id;
};


struct sctphdr
{
  /*
    The data types/sizes we need to use are: unsigned char - 1 byte (8 bits),
    unsigned short int - 2 bytes (16 bits) and unsigned int - 4 bytes (32 bits)
  */
  u_short           sport;
  u_short           dport;
  unsigned int      veriftag;
  unsigned int      sctp_sum;
  // chunk follows
  struct chunk          chnk;
};


struct ethernet {
  u_char        mac1[6];
  u_char        mac2[6];
  u_short       protocol;
};


struct packet{

//struct ethernet ether;

struct iphdr iph;

struct sctphdr sctph;

u_char payload_data[396];

};



int main()
{
  pcap_t *fd;

  char errbuf[PCAP_ERRBUF_SIZE];

  struct pcap_pkthdr *header;
  const u_char *pkt_data;
  u_int i=1;

  pcap_t *pd;
  pcap_dumper_t *pdumper;

  pd = pcap_open_dead(DLT_RAW, 65535);
  pdumper = pcap_dump_open(pd, "test3.pcap");


  //lets move on to SCTP header

  struct packet mypacket;


  #if __BYTE_ORDER == __LITTLE_ENDIAN
  mypacket.sctph.sport = htons(2945);
  mypacket.sctph.dport = htons(2945);
  #endif
  mypacket.sctph.veriftag = 0;
  mypacket.sctph.sctp_sum = 0;

  mypacket.sctph.chnk.identifier =  SH_DATA;
  mypacket.sctph.chnk.flags      =  0x03;

  #if __BYTE_ORDER == __LITTLE_ENDIAN
  mypacket.sctph.chnk.length = htons(sizeof(struct chunk)+SCTP_payload);


  mypacket.sctph.chnk.seq_num    =  htonl(206);
  mypacket.sctph.chnk.stream_id  =  htons(0x0001);
  mypacket.sctph.chnk.stream_seq_num = htons(205);
  mypacket.sctph.chnk.payload_id     = htonl(H248);
  #endif


  printf("SCTP_payload:%d\n",SCTP_payload);  


  struct pcap_pkthdr packet_header;
  struct timeval ts;

  packet_header.ts = ts;
  packet_header.caplen = sizeof(struct packet) + SCTP_payload;
  packet_header.len =  sizeof(struct packet) + SCTP_payload;


  #if __BYTE_ORDER  == __LITTLE_ENDIAN
  //write data for IP protocol header

  char dst_addr[]={"10.87.25.136"};
  char src_addr[]={"10.92.152.7"};

  mypacket.iph.saddr = inet_addr(src_addr);
  mypacket.iph.daddr = inet_addr(dst_addr);

  mypacket.iph.version = 4;
  mypacket.iph.ihl = 5; //20 bytes
  mypacket.iph.tos = 0; //type of service
  #endif

  #if __BYTE_ORDER  == __LITTLE_ENDIAN

  mypacket.iph.tot_len = htons(sizeof(struct iphdr)+sizeof(struct sctphdr)+SCTP_payload);



  printf("iph.tot_len:%d\n",sizeof(struct iphdr));



  mypacket.iph.id = htons(0x9152); //identification
  mypacket.iph.frag_off = 0; //fragment offset
  mypacket.iph.ttl=255;
  mypacket.iph.protocol = 132; //SCTP
  mypacket.iph.check = htons(0x6069);
  #endif



  memcpy(mypacket.payload_data,&payload[0],SCTP_payload*sizeof(u_char));

  pcap_dump((u_char*)pdumper, &packet_header, (const u_char*)&mypacket);


  pcap_close(pd);
  pcap_dump_close(pdumper);


}
不幸的是,当我运行修改后的C程序时,无法识别数据包的SCTP有效负载(H.248消息),因为在SCTP有效负载协议标识符(00 07)之后插入了一些垃圾数据。请查看下图:

我做错了什么

提前谢谢你

函数需要第三个参数(
mypacket
)中指定的数据。在您的第一次尝试中,情况就是这样,因为数据直接存储在结构
struct数据包中

struct packet {
    struct iphdr iph;
    struct sctphdr sctph;
    u_char payload_data[396];
};
然后您将其更改为:

struct packet {
    struct iphdr iph;
    struct sctphdr sctph;
    u_char *payload_data;
};
现在,结构中存储的不是数据本身,而是指向存储数据的内存位置的指针
pcap_dump
不知道数据的语义,因此它当然不能取消引用该指针并使用存储在那里的数据,但它只存储内存位置

一种可能的解决方案是按如下方式定义结构:

struct packet {
    struct iphdr iph;
    struct sctphdr sctph;
    u_char payload_data[1];
};
然后为整个结构分配内存,如:

struct packet *p = malloc(sizeof(struct packet)+payloadlen);
通过这种方式,您可以使有效负载长度动态变化,但数据仍然是整体的,因此适合于
pcap\u dump()

pcap\u dump()
-函数需要在第三个参数(
mypacket
在您的情况下)中整体指定的数据。在您的第一次尝试中,情况就是这样,因为数据直接存储在结构
struct数据包中

struct packet {
    struct iphdr iph;
    struct sctphdr sctph;
    u_char payload_data[396];
};
然后您将其更改为:

struct packet {
    struct iphdr iph;
    struct sctphdr sctph;
    u_char *payload_data;
};
现在,结构中存储的不是数据本身,而是指向存储数据的内存位置的指针
pcap_dump
不知道数据的语义,因此它当然不能取消引用该指针并使用存储在那里的数据,但它只存储内存位置

一种可能的解决方案是按如下方式定义结构:

struct packet {
    struct iphdr iph;
    struct sctphdr sctph;
    u_char payload_data[1];
};
然后为整个结构分配内存,如:

struct packet *p = malloc(sizeof(struct packet)+payloadlen);

通过这种方式,您可以动态设置有效负载长度,但数据仍然是整体的,因此适合于
pcap\u dump()

Libpcap实际上不适合创建数据包。你看过像Scapy这样的框架吗?Libpcap真的不适合创建数据包。你看过像Scapy这样的框架吗?