فهرست منبع

Merge pull request #45 from liu2guang/master

【更新】更新抓包工具
朱天龙 (Armink) 5 سال پیش
والد
کامیت
771bb0f4ba
1فایلهای تغییر یافته به همراه87 افزوده شده و 40 حذف شده
  1. 87 40
      tcpdump/tcpdump.c

+ 87 - 40
tcpdump/tcpdump.c

@@ -98,14 +98,29 @@ do {                                                            \
     (_head)->linktype = LINKTYPE_ETHERNET;                      \
 } while (0)
 
+#define PACP_ZERO_PKTHDR_CREATE(_head, _len)                    \
+do{                                                             \
+    (_head)->ts.tv_sec = 0;                                     \
+    (_head)->ts.tv_usec = 0;                                    \
+    (_head)->caplen = _len;                                     \
+    (_head)->len = _len;                                        \
+} while (0)
+
 #define PACP_PKTHDR_CREATE(_head, _p)                           \
 do{                                                             \
-    (_head)->ts.tv_sec = rt_tick_get() / RT_TICK_PER_SECOND;    \
-    (_head)->ts.tv_msec = rt_tick_get() % RT_TICK_PER_SECOND;   \
+    (_head)->ts.tv_sec = _p->tick / 1000;                       \
+    (_head)->ts.tv_usec = (_p->tick % 1000) * 1000;             \
     (_head)->caplen = _p->tot_len;                              \
     (_head)->len = _p->tot_len;                                 \
 } while (0)
 
+struct tcpdump_buf
+{
+    rt_uint16_t tot_len; 
+    rt_tick_t tick; 
+    void *buf; 
+}; 
+
 struct rt_pcap_file_header
 {
     rt_uint32_t magic;
@@ -120,7 +135,7 @@ struct rt_pcap_file_header
 struct rt_timeval
 {
     rt_uint32_t tv_sec;
-    rt_uint32_t tv_msec;
+    rt_uint32_t tv_usec;
 };
 
 struct rt_pcap_pkthdr
@@ -189,15 +204,22 @@ static void hex_dump(const rt_uint8_t *ptr, rt_size_t buflen)
 /* get tx data */
 static err_t _netif_linkoutput(struct netif *netif, struct pbuf *p)
 {
+    // pbuf->payload + sizeof(struct tcpdump_buf)
+    struct tcpdump_buf *tbuf = (struct tcpdump_buf *)rt_malloc(p->tot_len+sizeof(struct tcpdump_buf));
+
+    RT_ASSERT(tbuf != RT_NULL);
     RT_ASSERT(netif != RT_NULL);
 
+    tbuf->tick = rt_tick_get(); 
+    tbuf->buf = ((rt_uint8_t *)tbuf) + sizeof(struct tcpdump_buf); 
+    tbuf->tot_len = p->tot_len; 
+    pbuf_copy_partial(p, tbuf->buf, p->tot_len, 0);
+
     if (p != RT_NULL)
     {
-        pbuf_ref(p);
-
-        if (rt_mb_send(tcpdump_mb, (rt_uint32_t)p) != RT_EOK)
+        if (rt_mb_send(tcpdump_mb, (rt_uint32_t)tbuf) != RT_EOK)
         {
-            pbuf_free(p);
+            rt_free(tbuf); 
         }
     }
     return link_output(netif, p);
@@ -206,14 +228,22 @@ static err_t _netif_linkoutput(struct netif *netif, struct pbuf *p)
 /* get rx data */
 static err_t _netif_input(struct pbuf *p, struct netif *inp)
 {
-    RT_ASSERT(inp != RT_NULL);
+    // pbuf->payload + sizeof(struct tcpdump_buf)
+    struct tcpdump_buf *tbuf = (struct tcpdump_buf *)rt_malloc(p->tot_len+sizeof(struct tcpdump_buf));
+
+    RT_ASSERT(tbuf != RT_NULL);
+    RT_ASSERT(netif != RT_NULL);
+
+    tbuf->tick = rt_tick_get(); 
+    tbuf->buf = ((rt_uint8_t *)tbuf) + sizeof(struct tcpdump_buf); 
+    tbuf->tot_len = p->tot_len; 
+    pbuf_copy_partial(p, tbuf->buf, p->tot_len, 0);
 
     if (p != RT_NULL)
     {
-        pbuf_ref(p);
-        if (rt_mb_send(tcpdump_mb, (rt_uint32_t)p) != RT_EOK)
+        if (rt_mb_send(tcpdump_mb, (rt_uint32_t)tbuf) != RT_EOK)
         {
-            pbuf_free(p);
+            rt_free(tbuf); 
         }
     }
     return input(p, inp);
@@ -230,13 +260,13 @@ static rt_err_t rt_tcpdump_pcap_file_write(const void *buf, int len)
         return -RT_ERROR;
     }
 
-    if ((len == 0) && (fd > 0))
-    {
-        dbg_log(DBG_ERROR, "ip mess error and close file!\n");
-        close(fd);
-        fd = -1;
-        return -RT_ERROR;
-    }
+    // if ((len == 0) && (fd > 0))
+    // {
+    //     dbg_log(DBG_ERROR, "ip mess error and close file! len = %d, fd = %d\n", len, fd);
+    //     close(fd);
+    //     fd = -1;
+    //     return -RT_ERROR;
+    // }
 
     if (fd < 0)
     {
@@ -267,23 +297,22 @@ static rt_err_t rt_tcpdump_pcap_file_save(const void *buf, int len)
 }
 
 /* write ip mess and print */
-static void rt_tcpdump_ip_mess_write(struct pbuf *p)
+static void rt_tcpdump_ip_mess_write(struct tcpdump_buf *p)
 {
-    rt_uint8_t *buf = (rt_uint8_t *)rt_malloc(p->tot_len);
-
-    RT_ASSERT(buf != RT_NULL);
+    struct tcpdump_buf *tbuf = p; 
 
-    pbuf_copy_partial(p, buf, p->tot_len, 0);
+    RT_ASSERT(tbuf != RT_NULL);
 
 #ifdef PKG_NETUTILS_TCPDUMP_PRINT
-    hex_dump(buf, p->tot_len);
+    hex_dump(tbuf->buf, tbuf->tot_len);
 #endif
 
     /* write ip mess */
     if (tcpdump_write != RT_NULL)
-        tcpdump_write(buf, p->tot_len);
-
-    rt_free(buf);
+    {
+        // rt_kprintf("tbuf->tot_len = %d\n", tbuf->tot_len); 
+        tcpdump_write(tbuf->buf, tbuf->tot_len);
+    }
 }
 
 /* write pcap file header */
@@ -304,8 +333,23 @@ static rt_err_t rt_tcpdump_pcap_file_init(void)
     /* in rdb mode does not need to write pcap file header */
     if ((tcpdump_write != RT_NULL) && (tcpdump_write == rt_tcpdump_pcap_file_write))
     {
+        struct rt_pcap_pkthdr pkthdr;
+
+        /* pcap header */
         PACP_FILE_HEADER_CREATE(&file_header);
         res = tcpdump_write(&file_header, sizeof(file_header));
+
+        /* Positioning at time zero */ 
+        char pacp_zero[] = 
+        {
+            0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 
+            0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 
+            0x08, 0x00, 
+            ' ', ' ', 'R', 'T', 'T', 'H', 'R', 'E', 'A', 'D', ' ', 'Z', 'E', 'R', 'O' 
+        }; 
+        PACP_ZERO_PKTHDR_CREATE(&pkthdr, sizeof(pacp_zero)); 
+        tcpdump_write(&pkthdr, sizeof(pkthdr));
+        tcpdump_write(pacp_zero, sizeof(pacp_zero)); 
     }
 
 #ifdef  PKG_NETUTILS_TCPDUMP_PRINT
@@ -320,30 +364,31 @@ static rt_err_t rt_tcpdump_pcap_file_init(void)
 
 static void rt_tcpdump_thread_entry(void *param)
 {
-    struct pbuf *pbuf = RT_NULL;
+    // struct pbuf *pbuf = RT_NULL;
+    struct tcpdump_buf *tbuf = RT_NULL; 
     struct rt_pcap_pkthdr pkthdr;
     rt_uint32_t mbval;
 
     while (1)
     {
-        if (rt_mb_recv(tcpdump_mb, &mbval, RT_WAITING_FOREVER) == RT_EOK)
+        if (rt_mb_recv(tcpdump_mb, (rt_ubase_t *)&mbval, RT_WAITING_FOREVER) == RT_EOK)
         {
-            pbuf = (struct pbuf *)mbval;
-            RT_ASSERT(pbuf != RT_NULL);
+            tbuf = (struct tcpdump_buf *)mbval;
+            RT_ASSERT(tbuf != RT_NULL);
 
             /* write pkthdr */
             if ((tcpdump_write != RT_NULL) && (tcpdump_write == rt_tcpdump_pcap_file_write))
             {
-                PACP_PKTHDR_CREATE(&pkthdr, pbuf);
+                PACP_PKTHDR_CREATE(&pkthdr, tbuf);
                 tcpdump_write(&pkthdr, sizeof(pkthdr));
             }
 
 #ifdef  PKG_NETUTILS_TCPDUMP_PRINT
             hex_dump((rt_uint8_t *)&pkthdr, PCAP_PKTHDR_SIZE);
 #endif
-            rt_tcpdump_ip_mess_write(pbuf);
-            pbuf_free(pbuf);
-            pbuf = RT_NULL;
+            rt_tcpdump_ip_mess_write(tbuf);
+            rt_free(tbuf);
+            tbuf = RT_NULL;
         }
 
         /* tcpdump deinit, the mailbox does not receive the data, exits the thread*/
@@ -478,7 +523,8 @@ static int rt_tcpdump_init(void)
 static void rt_tcpdump_deinit(void)
 {
     rt_base_t level;
-
+    struct rt_mailbox *tcpdump_mb_tmp = RT_NULL;
+    
     if (netif == RT_NULL)
     {
         dbg_log(DBG_ERROR, "capture packet stopped, no repeat input required!\n");
@@ -487,14 +533,17 @@ static void rt_tcpdump_deinit(void)
 
     /* linkoutput and input deinit */
     level = rt_hw_interrupt_disable();
+    tcpdump_mb_tmp = tcpdump_mb; 
+    tcpdump_mb = RT_NULL;
     netif->linkoutput = link_output;
     netif->input = input;
     netif = RT_NULL;
     rt_hw_interrupt_enable(level);
     /* linkoutput and input deinit */
 
-    rt_mb_delete(tcpdump_mb);
-    tcpdump_mb = RT_NULL;
+    rt_thread_mdelay(10); 
+    rt_mb_delete(tcpdump_mb_tmp);
+    tcpdump_mb_tmp = RT_NULL; 
 }
 
 static void rt_tcpdump_help_info_print(void)
@@ -714,9 +763,7 @@ static int tcpdump_test(int argc, char *argv[])
     }
 
     rt_tcpdump_cmd_argv_deinit();
-
     res = rt_tcpdump_cmd_parse(argv, MSH_CMD);
-
     if (res == STOP)
         return RT_EOK;