efd2dc43874dc06f8a3eaf9fe0b16812328c26fd
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)
102 {
103 return (navl_wrapper_init(0, NULL));
104 }
107 static const char *
108 get_state_string(navl_state_t state)
109 {
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 }
123 }
125 static const char *
126 get_confidence_string(int confidence)
127 {
128 switch (confidence)
129 {
130 case 50:
131 return "PORT";
132 case 100:
133 return "DPI";
134 default:
135 return "NONE";
136 }
137 }
139 static const char *
140 get_error_string(int error)
141 {
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 }
165 }
167 static int
168 navl_wrapper_init(int argc, char *argv[])
169 {
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;
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;
281 }
283 //per thread init. Call this in worker thread context
284 int navl_per_thread_init(uint32_t thread_num)
285 {
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;
347 }
350 static uint64_t
351 msec_time(struct timeval *tv)
352 {
353 return ((uint64_t)tv->tv_sec * 1000) + (tv->tv_usec / 1000);
354 }
356 static void
357 msec_delay(uint64_t msecs)
358 {
359 struct timeval tv = { msecs / 1000, (msecs % 1000) * 1000 };
360 select(0, 0, 0, 0, &tv);
361 }
363 #if 1
364 typedef struct
365 {
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
374 {
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)
392 {
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;
447 }
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)
456 {
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;
490 }
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)
496 {
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;
507 v1 = netapi_timing_start();
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 }
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;
566 }
568 int navl_done(void)
569 {
570 navl_fini(g_reader->navl);
571 navl_close(g_reader->navl);
572 return 1;
573 }
575 void navl_results(int fp_thread)
576 {
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);
640 }
642 static void
643 navl_wrapper_mem_stat_print()
644 {
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");
673 }
676 void navl_results2(int fp_thread)
677 {
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;
695 g_reader.stats_pkt[0] = pTemp + sizeof(navl_wrapper_cfg_info_t);
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
760 }
764 /* Private memory stamp type for tracking memory with navl_wrapper_malloc/free */
765 typedef struct
766 {
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)
774 {
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;
838 }
840 static void
841 navl_wrapper_free(void *p)
842 {
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);
861 }
863 static int
864 navl_wrapper_log_message(const char *level, const char *func, const char *format, ... )
865 {
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;
876 }
878 //clear stats
879 void clear_pkt_stats()
880 {
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 }
895 }