Fix clear stats for transport_dpi_demo application
[keystone-rtos/netapi.git] / ti / runtime / netapi / demo / src / navl_wrapper.c
1 #define __STDC_FORMAT_MACROS
2 #include <inttypes.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <signal.h>
7 #include <getopt.h>
8 #include <errno.h>
9 #include <assert.h>
10 #include <stdarg.h>
11 #include "ti/runtime/hplib/hplib.h"
12 #include "ti/runtime/netapi/netapi_types.h"
13 #include "navl_wrapper.h"
14 /* timing */
16 #define netapi_timing_start hplib_mUtilGetPmuCCNT
18 navl_wrapper_cfg_info_t *pNavlCfg;
19 navl_global_dpi_stats *pDpiStats;
20 void* pShmBase;
21 void *pShmEntry;
23 //int free_inst=0;
25 static unsigned long long timing=0LL;
27 static char last_url[256];
28 int class=0;
29 void clear_pkt_stats();
30 void navl_clear_stats(void)
31 {
32     memset(pDpiStats, 0, sizeof(navl_global_dpi_stats));
33     pDpiStats->min_time=100000000;
34     clear_pkt_stats();
35 }
36 void navl_return_stats(int * Pn_ops, int * Pn_class, unsigned long * Pmin_time, unsigned long * Pmax_time, unsigned long long *Ptiming, int * Pmalloc_inst, int *Pmalloc_bytes, int * Pn_err, int *Pfree_inst, unsigned long *Pmalloc_cycles, unsigned long *Pfree_cycles)
37 {
38     *Pn_ops=pDpiStats->n_ops;
39     *Pn_class=pDpiStats->n_class;
40     *Pmin_time=pDpiStats->min_time;
41     *Pmax_time=pDpiStats->max_time;
42     *Ptiming=timing;
43     *Pmalloc_inst = pDpiStats->malloc_inst;
44     *Pmalloc_bytes= pDpiStats->malloc_bytes;
45     *Pn_err=pDpiStats->n_err;
46     *Pfree_inst = pDpiStats->free_inst; 
47     *Pmalloc_cycles= pDpiStats->malloc_inst ? pDpiStats->malloc_cycles/pDpiStats->malloc_inst: 0;
48     *Pfree_cycles= pDpiStats->free_inst? pDpiStats->free_cycles/pDpiStats->free_inst : 0;
49 }
51 //#define MAX_BIN 10
52 static long bins[MAX_BIN]={10000, 12500, 15000,17500,20000, 25000,30000,35000,40000,50000};
53 static char* binStr[MAX_BIN]={"10K", "12.5K", "15K","17.5K","20K","25K","30K","35K","40K","50K"};
55 void add2bin(long cycles, long p_bins[])
56 {
57     int i;
58     for(i=0;i<MAX_BIN-1;i++)
59       if (cycles<bins[i]) {p_bins[i]+=1;return;}
60      p_bins[MAX_BIN-1] += 1; //max
61 }
65 navl_mcb_t *g_reader = NULL;
66 const char *g_exename = NULL;
68 static int  navl_wrapper_init(int argc, char *argv[]);
69 static void *navl_wrapper_malloc(size_t);
70 static void  navl_wrapper_free(void *);
71 static int   navl_wrapper_log_message(const char *level, const char *func, const char *format, ...);
73 static int navl_classify_callback(navl_handle_t handle, navl_result_t result, navl_state_t state, navl_conn_t conn, void *arg, int error);
75 static void  navl_wrapper_mem_stat_print();
77 /* external definitions */
78 void bind_navl_externals();
80 void navl_set_verbose(void)
81 {
82     g_reader->option_verbose=!g_reader->option_verbose;
83     printf(">**DPI Now in %s mode\n",g_reader->option_verbose?"verbose":"nonverbose");
84 }
85 void navl_dump_conn_info()
86 {
87 navl_diag(g_reader->navl, "TCP", NULL);
88 }
91 #define navl_wrapper_error() \
92 do { \
93     fprintf(stderr, "%s failed in %s:%u", g_exename, __FUNCTION__, __LINE__); \
94     if (g_reader) { \
95     if (g_reader->error_navl) \
96     fprintf(stderr, " with navl error %s", get_error_string(navl_error_get(g_reader->navl))); \
97     } \
98     fprintf(stderr, "\n"); \
99 } while (0)
101 int navl_setup(void)
103     return (navl_wrapper_init(0, NULL));
107 static const char *
108 get_state_string(navl_state_t state)
110 switch (state)
111     {
112         case NAVL_STATE_INSPECTING:
113             return "INSPECTING";
114         case NAVL_STATE_MONITORING:
115             return "MONITORING";
116         case NAVL_STATE_CLASSIFIED:
117             return "CLASSIFIED";
118         case NAVL_STATE_TERMINATED:
119             return "TERMINATED";
120         default:
121             return "UNKNOWN";
122     }
125 static const char *
126 get_confidence_string(int confidence)
128     switch (confidence)
129     {
130         case 50:
131             return "PORT";
132         case 100:
133             return "DPI";
134         default:
135             return "NONE";
136     }
139 static const char *
140 get_error_string(int error)
142     switch (error)
143     {
144         case 0:
145             return "None";
146         case ENOMEM:
147             return "No memory available";
148         case EPROTO:
149             return "Protocol error";
150         case ENOTCONN:
151             return "No connection allocated";
152         case EEXIST:
153             return "Object exists";
154         case EINVAL:
155             return "Invalid parameter";
156         case ECANCELED:
157             return "Operation cancelled";
158         case ENOENT:
159             return "No such file or directory";
160         case EPROTONOSUPPORT:
161             return "Protocol not supported";
162         default:
163             return "Unknown";
164     }
167 static int
168 navl_wrapper_init(int argc, char *argv[])
170     static navl_mcb_t reader;
172     int ret;
173     int i,j;
175     g_reader = &reader;
177     g_reader->navl = -1;
179     g_reader->config_capfile = NULL;
180     g_reader->config_plugins = "plugins";
181     g_reader->config_num_proto = 0;
182     g_reader->config_conn_id_attr = 0;
183     g_reader->config_http_attr = 0;
184     g_reader->config_num_memctx = NUM_MEM_CTX;
185     g_reader->config_num_memobj = NUM_MEM_OBJ;
187     g_reader->option_dpi = 1;
188     g_reader->option_simple = 0;
189     g_reader->option_track_memory = 1;
190     g_reader->option_limit_memory = 0;
191     g_reader->option_realtime_mode = 1;
192     g_reader->option_verbose = 0;
194     g_reader->error_navl = 0;
196     for(j=0;j< NUM_FP_PROCS;j++)
197         g_reader->stats_pkt[j] = NULL;
198     
199     g_reader->stats_conns = 0;
201     g_reader->running = 1;
202     g_reader->alloc_curr = 0;
203     g_reader->alloc_peak = 0;
205     g_exename = "dpi_demo";
208     /* allocate segment for shared memory for packet stats */
209      /* allocate packet statistics */
210     pShmBase = hplib_shmOpen();
211     if (pShmBase)
212     {
213         pShmEntry = hplib_shmGetEntry(pShmBase, APP_ENTRY_1);
214         pNavlCfg =  (navl_wrapper_cfg_info_t*)pShmEntry;
215         memset(pNavlCfg,
216                0,
217                sizeof(navl_wrapper_pkt_stat_t) * MAX_PROTOCOLS *NUM_FP_PROCS+ sizeof(navl_wrapper_cfg_info_t));
218         pNavlCfg =  (navl_wrapper_cfg_info_t*)pShmEntry;
219         pNavlCfg->num_protocols = g_reader->config_num_proto;
220         g_reader->stats_pkt[0] = pShmEntry + sizeof(navl_wrapper_cfg_info_t);
222         g_reader->stats_pkt[1] = pShmEntry + sizeof(navl_wrapper_cfg_info_t) +
223                 (sizeof(navl_wrapper_pkt_stat_t)*MAX_PROTOCOLS); 
225         for (j = 0; j < NUM_FP_PROCS; j++)
226         {
227             for(i=0;i< MAX_PROTOCOLS;i++)
228             {
229                 g_reader->stats_pkt[j][i].cycles_min=10000000;
230                 g_reader->stats_pkt[j][i].cycles_max=0;
232             }
233         }
234         pShmEntry = hplib_shmGetEntry(pShmBase, APP_ENTRY_2);
235         pDpiStats = (navl_global_dpi_stats*) pShmEntry;
236     }
237     else
238     {
239         printf("navl_wrapper_init: hplib_shmOpen failure\n");
240         return NETAPI_ERR_NOMEM;
241     }
243     /* EXTERNAL BINDINGS GO HERE */
244     {
245         /* Bind the platform specific functions. */
246         bind_navl_externals();
248         /* Private overrides for this example application. */
249         navl_log_message = navl_wrapper_log_message;
250         if (g_reader->option_track_memory)
251         {
252             navl_malloc_local = navl_wrapper_malloc;
253             navl_free_local = navl_wrapper_free;
254             navl_malloc_shared = navl_wrapper_malloc;
255             navl_free_shared = navl_wrapper_free;
257             memset(g_reader->stats_mem, 0, sizeof(g_reader->stats_mem));
258         }
259     }
261     /* open the navl library */
262     if ((g_reader->navl = navl_open(g_reader->config_plugins)) == -1)
263         navl_wrapper_error();
265     /* set logging level to "error | fatal" */
266     if (navl_config_set(g_reader->navl, "system.loglevel", "48") == -1)
267         navl_wrapper_error();
269     /* determine the max protocol index */
270     if ((ret = navl_proto_max_index(g_reader->navl)) == -1)
271     {
272         printf("navl_proto_max_index error\n");
273         navl_wrapper_error();
274     }
276     /* the number of protocols is the max + 1 */
277     g_reader->config_num_proto = (ret + 1);
278     pNavlCfg->num_protocols = g_reader->config_num_proto;
280     return NETAPI_ERR_OK;
283 //per thread init. Call this in worker thread context
284 int navl_per_thread_init(uint32_t thread_num)
286     int  ret;
287     int c;
289      /* initialize this thread for classification */
290     if (navl_init(g_reader->navl))
291     {
292         printf("navl_init error\n");
293         navl_wrapper_error();
294     }
295 #if 0
296         /* enable connection tracking */
297         if (navl_attr_enable(g_reader->navl, "conn.id", 1) == -1)
298                 navl_wrapper_error();
300 #ifdef HTTP_ATTRIB
301         /* enable http url */
302         if (navl_attr_enable(g_reader->navl, "http.request.url",1) == -1)
303                 navl_wrapper_error();
304 #endif
306         /* lookup the key for conn.id */
307         if ((g_reader->config_conn_id_attr = navl_attr_key_get(g_reader->navl, "conn.id")) == -1)
308                 navl_wrapper_error();
309 #ifdef HTTP_ATTRIB
310         /* lookup the key for http.request.host */
311         if ((g_reader->config_http_attr = navl_attr_key_get(g_reader->navl, "http.request.url")) == -1)
312                 navl_wrapper_error();
313 #endif
314 #endif
315     /* simulated realtime */
316     if (g_reader->option_realtime_mode == 2)
317         navl_clock_set_mode(g_reader->navl, 1);
320 #if 0
321     /* determine the max protocol index */
322     if ((ret = navl_proto_max_index(g_reader->navl)) == -1)
323     {
324         printf("navl_proto_max_index error\n");
325         navl_wrapper_error();
326     }
328     /* the number of protocols is the max + 1 */
329     g_reader->config_num_proto = (ret + 1);
330 #endif
333     /* now fetch all the protocol name ahead of time do we don't have to lookup them up on each packet */
334     for (ret = 0; ret != g_reader->config_num_proto; ret++)
335         navl_proto_get_name(g_reader->navl, ret,
336                             g_reader->stats_pkt[thread_num-1][ret].name,
337                             sizeof(g_reader->stats_pkt[thread_num-1][ret].name));
340  /* fetch all the memory tag names */
341     for (c = 0; c < NUM_MEM_CTX; c++)
342         navl_memory_ctx_name(g_reader->navl, c, g_reader->ctx_name[c], sizeof(g_reader->ctx_name[c]));
343     for (c = 0; c < NUM_MEM_OBJ; c++)
344         navl_memory_obj_name(g_reader->navl, c, g_reader->obj_name[c], sizeof(g_reader->obj_name[c]));
346     return 1;
350 static uint64_t
351 msec_time(struct timeval *tv)
353     return ((uint64_t)tv->tv_sec * 1000) + (tv->tv_usec / 1000);
356 static void
357 msec_delay(uint64_t msecs)
359     struct timeval tv = { msecs / 1000, (msecs % 1000) * 1000 };
360     select(0, 0, 0, 0, &tv);
363 #if 1
364 typedef struct
366     const uint8_t *data;
367     uint32_t       size;
368     uint32_t       sequence;
369     int32_t        appidx;
370     uint64_t       connid;
371 } navl_wrapper_packet_t;
372 #else
373 typedef struct
375         const uint8_t    *data;
376         uint32_t          size;
377         uint32_t          sequence;
378         int32_t           appidx;
379         int32_t           num_cb;
380 } navl_wrapper_packet_t;
381 #endif
384 #if 1
385 static int
386 navl_classify_callback(navl_handle_t handle,
387                             navl_result_t result,
388                             navl_state_t state,
389                             navl_conn_t conn,
390                             void *arg,
391                             int error)
393     int idx, protoid = 0, confidence = 0;
394     char buf[256] = {0};
395     navl_iterator_t it;
396     navl_wrapper_packet_t *packet = (navl_wrapper_packet_t *)arg;
397     int threadId =Osal_nwalGetProcId();
399     packet->appidx = navl_app_get(g_reader->navl, result, &confidence);
400     if((state==NAVL_STATE_CLASSIFIED) ||
401        (state==NAVL_STATE_TERMINATED) ||
402        (state==NAVL_STATE_MONITORING))
403     {
404         pDpiStats->n_class+=1;
405         class =1;
406     }
407     else
408         class=0;
409 #if 0
410     if (navl_proto_find_index(g_reader->navl, "HTTP") == packet->appidx)
411     {
412         it = navl_proto_find(g_reader->navl, result, navl_proto_find_index(g_reader->navl, "HTTP"));
413         if (navl_proto_valid(g_reader->navl, it))
414             navl_attr_get(g_reader->navl,
415             it, 
416             g_reader->config_http_attr, 
417             &last_url,
418             sizeof(last_url));
419     }
420 #endif
421     if (g_reader->option_verbose)
422     {
423         /* Build the stack string */
424         for (idx = 0, it = navl_proto_first(g_reader->navl, result); navl_proto_valid(g_reader->navl, it); navl_proto_next(g_reader->navl, it))
425         {
426             protoid = navl_proto_get_index(g_reader->navl, it);
427             if (!packet->connid)
428             {
429                 if (navl_proto_find_index(g_reader->navl, "IP") == protoid)
430                 {
431 #if 0
432                     navl_attr_get(g_reader->navl, it, g_reader->config_conn_id_attr, &packet->connid, sizeof(packet->connid));
433                     if (packet->connid > g_reader->stats_conns)
434                     g_reader->stats_conns = packet->connid;
435 #endif
436                 }
437             }
438             idx += sprintf(&buf[idx], "/%s", g_reader->stats_pkt[threadId-1][protoid].name);
439         }
440         printf(" Pkt: %u (%u bytes), Conn: %" PRIu64 ", App: %s (%s), State: %s, Stack: %s, Error: %s\n", packet->sequence
441         , packet->size, packet->connid, g_reader->stats_pkt[threadId-1][packet->appidx].name
442         , get_confidence_string(confidence), get_state_string(state), buf, get_error_string(error));
443     }
445     /* Continue tracking the flow */
446     return 0;
448 #else
449 static int
450 navl_classify_callback(navl_handle_t handle,
451                             navl_result_t result,
452                             navl_state_t state,
453                             navl_conn_t conn,
454                             void *arg,
455                             int error)
457         int idx, protoid = 0, confidence = 0;
458         char buf[256] = {0};
459         navl_iterator_t it;
460         navl_conn_id_t conn_id = navl_conn_id_get(handle, conn);
461         navl_wrapper_packet_t *packet = (navl_wrapper_packet_t *)arg;
463         /* Always display the outer packet; optionally display encapsulated data */
464         if (!packet->num_cb || g_reader->option_tunnel)
465         {
466                 packet->appidx = navl_app_get(g_reader->navl, result, &confidence);
468                 if (g_reader->option_verbose)
469                 {
470                         if (conn_id > g_reader->stats_conns)
471                                 g_reader->stats_conns = conn_id;
473                         /* Build the stack string */
474                         for (idx = 0, it = navl_proto_first(g_reader->navl, result); navl_proto_valid(g_reader->navl, it); navl_proto_next(g_reader->navl, it))
475                         {
476                                 protoid = navl_proto_get_index(g_reader->navl, it);
477                                 idx += sprintf(&buf[idx], "/%s", g_reader->stats_pkt[fp_thread][protoid].name);
478                         }
480                         printf(" Pkt: %u (%u bytes), Conn: %" PRIu64 ", App: %s (%s), State: %s, Stack: %s, Error: %s\n"
481                                 , packet->sequence, packet->size, conn_id, g_reader->stats_pkt[fp_thread][packet->appidx].name
482                                 , get_confidence_string(confidence), get_state_string(state), buf, get_error_string(error));
483                 }
484         }
486         packet->num_cb++;
488         /* Continue tracking the flow */
489         return 0;
491 #endif
493 //process the packet
494 __thread navl_wrapper_packet_t packet = { NULL, 0, 0 };
495 int navl_process_pkt(unsigned char *p_pkt, int len)
497     volatile unsigned long v1;
498     volatile unsigned long v2;
499     unsigned long temp=0;
500     uint64_t last = 0;
501     uint64_t next = 0;
502     unsigned long long mf1;
503     unsigned long long mf2;
504     int threadId =Osal_nwalGetProcId();
505     mf1= pDpiStats->malloc_cycles+pDpiStats->free_cycles;
506     
507     v1 = netapi_timing_start();
508     
509 /* update the current packet */
510     packet.sequence++;
511     packet.size = len;
512     packet.appidx = 0;
513     //packet.connid = 0;
514     packet.data=p_pkt;
516     /* "real" realtime */
517     if (g_reader->option_realtime_mode == 1)
518     {
519         //next = msec_time(0LL);//dal -> get ts here
520         next=0LL;
521         if (last)
522         msec_delay(next - last);
523         last = next;
524     }
525     if (navl_classify(g_reader->navl,
526                       NAVL_ENCAP_ETH,
527                       packet.data,
528                       packet.size,
529                       NULL,
530                       0,
531                       navl_classify_callback,
532                       &packet) == -1)
533     printf(" Pkt: %u (%u bytes), Error: %s\n", packet.sequence,
534                                                packet.size,
535                 get_error_string(navl_error_get(g_reader->navl)));
537     /* Update the stats. If classification was not enabled, then the appidx will be 0 and all packets
538      * captured will be accumulated there */
539     g_reader->stats_pkt[threadId-1][packet.appidx].packets++;
540     g_reader->stats_pkt[threadId-1][packet.appidx].bytes += packet.size;
541     if(class)
542         g_reader->stats_pkt[threadId-1][packet.appidx].class++;
543     //update timing
544     v2 = netapi_timing_start();
545     temp=v2-v1;
546     mf2= pDpiStats->malloc_cycles + pDpiStats->free_cycles;
547     timing+= (unsigned long long) temp;
548     g_reader->stats_pkt[threadId-1][packet.appidx].cycles += (unsigned long long) temp;
549     g_reader->stats_pkt[threadId-1][packet.appidx].cycles_nomem += ((unsigned long long) temp - (mf2-mf1));
551     if (g_reader->stats_pkt[threadId-1][packet.appidx].cycles_min > temp)
552         g_reader->stats_pkt[threadId-1][packet.appidx].cycles_min = temp;
554     if (g_reader->stats_pkt[threadId-1][packet.appidx].cycles_max  < temp)
555     {
556         g_reader->stats_pkt[threadId-1][packet.appidx].cycles_max = temp;
558     }
559     
561     add2bin((temp - (unsigned long)(mf2-mf1)),&g_reader->stats_pkt[threadId-1][packet.appidx].bin_cycles[0]); 
562     pDpiStats->n_ops+=1;
563     if (temp > pDpiStats->max_time) pDpiStats->max_time = temp;
564     if (temp< pDpiStats->min_time) pDpiStats->min_time = temp;
565     return 1;
568 int navl_done(void)
570     navl_fini(g_reader->navl);
571     navl_close(g_reader->navl);
572     return 1;
575 void navl_results(int fp_thread)
577     int idx;
578     int i;
579     uint64_t total_packets, total_bytes;
580     void* pShmEntry;
582     total_packets = 0;
583     total_bytes = 0;
585     if (g_reader->option_dpi)
586     {
587         printf("\n NAVL DPI stats for CORE ID %d\n", fp_thread + 1);
588         printf("\n AppProto    Packets  Class   Bytes        Cycles/Pkt      Cyclesnomem/Pkt  (min)  (max) ");
589         for(i=0;i<MAX_BIN;i++)
590             printf("<%s ",binStr[i]);
591         printf("\n ----------------------------------------------------------------------------------------------------------------------------------------------------\n");
592     }
594     //for (idx = 0; idx < g_reader->config_num_proto; idx++)
595     for (idx = 0; idx < pNavlCfg->num_protocols; idx++)
596     {
597         if (g_reader->option_dpi)
598         {
599             if (g_reader->stats_pkt[fp_thread][idx].packets)
600             {
601                 /* We need to provide protocol definitions */   
602                 printf(" %-12s%-12" PRIu64 " %" PRIu64 " %" PRIu64 "      %" PRIu64 "       %" PRIu64 "    %ld    %ld    " , 
603                         g_reader->stats_pkt[fp_thread][idx].name,
604                         g_reader->stats_pkt[fp_thread][idx].packets, 
605                         g_reader->stats_pkt[fp_thread][idx].class, 
606                         g_reader->stats_pkt[fp_thread][idx].bytes,
607                         g_reader->stats_pkt[fp_thread][idx].cycles/g_reader->stats_pkt[fp_thread][idx].packets, 
608                         g_reader->stats_pkt[fp_thread][idx].cycles_nomem/g_reader->stats_pkt[fp_thread][idx].packets,
609                         g_reader->stats_pkt[fp_thread][idx].cycles_min,
610                         g_reader->stats_pkt[fp_thread][idx].cycles_max);
611                 for(i=0;i<MAX_BIN;i++) printf("%ld ",g_reader->stats_pkt[fp_thread][idx].bin_cycles[i]);
612                 printf("\n");
613             }
614         }
616         total_packets += g_reader->stats_pkt[fp_thread][idx].packets;
617         total_bytes += g_reader->stats_pkt[fp_thread][idx].bytes;
618     }
620     if (!total_packets)
621         printf("\n No packets captured.\n");
622     else
623         printf("\n %" PRIu64 " packets captured (%" PRIu64 " bytes)\n", total_packets, total_bytes);
625     if (g_reader->stats_conns)
626         printf(" %" PRIu64 " connections tracked\n", g_reader->stats_conns);
628     printf("\n");
629     if (g_reader->option_track_memory)
630         navl_wrapper_mem_stat_print();
633     if (pNavlCfg->alloc_curr != 0)
634         printf("Bytes not freed: %" PRIi64 "\n", pNavlCfg->alloc_curr);
636     if (g_reader->alloc_peak != 0)
637            printf("Peak allocated: %" PRIi64 "\n", g_reader->alloc_peak);
639     printf("attr test: last http utl= %s\n",last_url);
642 static void 
643 navl_wrapper_mem_stat_print()
645     int i, j;
646     navl_wrapper_stat_t *stat;
647     char *name;
649     printf("                                          Curr      Peak      Fail   \n");
650     printf("-----------------------------------------------------------------------");
652     for (i = 0; i < g_reader->config_num_memctx; i++)
653     {
654         stat = &g_reader->stats_mem[i][0];
655         if (stat->peak == 0)
656         continue;
658         printf("\n\t%s\n", g_reader->ctx_name[i]);
660         for (j = g_reader->config_num_memobj - 1; j >= 0; j--)
661         {
662             navl_wrapper_stat_t *stat = &g_reader->stats_mem[i][j];
663             if (stat->peak == 0)
664             continue;
666             name = j ? g_reader->obj_name[j] : (char *)"other";
668             if (stat->peak || stat->fail)
669             printf("\t\t%-20s%10" PRIu64 "%10" PRIu64 "%10" PRIu64 "\n", name, stat->curr, stat->peak, stat->fail);
670         }
671     }
672     printf("\n\n");
676 void navl_results2(int fp_thread)
678     int idx;
679     int i;
680     uint64_t total_packets, total_bytes;
681     void* pShmEntry;
682     void* pShmBase;
683     void* pTemp;
684     navl_wrapper_cfg_info_t *pNavlCfg;
685     navl_wrapper_pkt_stat_t *pStats1;
686     navl_wrapper_pkt_stat_t *pStats2;
687     navl_mcb_t g_reader;
689     pShmBase = hplib_shmOpen();
690     if (pShmBase)
691     {
692         pTemp = hplib_shmGetEntry(pShmBase, APP_ENTRY_1);
693         pNavlCfg =  (navl_wrapper_cfg_info_t*)pTemp;
694     
695         g_reader.stats_pkt[0] = pTemp + sizeof(navl_wrapper_cfg_info_t);
696     
697     
698         g_reader.stats_pkt[1] = pTemp + sizeof(navl_wrapper_cfg_info_t) +
699                 (sizeof(navl_wrapper_pkt_stat_t)*pNavlCfg->num_protocols);
700     }
701     total_packets = 0;
702     total_bytes = 0;
704     //if (g_reader->option_dpi)
705     {
706         printf("\n NAVL DPI stats for CORE ID %d\n", fp_thread);
707         printf("\n AppProto    Packets  Class   Bytes        Cycles/Pkt      Cyclesnomem/Pkt  (min)  (max) ");
708         for(i=0;i<MAX_BIN;i++)
709             printf("<%s ",binStr[i]);
710         printf("\n ----------------------------------------------------------------------------------------------------------------------------------------------------\n");
711     }
713     //for (idx = 0; idx < g_reader->config_num_proto; idx++)
714     for (idx = 0; idx < pNavlCfg->num_protocols; idx++)
715     {
716         //if (g_reader->option_dpi)
717         {
718             if (g_reader.stats_pkt[fp_thread][idx].packets)
719             {
720                 /* We need to provide protocol definitions */   
721                 printf(" %-12s%-12" PRIu64 " %" PRIu64 " %" PRIu64 "      %" PRIu64 "       %" PRIu64 "    %ld    %ld    " , 
722                         g_reader.stats_pkt[fp_thread][idx].name,
723                         g_reader.stats_pkt[fp_thread][idx].packets, 
724                         g_reader.stats_pkt[fp_thread][idx].class, 
725                         g_reader.stats_pkt[fp_thread][idx].bytes,
726                         g_reader.stats_pkt[fp_thread][idx].cycles/g_reader.stats_pkt[fp_thread][idx].packets, 
727                         g_reader.stats_pkt[fp_thread][idx].cycles_nomem/g_reader.stats_pkt[fp_thread][idx].packets,
728                         g_reader.stats_pkt[fp_thread][idx].cycles_min,
729                         g_reader.stats_pkt[fp_thread][idx].cycles_max);
730                 for(i=0;i<MAX_BIN;i++) printf("%ld ",g_reader.stats_pkt[fp_thread][idx].bin_cycles[i]);
731                 printf("\n");
732             }
733         }
735         total_packets += g_reader.stats_pkt[fp_thread][idx].packets;
736         total_bytes += g_reader.stats_pkt[fp_thread][idx].bytes;
737     }
739     if (!total_packets)
740         printf("\n No packets captured.\n");
741     else
742         printf("\n %" PRIu64 " packets captured (%" PRIu64 " bytes)\n", total_packets, total_bytes);
744 #if 0
745     if (g_reader.stats_conns)
746         printf(" %" PRIu64 " connections tracked\n", g_reader.stats_conns);
748     printf("\n");
749     //if (g_reader.option_track_memory)
750         navl_wrapper_mem_stat_print();
752     if (pNavlCfg->alloc_curr != 0)
753         printf("Bytes not freed: %" PRIi64 "\n", pNavlCfg->alloc_curr);
755     if (g_reader.alloc_peak != 0)
756            printf("Peak allocated: %" PRIi64 "\n", g_reader.alloc_peak);
758     printf("attr test: last http utl= %s\n",last_url);
759 #endif
764 /* Private memory stamp type for tracking memory with navl_wrapper_malloc/free */
765 typedef struct
767     size_t      size;       /* size of allocation */
768     short       ctx_tag;    /* ctx axis */
769     short       obj_tag;    /* obj axis */
770     char        mem[0];
771 } memstamp_t;
773 static void *navl_wrapper_malloc(size_t size)
775     navl_handle_t handle;
776     navl_wrapper_stat_t *stat_mem;
777     int tag;
778     int ctx_tag, obj_tag;
779     unsigned long t1;
780     unsigned long t2;
781     pDpiStats->malloc_inst+=1;
782     pDpiStats->malloc_bytes+=size;
783     t1=netapi_timing_start();
785     assert(size);
787     /* In this context, the handle should be read using navl_handle_get() since
788      * the application cached handle (in this case g_reader->navl) will not be set
789      * until navl_open() returns. For this simple test we just assert that the handle
790      * is infact valid. */
791     handle = navl_handle_get();
792     assert(handle != 0);
794     /* Fetch the tags associated with this allocation. They will be used below to record
795      * statistics about allocations within the library on 2 axis. The upper 16 bits contain
796      * a memory obj tag and the lower 16 bits contain the allocation context tag. These
797      * tags are indices, the upper of which is available through navl_memory_ctx_num()
798      * and navl_memory_obj_num() resp. They are generated dynamically and may differ  between
799      * configurations. These total number of indices are available ONLY AFTER navl_open() 
800      * returns.
801      */
802     tag = navl_memory_tag_get(handle);
803     obj_tag = (tag >> 16);
804     ctx_tag = (tag & 0x0000FFFF);
806     /* You could do something better here and reallocate the matrix */
807     if (ctx_tag >= g_reader->config_num_memctx || obj_tag >= g_reader->config_num_memobj)
808     {
809         assert(0);
810         return NULL;
811     }
813     stat_mem = &g_reader->stats_mem[ctx_tag][obj_tag];
815     /* check limits */
816     if (!g_reader->option_limit_memory || (pNavlCfg->alloc_curr + size < g_reader->option_limit_memory))
817     {
818         memstamp_t *ptr = (memstamp_t *)malloc(size + sizeof(memstamp_t));
819         if (ptr)
820         {
821             /* track peak values */
822             if ((pNavlCfg->alloc_curr += size) > g_reader->alloc_peak)
823             g_reader->alloc_peak = pNavlCfg->alloc_curr;
825             if ((stat_mem->curr += size) > stat_mem->peak)
826             stat_mem->peak = stat_mem->curr;
828             ptr->size = size;
829             ptr->ctx_tag = ctx_tag;
830             ptr->obj_tag = obj_tag;
831             t2=netapi_timing_start();
832             pDpiStats->malloc_cycles += (unsigned long long)  (t2-t1);
833             return ptr->mem;
834         }
835     }
836     stat_mem->fail += size;
837     return NULL;
840 static void 
841 navl_wrapper_free(void *p)
843     unsigned long t1;
844     unsigned long t2;
845     pDpiStats->free_inst += 1;
846     t1=netapi_timing_start();
847     if (!p)
848         return;
850     memstamp_t *ptr = (memstamp_t *)((char *)p - offsetof(memstamp_t, mem));
851     navl_wrapper_stat_t *stat_mem = &g_reader->stats_mem[ptr->ctx_tag][ptr->obj_tag];
853     assert(p == ptr->mem);
855     stat_mem->curr -= ptr->size;
856     pNavlCfg->alloc_curr -= ptr->size;
858     free(ptr);
859     t2=netapi_timing_start();
860     pDpiStats->free_cycles += (unsigned long long)  (t2-t1);
863 static int
864 navl_wrapper_log_message(const char *level, const char *func, const char *format, ... )
866     int res = 0;
867     char buf[4096];
868     va_list va;
869     va_start(va, format);
871     res = snprintf(buf, 4096, "%s: %s: ", level, func);
872     res += vsnprintf(buf + res, 4096 - res, format, va);
873     printf("%s\n", buf);
874     va_end(va);
875     return res;
878 //clear stats
879 void clear_pkt_stats()
881     int ret, i;
883     for (i=0;i < NUM_FP_PROCS;i++)
884     {
885         memset(g_reader->stats_pkt[i], 0, (sizeof(navl_wrapper_pkt_stat_t)*MAX_PROTOCOLS));
886         /* now fetch all the protocol name ahead of time do we don't have to lookup them up on each packet */
887         for (ret = 0; ret != MAX_PROTOCOLS; ret++)
888         {
889             g_reader->stats_pkt[i][ret].cycles_min=10000000;
890             navl_proto_get_name(g_reader->navl, ret,
891                             g_reader->stats_pkt[i][ret].name,
892                             sizeof(g_reader->stats_pkt[i][ret].name));
893         }
894     }