日本好好热aⅴ|国产99视频精品免费观看|日本成人aV在线|久热香蕉国产在线

  • <cite id="ikgdy"><table id="ikgdy"></table></cite>
    1. 西西軟件園多重安全檢測(cè)下載網(wǎng)站、值得信賴的軟件下載站!
      軟件
      軟件
      文章
      搜索

      首頁(yè)編程開(kāi)發(fā)其它知識(shí) → linux環(huán)境下數(shù)據(jù)包回放工具--pplayer分享

      linux環(huán)境下數(shù)據(jù)包回放工具--pplayer分享

      前往專題相關(guān)軟件相關(guān)文章發(fā)表評(píng)論 來(lái)源:西西整理時(shí)間:2013/5/10 22:29:18字體大。A-A+

      作者:道阻且長(zhǎng)點(diǎn)擊:76次評(píng)論:2次標(biāo)簽: linux

      pplayer(packet player)是我寫的一款小工具,支持主流協(xié)議,專門用來(lái)測(cè)試IPS和防火墻設(shè)備,經(jīng)長(zhǎng)時(shí)間驗(yàn)證,簡(jiǎn)單可靠,故發(fā)布。

      程序的原理很簡(jiǎn)單,首先加載pcap包中的數(shù)據(jù)包,保存在內(nèi)存中,然后在回放環(huán)境中回放數(shù)據(jù)包。

      拓?fù)洌?/p>

       

      原理:

        防火墻的兩個(gè)網(wǎng)卡和linux pc的兩個(gè)網(wǎng)卡分別對(duì)接形成環(huán)路,pplayer程序運(yùn)行在linux pc中。

        1,加載pcap文件中網(wǎng)路數(shù)據(jù)包,識(shí)別出數(shù)據(jù)包發(fā)送方向(client to server or server to client)

        2,修改數(shù)據(jù)包內(nèi)容(源/目的ip地址,校驗(yàn)和)

        3,按順序發(fā)送數(shù)據(jù)包,同時(shí)接收數(shù)據(jù)包

        4,打印log,提示發(fā)送和接收情況,回放完畢。

      使用方法:

        pplayer -f filename [ -t time] | [-m] | [-v ipversion] | [-p portnum] 

      可用參數(shù):

        -f:  必選,參數(shù)是pcap文件名。

        -t:  可選,參數(shù)是等待接收一個(gè)已發(fā)送的數(shù)據(jù)報(bào)的時(shí)間;如不選默認(rèn)30(微秒)。

        -m: 可選,理想情況下pcap包中只包含兩個(gè)ip地址的數(shù)據(jù)包,但是如果存在第3方或3個(gè)以上ip地址,就形成了若干的回放關(guān)系。

          默認(rèn)情況下,只選擇數(shù)據(jù)包數(shù)量最多得一對(duì)ip進(jìn)行回放。如需回放其他ip對(duì)的數(shù)據(jù)包,需要使用-m參數(shù),會(huì)以ip對(duì)為順序來(lái)回放數(shù)據(jù)包。

        -v: 可選,4或6, 回放IPV4/6數(shù)據(jù)包, 默認(rèn)4. 

        -p: 可選,選擇只回放指定端口的數(shù)據(jù)包,例如,指定回訪HTTP包, -p 80。

        另外pplayer支持nat環(huán)境回放,使用方法見(jiàn)下面配置文件。

      舉例:

        1,./pplayer -f http.pcap(回放http.pcap的數(shù)據(jù)包)

        2, ./pplayer -f http.pcap -v 6 (回放http.pcap的數(shù)據(jù)包,數(shù)據(jù)包格式是ipv6)

        3,./pplayer -f http.pcap -v 6 -t 50 (回放http.pcap的數(shù)據(jù)包,數(shù)據(jù)包格式是ipv6, 每個(gè)數(shù)據(jù)包的等待接收時(shí)間設(shè)為50微秒)


      配置文件:

        配置名是conf,和pplayer程序在同一目錄下。

      格式:
        device1:eth0
        device2:eth1
        device1ip:1.1.1.1
        device2ip:2.2.2.2
        device1nat:3.3.3.3
        device2nat:4.4.4.4
        fwmac1:00:0C:29:25:63:6E
        fwmac2:00:0C:29:25:63:78

      注:冒號(hào)后面緊接內(nèi)容,不能有空格或換行

        1.device1和device2表示linxu pc的兩個(gè)網(wǎng)卡

        2.device1ip和device2ip表示linux pc的兩個(gè)網(wǎng)卡的ip地址

        3.device1nat和device2nat是用來(lái)支持nat環(huán)境回放的。

          例如:設(shè)備1的ip是1.1.1.1,設(shè)備1處于nat環(huán)境,轉(zhuǎn)換后的ip是3.3.3.3;

          設(shè)備2的ip是2.2.2.2,設(shè)備2處于nat環(huán)境,轉(zhuǎn)換后的ip是4.4.4.4;

          如果設(shè)備不處于nat環(huán)境之中,對(duì)應(yīng)的nat配置項(xiàng)填0.0.0.0(ipv6的填::)

      并發(fā)/批量回放:

        目前pplayer只支持一次回放一個(gè)IP對(duì),一次只能回放一個(gè)pcap文件,不支持并發(fā)和批量回放這兩種功能,后續(xù)我可能會(huì)以shell腳本調(diào)用pplayer的方式實(shí)現(xiàn)

        這兩個(gè)功能。

      核心代碼:

      void LoadPacket (const struct pcap_pkthdr *pcap_hdr, Trace *trace, Flow *flow, const u_char * data, int pkt_id)
      {
          Packet *pkt = NULL;
          struct ether_header *ph = NULL;
          struct iphdr *iph = NULL;
          struct ip6_hdr *iph6 = NULL;
          struct tcphdr *tcph = NULL;
          struct udphdr *udph = NULL;
          if (flow->pkt_cap == 0) {
              flow->pkt_cap = 64;
              flow->pkt = calloc(64, sizeof(Packet));
          } else if (flow->pkt_num == flow->pkt_cap) {
              flow->pkt_cap += 64;
              flow->pkt = realloc(flow->pkt, (flow->pkt_cap) * sizeof(Packet));
          }
          pkt = &flow->pkt[flow->pkt_num]; 
          pkt->id = pkt_id;
          if (my_file.ipversion == 4) {
              iph = (struct iphdr *)(data + ETH_HLEN);
              int offset = (iph->ihl << 2) + ETH_HLEN;
              tcph = (struct tcphdr *)(data + offset);
              if (my_file.port != 0 &&
                  htons(my_file.port) != tcph->th_dport &&
                  htons(my_file.port) != tcph->th_sport) {
                  return;
              }
              pkt->len = pcap_hdr->caplen;//ntohs(iph->tot_len) + ETH_HLEN;
              pkt->buf = malloc(pkt->len + ETHER_CRC_LEN);
              memcpy(pkt->buf, data, pkt->len);
              iph = (struct iphdr *)(pkt->buf + ETH_HLEN);
          } else {
              iph6 = (struct ip6_hdr *)(data + ETH_HLEN);
              int offset = 40 + ETH_HLEN;
              tcph = (struct tcphdr *)(data + offset);
              if (my_file.port != 0 &&
                  htons(my_file.port) != tcph->th_dport &&
                  htons(my_file.port) != tcph->th_sport) {
                  return;
              }
              pkt->len = pcap_hdr->caplen;//ntohs(iph6->ip6_plen) + 40 + ETH_HLEN;
              pkt->buf = malloc(pkt->len + ETHER_CRC_LEN);
              memcpy(pkt->buf, data, pkt->len);
              iph6 = (struct ip6_hdr *)(pkt->buf + ETH_HLEN);
          }
          flow->pkt_num ++;
          trace->total_pkt_num ++;
      
          if (my_file.ipversion == 4) {
              if (iph->saddr == flow->sv4) {
                  if (my_file.device2_in_nat) {
                      iph->saddr = interface.sv4;
                      iph->daddr = interface.device2nat4;
                  } else {
                      iph->saddr = interface.sv4;
                      iph->daddr = interface.dv4;
                  }
                  pkt->interface = 1;
              } else {
                  if (my_file.device1_in_nat) {
                      iph->daddr = interface.device1nat4;
                      iph->saddr = interface.dv4;
                  } else {
                      iph->daddr = interface.sv4;
                      iph->saddr = interface.dv4;
                  }
                  pkt->interface = 2;
              }
          } else {
              if (!memcmp(&iph6->ip6_src, flow->sv6, 16)) {
                  if (my_file.device2_in_nat) {
                      memcpy(&iph6->ip6_src, interface.sv6, 16);
                      memcpy(&iph6->ip6_dst, interface.device2nat6, 16);    
                  } else {
                      memcpy(&iph6->ip6_src, interface.sv6, 16);
                      memcpy(&iph6->ip6_dst, interface.dv6, 16);
                  }
                  pkt->interface = 1;
              } else {
                  if (my_file.device1_in_nat) {
                      memcpy(&iph6->ip6_src, interface.device1nat6, 16);
                      memcpy(&iph6->ip6_dst, interface.sv6, 16);
                  } else {
                      memcpy(&iph6->ip6_src, interface.dv6, 16);
                      memcpy(&iph6->ip6_dst, interface.sv6, 16);
                  }
                  pkt->interface = 2;
              }
          }
      
          if (my_file.ipversion == 4) {
              ip_csum(iph);
              if ((iph->frag_off & htons(0x1fff)) == 0) {
                  int offset = (iph->ihl << 2) + ETH_HLEN;
                  if (iph->protocol == IPPROTO_TCP) {
                      tcp_csum(iph, pkt->buf + offset);
                  } else if (iph->protocol == IPPROTO_UDP) {
                      udph = (struct udphdr *)(pkt->buf + offset);
                      if (udph->uh_sum != 0) {
                          udp_csum(iph, (uint8_t *)udph);
                      }
                  }
              }
          } else {
              int offset = 40 + ETH_HLEN;
              if (iph6->ip6_nxt == IPPROTO_TCP) {
                  tcp_csum6(iph6, pkt->buf + offset, pkt->id);
              } else if (iph6->ip6_nxt == IPPROTO_UDP) {
                  udp_csum6(iph6, pkt->buf + offset, pkt->id);
              }
          }
          /*
           * Rewrite the mac addresses on the packet.
           */
          ph = (struct ether_header *)pkt->buf;
          if (pkt->interface == 1) {
              ph->ether_shost[0] = interface.device1_mac[0];
              ph->ether_shost[1] = interface.device1_mac[1];
              ph->ether_shost[2] = interface.device1_mac[2];
              ph->ether_shost[3] = interface.device1_mac[3];
              ph->ether_shost[4] = interface.device1_mac[4];
              ph->ether_shost[5] = interface.device1_mac[5];
              
              ph->ether_dhost[0] = interface.fw_mac1[0];
              ph->ether_dhost[1] = interface.fw_mac1[1];
              ph->ether_dhost[2] = interface.fw_mac1[2];
              ph->ether_dhost[3] = interface.fw_mac1[3];
              ph->ether_dhost[4] = interface.fw_mac1[4];
              ph->ether_dhost[5] = interface.fw_mac1[5];
          } else {
              ph->ether_dhost[0] = interface.fw_mac2[0];
              ph->ether_dhost[1] = interface.fw_mac2[1];
              ph->ether_dhost[2] = interface.fw_mac2[2];
              ph->ether_dhost[3] = interface.fw_mac2[3];
              ph->ether_dhost[4] = interface.fw_mac2[4];
              ph->ether_dhost[5] = interface.fw_mac2[5];
              
              ph->ether_shost[0] = interface.device2_mac[0];
              ph->ether_shost[1] = interface.device2_mac[1];
              ph->ether_shost[2] = interface.device2_mac[2];
              ph->ether_shost[3] = interface.device2_mac[3];
              ph->ether_shost[4] = interface.device2_mac[4];
              ph->ether_shost[5] = interface.device2_mac[5];
          } 
          /* Compute the FCS on the Ethernet Frame
           * Some people say the hardare should do this, but it does not seem to.
           * Also for packets > 1510, the WriteInterface dies with a message too long error
           */
          /*
           * This section actually calculates the FCS, but it's not currently
           * working correctly, so I've commented it out.  The CRC32 function
           * needs to be verified.
           */
          /*
         if ( pkt->len <= 15 + ETH_HLEN ) {
              uint32_t newFCS = CRC32( pkt->buf , pkt->len );
              memcpy(pkt->buf + pkt->len , &newFCS , ETHER_CRC_LEN);
          }
          */
      }

      可用版本: 

      紅帽9       http://pan.baidu.com/share/link?shareid=550929&uk=85241834

      fedora15 http://pan.baidu.com/share/link?shareid=550933&uk=85241834

      cenos5.5 http://pan.baidu.com/share/link?shareid=550937&uk=85241834

        相關(guān)評(píng)論

        閱讀本文后您有什么感想? 已有人給出評(píng)價(jià)!

        • 8 喜歡喜歡
        • 3 頂
        • 1 難過(guò)難過(guò)
        • 5 囧
        • 3 圍觀圍觀
        • 2 無(wú)聊無(wú)聊

        熱門評(píng)論

        最新評(píng)論

        發(fā)表評(píng)論 查看所有評(píng)論(2)

        昵稱:
        表情: 高興 可 汗 我不要 害羞 好 下下下 送花 屎 親親
        字?jǐn)?shù): 0/500 (您的評(píng)論需要經(jīng)過(guò)審核才能顯示)