From 55d028fcd35b92dd98d767df18a5905a2f1951c7 Mon Sep 17 00:00:00 2001 From: yangwei Date: Fri, 2 Aug 2019 17:06:26 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E6=96=B0=E5=A2=9Ebuild.sh=E5=92=8Ccl?= =?UTF-8?q?ean.sh=EF=BC=8C=E7=94=A8=E4=BA=8E=E8=BE=85=E5=8A=A9=E7=BC=96?= =?UTF-8?q?=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2、更新tcpreplay.c,支持回放MPLS,PPPoE,VLAN封装的数据包 --- .gitignore | 1 + build.sh | 3 ++ clean.sh | 2 + src/tcpreplay.c | 128 ++++++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 124 insertions(+), 10 deletions(-) create mode 100644 .gitignore create mode 100755 build.sh create mode 100755 clean.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f3f921b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +tcpburst diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..43c4f0d --- /dev/null +++ b/build.sh @@ -0,0 +1,3 @@ +sh ./configure --enable-dynamic-link +make +cp src/tcpreplay ./tcpburst diff --git a/clean.sh b/clean.sh new file mode 100755 index 0000000..1fe86cb --- /dev/null +++ b/clean.sh @@ -0,0 +1,2 @@ +make clean +make distclean diff --git a/src/tcpreplay.c b/src/tcpreplay.c index aa02786..8b50cfc 100644 --- a/src/tcpreplay.c +++ b/src/tcpreplay.c @@ -1208,15 +1208,15 @@ static inline int stream_addr_cmp_udp(struct ip *iphdr, struct udphdr *udphdr) Ϊ˲¼УͣԴﵽϸߵķʣ ĵַʱIPַ޸ģӺͼٵֵҪ. */ -static int stream_edit_addr(u_char *pkt, int differ) +static int stream_edit_addr(u_char *pkt, int differ, struct ip* iphdr) { - struct ip *iphdr; + //struct ip *iphdr; struct tcphdr *tcphdr; struct udphdr *udphdr; differ *= 3; - iphdr = (struct ip *)(pkt + 14); + //iphdr = (struct ip *)(pkt + 14); if(IPPROTO_TCP == iphdr->ip_p) { @@ -1285,7 +1285,8 @@ static int stream_burst_send_pkt_by_marsio(struct mr_sendpath *handle, const u_c } #endif -#ifdef MARSIO +//#ifdef MARSIO +#if 0 static stream_burst_send_pkt_multiple(void *handle, const u_char *pkt, size_t pktlen) { marsio_buff_t *send_mbuf[256]; @@ -1422,7 +1423,97 @@ int stream_burst_send_pkt(void *handle, const u_char *pkt, size_t pktlen) #endif } -int stream_burst(sendpacket_t *sp, const u_char *pkt, size_t pktlen, int flush, int cache_file_idx) +struct mesa_mpls_hdr +{ +#if __BYTE_ORDER == __LITTLE_ENDIAN + unsigned short mpls_label_low; + unsigned char mpls_bls : 1; /* bottom of label stack */ + unsigned char mpls_exp : 3; + unsigned char mpls_label_high : 4; + unsigned char mpls_ttl; +#elif __BYTE_ORDER == __BIG_ENDIAN + unsigned char mpls_ttl; + unsigned char mpls_label_high : 4; + unsigned char mpls_exp : 3; + unsigned char mpls_bls : 1; /* bottom of label stack */ + unsigned short mpls_label_low; +#else +#error "Please check " +#endif +}; + +struct mesa_pppoe_session_hdr +{ +#if __BYTE_ORDER == __LITTLE_ENDIAN + unsigned int ver : 4; + unsigned int type : 4; +#elif __BYTE_ORDER == __BIG_ENDIAN + unsigned int type : 4; + unsigned int ver : 4; +#else +#error "Please check " +#endif + unsigned char code; + unsigned short session_id; + unsigned short len; + /* to do: + pppӦõΪһ, Ϊ˼򻯴, ǿƽPPPOE_SESһ, + ҪPPPЭ̹, ˽ṹҪĶ. + */ + unsigned short ppp_protocol; +} __attribute__((packed, aligned(1))); + +#define PPP_PROTOCOL_IPv4 (0x0021) + +static const u_char *find_iphdr(const u_char *pkt, size_t pktlen, const u_char *this_layer_data, u_short this_layer_type) +{ + if (pkt == NULL || pktlen <= 0 || this_layer_data == NULL) + { + return NULL; + } + if(this_layer_data - pkt >= pktlen) + { + return NULL; + } + u_short proto_type = 0; + struct mesa_mpls_hdr *this_mpls_hdr = NULL; + struct mesa_pppoe_session_hdr * ppp_hdr= NULL; + + switch (this_layer_type) + { + + case ETH_P_IP: + case ETH_P_IPV6: + return this_layer_data; + + case ETH_P_8021Q: + proto_type = *((unsigned short *)((char *)this_layer_data + 2)); + return find_iphdr(pkt, pktlen, this_layer_data + 4, ntohs(proto_type)); + + case ETH_P_MPLS_UC: + this_mpls_hdr = (struct mesa_mpls_hdr *)this_layer_data; + if (1 != this_mpls_hdr->mpls_bls) + { + return find_iphdr(pkt, pktlen, this_layer_data + 4, ETH_P_MPLS_UC); + } + else + { + return this_layer_data+4; + } + + case ETH_P_PPP_SES: + ppp_hdr = (struct mesa_pppoe_session_hdr *)this_layer_data; + if (PPP_PROTOCOL_IPv4 == ntohs(ppp_hdr->ppp_protocol)) + { + return this_layer_data+8; + } + default: + break; + } + return NULL; +} + + int stream_burst(sendpacket_t *sp, const u_char *pkt, size_t pktlen, int flush, int cache_file_idx) { u_char *pdata; MESA_fixed_qelem_t *q_obj; @@ -1435,9 +1526,11 @@ int stream_burst(sendpacket_t *sp, const u_char *pkt, size_t pktlen, int flush, } process_bar_print(pktlen, options.files[cache_file_idx]); - - struct ip *iphdr = (struct ip *)(pkt + 14); + //struct ip *iphdr = (struct ip *)(pkt + 14); + struct ethhdr * eth = (struct ethhdr *)pkt; + struct ip *iphdr = NULL; + if(1 == flush) /* ԭʼѶ, ǿˢ¶ʣݰ */ { if(options.pkt_distance > 0) @@ -1456,6 +1549,21 @@ int stream_burst(sendpacket_t *sp, const u_char *pkt, size_t pktlen, int flush, return 0; } + if(pkt != NULL && pktlen > 14) + { + iphdr=find_iphdr(pkt, pktlen, (pkt + 14), ntohs(eth->h_proto)); + } + + if (iphdr == NULL) + { + if ((options.stream_multiple != 0) && (options.verbose != 0)) + { + fprintf(stderr, "Not support encap pkt, cannot find iphdr%d\n"); + } + return -1; + } + + /* ֧TCPUDP, GRE, IPinIPЭ */ if((iphdr->ip_p != IPPROTO_TCP) && (iphdr->ip_p != IPPROTO_UDP) @@ -1480,7 +1588,7 @@ int stream_burst(sendpacket_t *sp, const u_char *pkt, size_t pktlen, int flush, for(i = 0; i < options.stream_multiple; i++) { memcpy(pbuf, pkt, pktlen); - stream_edit_addr(pbuf, i+1); + stream_edit_addr(pbuf, i+1, iphdr); MESA_fixed_q_join_tail(&pkt_queue[i], pbuf, pktlen); } @@ -1501,8 +1609,8 @@ int stream_burst(sendpacket_t *sp, const u_char *pkt, size_t pktlen, int flush, /* ûа, ֱӷNݰ */ for(i = 0; i < options.stream_multiple; i++) { - //memcpy(pbuf, pkt, pktlen); - //stream_edit_addr(pbuf, i+1); /* ںڲ޸İͷIP */ + memcpy(pbuf, pkt, pktlen); + stream_edit_addr(pbuf, i+1, iphdr); /* ںڲ޸İͷIP */ stream_burst_send_pkt(sp, pkt, pktlen); pkts_sent ++; bytes_sent += pktlen;