1 /*
2  * Copyright (C) 2018 Alibaba Group Holding Limited
3  */
4 #include "lwip/opt.h"
5 #ifdef WITH_LWIP_PKTPRINT
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include "lwip/pbuf.h"
10 #include "lwip/debug.h"
11 #include "lwip/def.h"
12 #include "lwip/netif.h"
13 #if AOS_COMP_CLI
14 #include "aos/cli.h"
15 #endif
16 
17 #define IPHDR_LEN 20
18 #define TCPS_MAX  11
19 
20 /* IP packet type */
21 #define IPPROTO_ICMP    0x01
22 #define IPPROTO_IGMP    0x02
23 #define IPPROTO_TCP     0x06
24 #define IPPROTO_UDP     0x11
25 
26 /* port type */
27 #define PORT_DNS        0x35
28 #define PORT_DHCP_SRV   0x43
29 #define PORT_DHCP_CLT   0x44
30 
31 /* TCP packet state flag */
32 #define TCPF_SYN        0x02
33 #define TCPF_RST        0x04
34 #define TCPF_ACK        0x10
35 #define TCPF_FINACK     0x11
36 #define TCPF_SYNACK     0x12
37 #define TCPF_RSTACK     0x14
38 #define TCPF_PSHACK     0x18
39 #define TCPF_FINPSHACK  0x19
40 
41 /* ICMP packet type */
42 #define ICMP_TYPE_ECHO_REPLY    0x00
43 #define ICMP_TYPE_ECHO_REQST    0x08
44 
45 /* print buffer length */
46 #define PKT_INFO_BUFF_SIZE      80
47 
48 /* net layer type enum */
49 typedef enum
50 {
51     NL_NONE     = 0,
52     NL_IP4      = 1,
53     NL_IP6      = 2,
54     NL_MAX
55 } DBG_NET_E;
56 
57 /* transport layer type enum */
58 typedef enum
59 {
60     TL_NONE     = 0,
61     TL_ICMP     = 1,
62     TL_IGMP     = 2,
63     TL_TCP      = 3,
64     TL_UDP      = 4,
65     TL_MAX
66 } DBG_TRANS_E;
67 
68 /* sub-transport layer type enum */
69 typedef enum
70 {
71     STL_NONE            = 0,
72 
73     /* TCP subtype */
74     STL_TCP_SYN         = 1,
75     STL_TCP_SYNACK      = 2,
76     STL_TCP_ACK         = 3,
77     STL_TCP_PSHACK      = 4,
78     STL_TCP_FINPSHACK   = 5,
79     STL_TCP_FINACK      = 6,
80     STL_TCP_RSTACK      = 7,
81     STL_TCP_RST         = 8,
82 
83     /* UDP subtype */
84     STL_UDP_DHCPREQ     = 9,
85     STL_UDP_DHCPREP     = 10,
86     STL_UDP_DNS         = 11,
87     /* ICMP subtype */
88     STL_ICMP_PINGREQ    = 12,
89     STL_ICMP_PINGREP    = 13,
90     STL_MAX
91 } DBG_SUBTRANS_E;
92 
93 /* packet direction */
94 typedef enum
95 {
96    DIR_OUTGOING,
97    DIR_INCOMING,
98    DIR_ERROR
99 } DBG_DIR_E;
100 
101 /* IP4 packet info struct */
102 typedef struct
103 {
104     u8_t*   ip_src;
105     u8_t*   ip_dst;
106     u16_t   len;
107     u16_t   id;
108     u16_t   offset;
109     u8_t    hlen;
110     u8_t    type;
111     u8_t    ttl;
112     u8_t    padding[3];
113 } DBG_IP4_T;
114 
115 typedef struct
116 {
117 //tbd
118 } DBG_IP6_T;
119 
120 /* TCP packet info struct */
121 typedef struct
122 {
123     u16_t   port_src;
124     u16_t   port_dst;
125     u32_t   seq;
126     u32_t   ack;
127     u16_t   wnd;
128     u16_t   dlen;
129 } DBG_TCP_T;
130 
131 /* UDP packet info struct */
132 typedef struct
133 {
134     u16_t   port_src;
135     u16_t   port_dst;
136     u16_t   len;
137     u8_t    padding[2];
138 } DBG_UDP_T;
139 
140 /* ICMP packet info struct */
141 typedef struct
142 {
143     u8_t    type;
144     u8_t    code;
145     u16_t   id;
146     u16_t   seq;
147     u8_t    padding[2];
148 } DBG_ICMP_T;
149 
150 /* IGMP packet info struct */
151 
152 typedef struct
153 
154 {
155     u32_t   group_addr;
156     u8_t    type;
157     u8_t    padding[3];
158 } DBG_IGMP_T;
159 
160 /* packet info struct */
161 typedef struct pkt_info
162 {
163     DBG_NET_E      net;
164     DBG_TRANS_E    trans;
165     DBG_SUBTRANS_E subtrans;
166     u32_t       pkt_id;
167     union{
168         DBG_IP4_T   ip4;
169         DBG_IP6_T   ip6;
170     }nl;
171     union{
172         DBG_TCP_T  tcp;
173         DBG_UDP_T  udp;
174         DBG_ICMP_T icmp;
175         DBG_IGMP_T igmp;
176     }tl;
177 } DBG_PKT_INFO_T;
178 
179 /* net layer type, it should be matched with DBG_NET_E */
180 static char s_net_type[NL_MAX][8] =
181 {
182     "NONE",
183     "IP4",
184     "IP6",
185 };
186 
187 /* transport layer type, it should be matched with DBG_TRANS_E */
188 static char s_trans_type[TL_MAX][8] =
189 {
190     "NONE",
191     "ICMP",
192     "IGMP",
193     "TCP",
194     "UDP"
195 };
196 
197 /* sub-transport layer type, it should be matched with DBG_SUBTRANS_E */
198 static char s_subtrans_type[STL_MAX][16] =
199 {
200     "NONE",
201     /* TCP */
202     "TCP_SYN",
203     "TCP_SYNACK",
204     "TCP_ACK",
205     "TCP_PSHACK",
206     "TCP_FINPSHACK",
207     "TCP_FINACK",
208     "TCP_RSTACK",
209     "TCP_RST",
210     /* UDP */
211     "DHCP_BOOTREQ",
212     "DHCP_BOOTREP",
213     "DNS",
214     /* ICMP */
215     "ICMP_PINGREQ",
216     "ICMP_PINGREP"
217 };
218 
219 #if 0
220 //TODO: show more info about tcp state
221 /* TCP state */
222 static char s_tcp_state[TCPS_MAX][24] =
223 {
224     "TCPS_CLOSED",          // 0 - closed */
225     "TCPS_LISTEN",          // 1 - listening for connection */
226     "TCPS_SYN_SENT",        // 2 - active, have sent syn */
227     "TCPS_SYN_RECEIVED",    // 3 - have send and received syn */
228     // states < "TCPS_ESTABLISHED are those where connections not established
229     "TCPS_ESTABLISHED",     // 4 - established */
230     "TCPS_CLOSE_WAIT",      // 5 - rcvd fin, waiting for close */
231     // states > "TCPS_CLOSE_WAIT are those where user has closed
232     "TCPS_FIN_WAIT_1",      // 6 - have closed, sent fin */
233     "TCPS_CLOSING",         // 7 - closed xchd FIN; await FIN ACK */
234     "TCPS_LAST_ACK",        // 8 - had fin and close; await FIN ACK */
235     // states > "TCPS_CLOSE_WAIT && < "TCPS_FIN_WAIT_2 await ACK of FIN */
236     "TCPS_FIN_WAIT_2",      // 9 - have closed, fin is acked
237     "TCPS_TIME_WAIT"        // 10 - in 2*msl quiet wait after close */
238 };
239 #endif
240 
241 /* default: print all */
242 static int pktprint_debug_level = 1;
243 
244 /* pkt info stats */
245 struct pkt_stats_data g_stats_data = {0};
246 
247 /* how packet info that contain the specified port */
248 static int filter_flag = 0;
249 static int filter_port = 0;
250 
lwip_pkt_print(char * note_ptr,void * buf,void * net)251 void lwip_pkt_print(char* note_ptr, void *buf, void* net)
252 {
253     int  len = 0;
254     unsigned char* ptr = NULL;
255     DBG_PKT_INFO_T dbg_pkt_info;
256     struct pbuf *pbuf = (struct pbuf *) buf;
257     struct netif *netif = (struct netif *) net;
258     DBG_DIR_E direction = DIR_ERROR;
259 
260     if(pktprint_debug_level == 0) {
261         return ;
262     }
263 
264     if(pbuf == NULL){
265 	    return ;
266     }
267 
268     ptr = pbuf->payload;
269     len = pbuf->len;
270 
271     if( len <= IPHDR_LEN || NULL == ptr ){
272         return ;
273     }
274 
275     if(strcmp(note_ptr, "LwIP_send") == 0) {
276         direction = DIR_OUTGOING;
277     } else if(strcmp(note_ptr, "LwIP_recv") == 0) {
278         direction = DIR_INCOMING;
279     }
280 
281     /* reset filter flag */
282     filter_flag = 0;
283 
284     memset(&dbg_pkt_info, 0, sizeof(DBG_PKT_INFO_T));
285 
286     /* check if IP v4 header */
287     if( 0x40 == (ptr[0] & 0xF0) )
288     {
289         DBG_IP4_T* ip4_ptr = &(dbg_pkt_info.nl.ip4);
290         u8_t ip4_hlen = 0;
291         ip4_ptr->hlen = 4*(ptr[0] & 0x0F);
292         ip4_hlen = ip4_ptr->hlen;
293 
294         /* check IP header length */
295         if( len <= ip4_hlen ){
296             LWIP_DEBUGF(PKTPRINT_DEBUG, ("LwIP: PacketInfoIp() - invalid len %d < iplen %d\n", len, ip4_hlen));
297             return ;
298         }
299 
300         /* get IP packet information */
301         dbg_pkt_info.net = NL_IP4;
302         ip4_ptr->len = (u16_t)(256*ptr[2] + ptr[3]);
303         ip4_ptr->id = (u16_t)(256*ptr[4] + ptr[5]);
304         ip4_ptr->offset = 2064*(0x1F & ptr[6]) + 8*ptr[7];   /* 2064 = 256*8 */
305         ip4_ptr->type = ptr[9];
306         ip4_ptr->ip_src = (uint8_t*)(ptr + 12);
307         ip4_ptr->ip_dst = (uint8_t*)(ptr + 16);
308 
309         /* classify IP sub-type */
310         switch( ip4_ptr->type ){
311         // ICMP
312         case IPPROTO_ICMP:
313             dbg_pkt_info.trans = TL_ICMP;
314             dbg_pkt_info.subtrans = STL_NONE;
315             if( 0 == ip4_ptr->offset ){
316                 DBG_ICMP_T* icmp_ptr = &(dbg_pkt_info.tl.icmp);
317                 icmp_ptr->type = ptr[ip4_hlen];
318                 icmp_ptr->code = ptr[ip4_hlen + 1];
319                 switch( icmp_ptr->type ){
320                 case ICMP_TYPE_ECHO_REQST:
321                     dbg_pkt_info.subtrans = STL_ICMP_PINGREQ;
322                     icmp_ptr->id  = (u16_t)(256*ptr[ip4_hlen + 4] + ptr[ip4_hlen + 5]);
323                     icmp_ptr->seq = (u16_t)(256*ptr[ip4_hlen + 6] + ptr[ip4_hlen + 7]);
324                     break;
325                 case ICMP_TYPE_ECHO_REPLY:
326                     dbg_pkt_info.subtrans = STL_ICMP_PINGREP;
327                     icmp_ptr->id  = (u16_t)(256*ptr[ip4_hlen + 4] + ptr[ip4_hlen + 5]);
328                     icmp_ptr->seq = (u16_t)(256*ptr[ip4_hlen + 6] + ptr[ip4_hlen + 7]);
329                     break;
330                 default:
331                     icmp_ptr->id  = 0;
332                     icmp_ptr->seq = 0;
333                     break;
334                 }
335             }
336             break;
337         // IGMP
338         case IPPROTO_IGMP:
339             dbg_pkt_info.trans = TL_IGMP;
340             dbg_pkt_info.subtrans = STL_NONE;
341             if( 0 == ip4_ptr->offset ){
342                 DBG_IGMP_T* igmp_ptr = &(dbg_pkt_info.tl.igmp);
343                 igmp_ptr->type = ptr[ip4_hlen];
344                 igmp_ptr->group_addr = ntohl(*((u32_t*)(ptr + ip4_hlen + 4)));
345             }
346             break;
347         // TCP
348         case IPPROTO_TCP:
349             dbg_pkt_info.trans = TL_TCP;
350             dbg_pkt_info.subtrans = STL_NONE;
351             if( 0 == ip4_ptr->offset ){
352                 DBG_TCP_T* tcp_ptr = &(dbg_pkt_info.tl.tcp);
353                 tcp_ptr->port_src = (u16_t)(256*ptr[ip4_hlen]   + ptr[ip4_hlen+1]);
354                 tcp_ptr->port_dst = (u16_t)(256*ptr[ip4_hlen+2] + ptr[ip4_hlen+3]);
355                 tcp_ptr->seq = ntohl(*((u32_t*)(ptr+ip4_hlen+4)));
356                 tcp_ptr->ack = ntohl(*((u32_t*)(ptr+ip4_hlen+8)));
357                 tcp_ptr->dlen = (u16_t)(ip4_ptr->len - ip4_ptr->hlen - (ptr[ip4_hlen+12]>>2));
358                 tcp_ptr->wnd = (u16_t)(256*ptr[ip4_hlen+14] + ptr[ip4_hlen+15]);
359 
360                 switch( ptr[ip4_hlen+13] ){
361                 case TCPF_SYN:          dbg_pkt_info.subtrans = STL_TCP_SYN;          break;
362                 case TCPF_RST:          dbg_pkt_info.subtrans = STL_TCP_RST;          break;
363                 case TCPF_ACK:          dbg_pkt_info.subtrans = STL_TCP_ACK;
364                                         if(pktprint_debug_level == 1)
365                                         {
366                                             if((tcp_ptr->port_src != filter_port)
367                                               && (tcp_ptr->port_dst != filter_port))
368                                             {
369                                                 filter_flag = 1;
370                                             }
371                                         }
372                                                                                       break;
373                 case TCPF_FINACK:       dbg_pkt_info.subtrans = STL_TCP_FINACK;       break;
374                 case TCPF_SYNACK:       dbg_pkt_info.subtrans = STL_TCP_SYNACK;       break;
375                 case TCPF_RSTACK:       dbg_pkt_info.subtrans = STL_TCP_RSTACK;       break;
376                 case TCPF_PSHACK:       dbg_pkt_info.subtrans = STL_TCP_PSHACK;
377                                         if(pktprint_debug_level == 1)
378                                         {
379                                             if((tcp_ptr->port_src != filter_port)
380                                               && (tcp_ptr->port_dst != filter_port))
381                                             {
382                                                 filter_flag = 1;
383                                             }
384                                         }
385                                                                                       break;
386                 case TCPF_FINPSHACK:    dbg_pkt_info.subtrans = STL_TCP_FINPSHACK;    break;
387                 default:
388                     break;
389                 }
390             }
391             break;
392         // UDP
393         case IPPROTO_UDP:
394             dbg_pkt_info.trans = TL_UDP;
395             dbg_pkt_info.subtrans = STL_NONE;
396             if( 0 == ip4_ptr->offset ){
397                 DBG_UDP_T* udp_ptr = &(dbg_pkt_info.tl.udp);
398                 udp_ptr->port_src = (u16_t)(256*ptr[ip4_hlen]   + ptr[ip4_hlen+1]);
399                 udp_ptr->port_dst = (u16_t)(256*ptr[ip4_hlen+2] + ptr[ip4_hlen+3]);
400                 udp_ptr->len = (u16_t)(256*ptr[ip4_hlen+4] + ptr[ip4_hlen+5]);
401                 /* switch for source port */
402                 switch(udp_ptr->port_src){
403                 case PORT_DHCP_CLT: dbg_pkt_info.subtrans = STL_UDP_DHCPREQ;  break;
404                 case PORT_DHCP_SRV: dbg_pkt_info.subtrans = STL_UDP_DHCPREP;  break;
405                 case PORT_DNS:      dbg_pkt_info.subtrans = STL_UDP_DNS;      break;
406                 default:
407                     if((1 == pktprint_debug_level) && (udp_ptr->port_src != filter_port) && (udp_ptr->port_dst != filter_port))
408                     {
409                         filter_flag = 1;
410                     }
411                     break;
412                 }
413                 /* check type for dest port */
414                 if( PORT_DNS == udp_ptr->port_dst ){
415                     dbg_pkt_info.subtrans = STL_UDP_DNS;
416                     filter_flag = 0;
417                 }
418             }
419             break;
420         default:
421             dbg_pkt_info.trans = TL_NONE;
422             dbg_pkt_info.subtrans = STL_NONE;
423             break;
424 
425         }
426     }
427 
428     if(dbg_pkt_info.net == NL_IP4)
429     {
430         DBG_IP4_T *ip4_ptr = &(dbg_pkt_info.nl.ip4);
431         char * type_ptr = NULL;
432         char info_str[PKT_INFO_BUFF_SIZE] = {0};
433 
434         /* set type string */
435         if( STL_NONE != dbg_pkt_info.subtrans )
436         {
437            type_ptr = s_subtrans_type[dbg_pkt_info.subtrans];
438         }
439         else if( TL_NONE != dbg_pkt_info.trans )
440         {
441            type_ptr = s_trans_type[dbg_pkt_info.trans];
442         }
443         else
444         {
445            type_ptr = s_net_type[dbg_pkt_info.net];
446         }
447 
448         switch( dbg_pkt_info.net ) {
449            case NL_IP4:
450               if( 0 == ip4_ptr->offset )
451               {
452                  /* set packet info string by transportation type*/
453                  switch( dbg_pkt_info.trans )
454                  {
455                     case TL_ICMP:
456                     {
457                         DBG_ICMP_T* icmp_ptr = &(dbg_pkt_info.tl.icmp);
458                         snprintf(info_str, (PKT_INFO_BUFF_SIZE-1),
459                           "Type(%d), Code(%d), Id(%x), Seq(%x)",
460                            icmp_ptr->type, icmp_ptr->code, icmp_ptr->id, icmp_ptr->seq);
461                        if(direction == DIR_OUTGOING) {
462                            g_stats_data.tx_packets ++;
463                            g_stats_data.tx_bytes += ip4_ptr->len;
464                            g_stats_data.tx_other_packets ++;
465                            g_stats_data.tx_other_bytes += ip4_ptr->len;
466                        } else if(direction == DIR_INCOMING) {
467                            g_stats_data.rx_packets ++;
468                            g_stats_data.rx_bytes += ip4_ptr->len;
469                            g_stats_data.rx_other_packets ++;
470                            g_stats_data.rx_other_bytes += ip4_ptr->len;
471                        }
472                     }
473                     break;
474                     case TL_IGMP:
475                     {
476                         DBG_IGMP_T* igmp_ptr = &(dbg_pkt_info.tl.igmp);
477                         snprintf(info_str, (PKT_INFO_BUFF_SIZE-1),
478                           "Type(%d), GroupAddr(0x%08x)",
479                           igmp_ptr->type, (uint32_t)igmp_ptr->group_addr);
480                        if(direction == DIR_OUTGOING) {
481                            g_stats_data.tx_packets ++;
482                            g_stats_data.tx_bytes += ip4_ptr->len;
483                            g_stats_data.tx_other_packets ++;
484                            g_stats_data.tx_other_bytes += ip4_ptr->len;
485                        } else if(direction == DIR_INCOMING) {
486                            g_stats_data.rx_packets ++;
487                            g_stats_data.rx_bytes += ip4_ptr->len;
488                            g_stats_data.rx_other_packets ++;
489                            g_stats_data.rx_other_bytes += ip4_ptr->len;
490                        }
491                     }
492                     break;
493                     case TL_TCP:
494                     {
495                        DBG_TCP_T* tcp_ptr = &(dbg_pkt_info.tl.tcp);
496                        snprintf(info_str, (PKT_INFO_BUFF_SIZE-1),
497                         "S:%x, A:%x, W:%d, l:%d, %d -> %d",
498                         tcp_ptr->seq, tcp_ptr->ack, tcp_ptr->wnd,
499                         tcp_ptr->dlen, tcp_ptr->port_src, tcp_ptr->port_dst);
500                        if(direction == DIR_OUTGOING) {
501                            g_stats_data.tx_packets ++;
502                            g_stats_data.tx_bytes += ip4_ptr->len;
503                            g_stats_data.tx_tcp_packets ++;
504                            g_stats_data.tx_tcp_bytes += ip4_ptr->len;
505                        } else if(direction == DIR_INCOMING) {
506                            g_stats_data.rx_packets ++;
507                            g_stats_data.rx_bytes += ip4_ptr->len;
508                            g_stats_data.rx_tcp_packets ++;
509                            g_stats_data.rx_tcp_bytes += ip4_ptr->len;
510                        }
511                     }
512                     break;
513                     case TL_UDP:
514                     {
515                         DBG_UDP_T* udp_ptr = &(dbg_pkt_info.tl.udp);
516                         snprintf(info_str, (PKT_INFO_BUFF_SIZE-1),
517                           "%d -> %d", udp_ptr->port_src, udp_ptr->port_dst);
518                        if(direction == DIR_OUTGOING) {
519                            g_stats_data.tx_packets ++;
520                            g_stats_data.tx_bytes += ip4_ptr->len;
521                            g_stats_data.tx_udp_packets ++;
522                            g_stats_data.tx_udp_bytes += ip4_ptr->len;
523                        } else if(direction == DIR_INCOMING) {
524                            g_stats_data.rx_packets ++;
525                            g_stats_data.rx_bytes += ip4_ptr->len;
526                            g_stats_data.rx_udp_packets ++;
527                            g_stats_data.rx_udp_bytes += ip4_ptr->len;
528                        }
529                     }
530                     break;
531                     default:
532                        //error
533                     break;
534                 }
535                 if((pktprint_debug_level == 2)||((pktprint_debug_level == 1)&&(filter_flag == 0)))
536                 {
537                     LWIP_DEBUGF(PKTPRINT_DEBUG, ("[ LwIP ] %s, pkt:%p, netif(%p), %u.%u.%u.%u -> %u.%u.%u.%u IPID(%x), %s, %s(%d)\n",
538                     note_ptr, pbuf, netif,
539                     ip4_ptr->ip_src[0],
540                     ip4_ptr->ip_src[1],
541                     ip4_ptr->ip_src[2],
542                     ip4_ptr->ip_src[3],
543                     ip4_ptr->ip_dst[0],
544                     ip4_ptr->ip_dst[1],
545                     ip4_ptr->ip_dst[2],
546                     ip4_ptr->ip_dst[3],
547                     ip4_ptr->id, info_str,
548                     type_ptr, ip4_ptr->len));
549                 }
550             }
551             else
552             {
553                 if(pktprint_debug_level)
554                 {
555                     LWIP_DEBUGF(PKTPRINT_DEBUG, ("[ LwIP ] %s, pkt:%p, netif(%p), %u.%u.%u.%u -> %u.%u.%u.%u IPID(%x), FRAG_OFFSET(%d), %s(%d)\n",
556                     note_ptr, pbuf, netif,
557                     ip4_ptr->ip_src[0],
558                     ip4_ptr->ip_src[1],
559                     ip4_ptr->ip_src[2],
560                     ip4_ptr->ip_src[3],
561                     ip4_ptr->ip_dst[0],
562                     ip4_ptr->ip_dst[1],
563                     ip4_ptr->ip_dst[2],
564                     ip4_ptr->ip_dst[3],
565                     ip4_ptr->id, ip4_ptr->offset,
566                    type_ptr, ip4_ptr->len));
567                 }
568             }
569             break;
570             case NL_NONE:
571             default:
572                if(pktprint_debug_level)
573                {
574                     LWIP_DEBUGF(PKTPRINT_DEBUG, ("[ LwIP ] %s, pkt:%p, netif(%p), %u.%u.%u.%u -> %u.%u.%u.%u UNKNOWN TYPE(%d)\n",
575                     note_ptr, pbuf, netif,
576                     ip4_ptr->ip_src[0],
577                     ip4_ptr->ip_src[1],
578                     ip4_ptr->ip_src[2],
579                     ip4_ptr->ip_src[3],
580                     ip4_ptr->ip_dst[0],
581                     ip4_ptr->ip_dst[1],
582                     ip4_ptr->ip_dst[2],
583                     ip4_ptr->ip_dst[3],
584                    pbuf->len));
585                }
586            break;
587 
588       }
589    }
590 }
591 
_cli_pktprint_help_command(void)592 void _cli_pktprint_help_command(void)
593 {
594     LWIP_DEBUGF(PKTPRINT_DEBUG, ("Usage: pktprint  [debug_level]\n"));
595     LWIP_DEBUGF(PKTPRINT_DEBUG, ("       pktprint  [-h]\n"));
596     LWIP_DEBUGF(PKTPRINT_DEBUG, ("  -h,        Show help\n"));
597     LWIP_DEBUGF(PKTPRINT_DEBUG, ("  The specified port pkt print is supported in level 1:\n"));
598     LWIP_DEBUGF(PKTPRINT_DEBUG, ("  -p,        Show packet info that contain the specified port\n"));
599     LWIP_DEBUGF(PKTPRINT_DEBUG, ("  -g,        Get the specified port that is to show packet info\n"));
600     LWIP_DEBUGF(PKTPRINT_DEBUG, ("  -c,        Clear the specified port packet print setting \n"));
601     LWIP_DEBUGF(PKTPRINT_DEBUG, ("  -s,        Show pkt_print debug level\n"));
602     LWIP_DEBUGF(PKTPRINT_DEBUG, ("  -t,        Set pkt_print debug level\n"));
603     LWIP_DEBUGF(PKTPRINT_DEBUG, ("  -i,        Show pkt stats information\n"));
604     LWIP_DEBUGF(PKTPRINT_DEBUG, ("  level value:\n"));
605     LWIP_DEBUGF(PKTPRINT_DEBUG, ("  0,         No pkt print\n"));
606     LWIP_DEBUGF(PKTPRINT_DEBUG, ("  1,         Print syn/synack/rst/finack/finpshack/sepcified port  pkt \n"));
607     LWIP_DEBUGF(PKTPRINT_DEBUG, ("  2,         Print all pkt\n"));
608 }
609 
lwip_pkt_stats(pkt_stats_data * data)610 void lwip_pkt_stats(pkt_stats_data *data) {
611     if(data != NULL) {
612         memcpy(data, &g_stats_data, sizeof(g_stats_data));
613     }
614 }
615 
616 #if AOS_COMP_CLI
pktprint_cmd(int argc,char ** argv)617 void pktprint_cmd(int argc, char **argv )
618 {
619     if ( argc != 2 && argc != 3 ) {
620          LWIP_DEBUGF(PKTPRINT_DEBUG, ("Invalid command\n"));
621          _cli_pktprint_help_command();
622          return;
623     }
624 
625     if ( strcmp( argv[1], "-h" ) == 0 ) {
626         _cli_pktprint_help_command();
627     }
628     else if ( strcmp( argv[1], "-s" ) == 0 ) {
629         LWIP_DEBUGF(PKTPRINT_DEBUG, ("pkt_print debug_level=%d\n", pktprint_debug_level));
630     }
631     else if ( strcmp( argv[1], "-g" ) == 0 ) {
632         LWIP_DEBUGF(PKTPRINT_DEBUG, ("pkt_print the specified port =%d\n", filter_port));
633     }
634     else if ( strcmp( argv[1], "-p" ) == 0 ) {
635         if(pktprint_debug_level != 1)
636         {
637             LWIP_DEBUGF(PKTPRINT_DEBUG, ("pktprint debug level should set to 1 first\n"));
638         }
639         else
640         {
641             if( argc == 3)
642             {
643                 filter_port = atoi(argv[2]);
644             }
645             else
646             {
647                 LWIP_DEBUGF(PKTPRINT_DEBUG, ("Invalid command, please use pktprint -h\n"));
648             }
649         }
650     }
651     else if ( strcmp( argv[1], "-c" ) == 0 ) {
652         filter_port = 0;
653     }
654     else if ( strcmp( argv[1], "-t" ) == 0 ) {
655         if( argc == 3)
656         {
657             pktprint_debug_level = atoi(argv[2]);
658             if(pktprint_debug_level < 0 && pktprint_debug_level > 3 )
659             {
660                 LWIP_DEBUGF(PKTPRINT_DEBUG, ("Invalid command, please use pktprint -h\n"));
661             }
662         }
663         else
664         {
665             LWIP_DEBUGF(PKTPRINT_DEBUG, ("Invalid command, please use pktprint -h\n"));
666         }
667     } else if ( strcmp( argv[1], "-i" ) == 0 ) {
668         LWIP_DEBUGF(PKTPRINT_DEBUG, ("rx_bytes    rx_packets    \
669 tx_bytes    tx_packets    rx_tcp_bytes    rx_tcp_packets    rx_udp_bytes   rx_udp_packets    rx_other_bytes    rx_other_packets    tx_tcp_bytes   tx_tcp_packets    tx_udp_bytes    tx_udp_packets    tx_other_bytes    tx_other_packets\n"));
670         LWIP_DEBUGF(PKTPRINT_DEBUG, ("%lld    %lld    %lld    %lld    %lld    %lld    %lld    %lld    %lld    %lld    %lld    %lld    %lld    %lld    %lld    %lld\n",
671                 g_stats_data.rx_bytes, g_stats_data.rx_packets, g_stats_data.tx_bytes, g_stats_data.tx_packets,
672                 g_stats_data.rx_tcp_bytes, g_stats_data.rx_tcp_packets, g_stats_data.rx_udp_bytes,
673                 g_stats_data.rx_udp_packets, g_stats_data.rx_other_bytes, g_stats_data.rx_other_packets,
674                 g_stats_data.tx_tcp_bytes, g_stats_data.tx_tcp_packets, g_stats_data.tx_udp_bytes,
675                 g_stats_data.tx_udp_packets, g_stats_data.tx_other_bytes, g_stats_data.tx_other_packets));
676     }
677     else {
678             LWIP_DEBUGF(PKTPRINT_DEBUG, ("Invalid command, please use pktprint -h\n"));
679     }
680 }
681 
682 /* reg args: fun, cmd, description*/
683 ALIOS_CLI_CMD_REGISTER(pktprint_cmd, pktprint, Pktprint command)
684 #endif /* AOS_COMP_CLI */
685 #endif /* WITH_LWIP_PKTPRINT */
686