summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author杨威 <[email protected]>2019-08-02 17:09:45 +0800
committer杨威 <[email protected]>2019-08-02 17:09:45 +0800
commitbfc450bfe656bd7e2a70fffcbce4182a784cca99 (patch)
tree03d538ed2dac556c6574cd1f645785cc4cb0911b
parent45c2c51968333f0ddc44fa5d59890fd732d1792a (diff)
parent55d028fcd35b92dd98d767df18a5905a2f1951c7 (diff)
Merge branch 'Feature-support-vlan-ppp-mpls-encap-pkt' into 'master'
支持更多的封装包格式回放,以及新增辅助编译脚本 See merge request common_tools/tcp_burst!3
-rw-r--r--.gitignore1
-rwxr-xr-xbuild.sh3
-rwxr-xr-xclean.sh2
-rw-r--r--src/tcpreplay.c128
4 files changed, 124 insertions, 10 deletions
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 <endian.h>"
+#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 <endian.h>"
+#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;
+ }
+
+
/* ֧��TCP��UDP, 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;