Coverage Report

Created: 2025-10-12 06:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ndpi/src/lib/ndpi_classify.c
Line
Count
Source
1
/*
2
 *
3
 * Copyright (c) 2016 Cisco Systems, Inc.
4
 * All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
8
 * are met:
9
 *
10
 *   Redistributions of source code must retain the above copyright
11
 *   notice, this list of conditions and the following disclaimer.
12
 *
13
 *   Redistributions in binary form must reproduce the above
14
 *   copyright notice, this list of conditions and the following
15
 *   disclaimer in the documentation and/or other materials provided
16
 *   with the distribution.
17
 *
18
 *   Neither the name of the Cisco Systems, Inc. nor the names of its
19
 *   contributors may be used to endorse or promote products derived
20
 *   from this software without specific prior written permission.
21
 *
22
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26
 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
33
 * OF THE POSSIBILITY OF SUCH DAMAGE.
34
 *
35
 */
36
37
/**
38
 * \file ndpi_classify.c
39
 *
40
 * \brief contains the functionality for inline classification
41
 *
42
 */
43
44
#include <stdio.h>
45
#include <ctype.h>
46
// #include <sys/time.h>
47
#include <stdlib.h>
48
#include <stdint.h>
49
#include <math.h>
50
#include "ndpi_main.h"
51
#include "ndpi_classify.h"
52
#include "ndpi_includes.h"
53
54
#include "ndpi_replace_printf.h"
55
56
/** finds the minimum value between to inputs */
57
#ifndef min
58
#define min(a,b)        \
59
135M
  ({ __typeof__ (a) _a = (a);     \
60
135M
    __typeof__ (b) _b = (b);      \
61
135M
    _a < _b ? _a : _b; })
62
#endif
63
64
/* **************************************** */
65
66
//bias (1) + w (207)
67
//const float ndpi_parameters_splt[NUM_PARAMETERS_SPLT_LOGREG] = {
68
float ndpi_parameters_splt[NUM_PARAMETERS_SPLT_LOGREG] = {
69
                -2.088057846500587456e+00, 7.763936238952200239e-05, 4.404309737393306595e-05, -9.467385027293546973e-02,
70
                4.348947142638090457e-01, -2.091409170053043390e-04, -5.788902107267982974e-04, 4.481443450852441001e-10,
71
                -3.136135459023654537e+00, -1.507730262127600751e+00, -1.204663669965535977e+00, -1.171839254318371104e+00,
72
                4.329302247232582057e-01, 8.310653628092458334e+00, 3.299246725156660176e+00, 0.000000000000000000e+00,
73
                1.847454931582027254e-02, -1.498024139966201096e+00, -7.660670007653060942e-01, -2.908130300830076731e+00,
74
                -1.252564844610269734e+00, -1.910955328742287573e+00, 9.471710980110392697e-01, 2.352302758516665371e+00,
75
                2.982269972214651954e+00, 4.280736383314343918e+00, 4.633629909719495288e+00, -2.198052637823726840e+00,
76
                -1.150759637168392580e+00, 3.420433363184381292e+00, 1.857878113059351077e-02, -1.559806674919653746e+00,
77
                4.197498183183401288e+00, 6.262186949633183453e+00, 1.100694844370524095e+01, 2.778688785515088000e+01,
78
                3.679948298336883195e+00, -2.432801394376875592e+00, 5.133442052706843617e-01, 2.181172654073517680e+00,
79
                -8.577551729671881731e-01, 7.013844214023315926e-01, 3.138233436228588857e+00, 7.319940508466630247e-01,
80
                0.000000000000000000e+00, 3.529209394581482861e+00, 1.464585117707144413e+01, 8.506550226820598359e-01,
81
                -9.060397326548508268e-01, 6.787474954688997641e+00, 8.125411068867387954e+00, 4.515740684104064151e+00,
82
                5.372135582950940069e+00, 9.210951196799497254e-01, 4.802177410869620466e+00, 2.945445016176073594e+01,
83
                1.575032253128311632e+00, -1.355276854364796946e-01, -3.322474764169629502e-01, 3.018397817188666732e+00,
84
                1.186503569922195744e+00, 0.000000000000000000e+00, 8.883242370198487503e-01, 7.248276146728496627e+00,
85
                0.000000000000000000e+00, 0.000000000000000000e+00, -4.831246718433664711e+00, 6.124136970173365002e-01,
86
                4.145693892559814686e-01, 2.683998941637626867e+00, 2.063906603639539039e+00, 2.989801217386735210e+00,
87
                2.262965767379551962e-01, 2.240332214649647380e+00, 5.984550782416063086e+00, 4.587011255338186544e+00,
88
                1.233118485315272039e+01, 1.115223490909697857e+00, -3.682686422016995476e+00, 6.096498453291562258e-01,
89
                1.119275528656461516e+00, 1.377886278915177731e-01, 3.828176805973048324e+00, 0.000000000000000000e+00,
90
                0.000000000000000000e+00, 1.442927634029647344e+01, 0.000000000000000000e+00, 5.719118583309401593e-01,
91
                1.993632609731877392e-01, 3.047472271520709430e+00, 5.736784864911910198e+00, 6.677826247219391220e+00,
92
                6.307175478564531090e+00, 3.150295169417364249e+01, 3.738597740702392258e+00, 1.129754590514236234e+01,
93
                6.108506268573830056e+00, 1.605489516792866667e+00, 2.929631990348545489e+00, -2.832543082245212937e-02,
94
                1.358286530670594461e+00, 1.655932469853677924e+00, 6.701964773769768513e-01, 2.131182050917533211e+00,
95
                2.998351165769753468e+00, 7.772095996358327596e+00, 1.285014785269981141e+00, 4.407334784589962418e+00,
96
                1.719858214230612026e+00, -1.012765674651314063e+00, -5.749271123172469133e-01, -3.559614093795681278e+00,
97
                -3.073088477387719397e+00, -4.492469521371540431e+00, -3.753286990415885427e+00, -3.219255423324282273e+00,
98
                -2.806436518181075090e+00, -2.697305948568419875e+00, -7.879608430851776646e-01, 4.625507221739111330e+00,
99
                4.809280703883450414e+00, -3.435194026629848629e+00, -3.218943068168937049e+00, 3.335535704890596698e+00,
100
                2.071359212435486263e+00, 4.538992059175040339e+00, -2.770772323566738038e+01, 2.903047708571506735e+00,
101
                -4.436143805989154032e+00, -2.647991280011542381e-01, 1.737252348126810064e+00, -4.121989655995259128e+00,
102
                3.209709099445720581e-01, 1.012758514896711759e+01, 3.313255624721038295e+00, 4.631467619785444967e+00,
103
                7.668642402146534032e+00, 6.780938812710099128e+00, -3.256164342602652972e+00, 6.749565128319576779e-01,
104
                0.000000000000000000e+00, -4.407265954524525853e+00, 0.000000000000000000e+00, -3.666522115024547901e+01,
105
                -7.886029397826226273e+01, 0.000000000000000000e+00, 0.000000000000000000e+00, -2.261283814517791058e+01,
106
                -4.024317426178160240e+00, 3.213063737030031342e-01, 5.079805145796887800e+00, 1.326813226475260343e+00,
107
                1.233684078112145643e+00, 8.671852503871454232e+00, -2.041800256066371944e+00, 0.000000000000000000e+00,
108
                0.000000000000000000e+00, -1.607347800380474823e+01, -4.430790279223246309e+00, 1.177552465851384511e+00,
109
                6.342921220500139512e+00, -2.466913734548706327e-02, 3.451642566010713065e-01, -6.012767168531006234e+00,
110
                7.328146570137336724e+00, 7.500088131707050465e+00, 0.000000000000000000e+00, -3.547913249211809017e+01,
111
                -3.130964814607208879e+00, 8.247326544297072237e-01, 3.757262485775580418e-01, -2.136528302027558723e+00,
112
                -2.631627236037529793e-01, -2.016718799388414141e+01, 0.000000000000000000e+00, 0.000000000000000000e+00,
113
                0.000000000000000000e+00, -7.708602132869285528e-01, -2.602868328868111814e+00, 1.435184800833797958e+00,
114
                0.000000000000000000e+00, -2.080420864280113413e+00, 1.169498351211070819e+00, -1.798334115637199560e+01,
115
                -1.193885252696202670e+01, 0.000000000000000000e+00, 0.000000000000000000e+00, 4.304089297965300709e+00,
116
                -3.020893216686394656e+00, -1.234427481614708721e+00, 0.000000000000000000e+00, 1.853340741926325697e+00,
117
                -2.686000064995862147e+01, -1.672275139058893600e+01, -2.826268691607605987e+01, 0.000000000000000000e+00,
118
                0.000000000000000000e+00, -1.547397429377200817e+00, -4.018181657009961327e+00, -7.289186736637049968e+00,
119
                -7.458655219230571731e+00, -9.625538282761622710e+00, -1.103039457077456298e+01, -6.262675161142102809e+01,
120
                -9.265912629799268885e+00, -8.961543476816615339e+00, -9.622764435629340696e+00, -1.097978292092879826e+01,
121
};
122
123
//bias (1) + w (207)
124
//const float ndpi_parameters_bd[NUM_PARAMETERS_BD_LOGREG] = {
125
float ndpi_parameters_bd[NUM_PARAMETERS_BD_LOGREG] = {
126
                  -1.678134053325450292e+00, 1.048946534609769413e-04, 9.608725756967682636e-05, -7.515489355100658797e-02,
127
                  2.089554874872663892e-01, -1.012058874142656513e-04, -2.917652723373885169e-04, 1.087540461196068741e-10,
128
                  -2.594688448425090055e+00, -2.071803573048482061e+00, -1.399303273236228939e+00, -2.089300736641718004e+00,
129
                  -8.842347826063630123e-01, 6.476433717022786141e+00, 3.114501282249810377e+00, -2.239127990932460399e+00,
130
                  -4.667574389646080291e-01, -2.200651610813817438e+00, -1.674926704401964894e+00, -3.894420410398949706e+00,
131
                  -1.232376502509682004e+00, -2.231027070413975189e+00, 7.691948448668822769e-01, 3.222335181407633531e+00,
132
                  1.430983188964249919e+00, 2.144317250116257956e+00, 6.596745231472220361e+00, -2.464580889153460852e+00,
133
                  -1.923337901965658681e+00, 2.910328594745831943e+00, -3.123244869063500073e-01, -1.683345539896562659e+00,
134
                  3.785795988845424898e+00, 5.235473328290667361e+00, 8.512526402199654285e+00, 1.393475907195251473e+01,
135
                  1.673386027437856916e+00, -2.910729265724139925e+00, 2.969886703676111184e-01, 1.700051266957717466e+00,
136
                  -5.472121114836264733e-01, 1.716354591332415469e-01, 3.177884264837486317e+00, 0.000000000000000000e+00,
137
                  0.000000000000000000e+00, 1.924354871334499062e-01, 6.568439271753665487e+00, 2.102316342451608644e-01,
138
                  -1.132124603237853355e+00, 7.329625148148498859e+00, 6.606460464951361189e+00, 2.844223241371105271e+00,
139
                  3.078771172794853683e+00, 0.000000000000000000e+00, 2.656884613648917703e+00, 1.779697712165259205e+01,
140
                  0.000000000000000000e+00, -3.457017935109325535e-01, 2.157595478838472414e-01, 3.829196175023549031e+00,
141
                  0.000000000000000000e+00, 1.650776974765602867e-01, 1.357223085191380796e-02, 3.946357663253555081e+00,
142
                  0.000000000000000000e+00, 0.000000000000000000e+00, -2.155616432815957495e+00, 8.213633570666911687e-01,
143
                  1.125480801049912050e-01, 2.684005418659722420e+00, 5.769541257304295900e-01, 1.060883870466023948e+00,
144
                  0.000000000000000000e+00, 0.000000000000000000e+00, 3.413708974045502664e+00, 2.275281553961784553e+00,
145
                  5.176725998383044924e+00, 1.019445219242678835e+00, -1.848344450190015698e+00, 0.000000000000000000e+00,
146
                  0.000000000000000000e+00, 0.000000000000000000e+00, 1.491820649409327126e+00, 0.000000000000000000e+00,
147
                  0.000000000000000000e+00, 9.379741891282449728e+00, 0.000000000000000000e+00, 5.444605374840002510e-01,
148
                  -9.654403640632221173e-02, 2.642171746731144744e+00, 4.626416118226488905e+00, 3.654642208477139498e+00,
149
                  3.427412899258296619e+00, 1.490784083593987397e+01, 2.322393214516801141e+00, 6.511453713852694669e+00,
150
                  6.949721651828602020e+00, 1.186838154505042375e+00, 2.072129970488261197e+00, 0.000000000000000000e+00,
151
                  1.598928631178261561e+00, 5.926083912988970859e-01, -1.612886287403501873e-01, 9.452951868724716045e-01,
152
                  2.145707914290207352e+00, 5.391610489831286657e+00, 8.454389313314318866e-01, 2.372736567215404602e+00,
153
                  -3.130110237826235764e-01, -2.994989290166069740e+00, -2.571950567149417832e+00, -5.018016256298333921e+00,
154
                  -4.851489154898488643e+00, -7.101788768628541249e+00, -5.227281714666618839e+00, -6.351346048086286444e+00,
155
                  -4.558191218464671124e+00, -5.293990544168526213e+00, -2.920034449434862345e-01, 5.166915658100844411e+00,
156
                  4.642130303354632836e+00, -5.246106907306949951e-01, -3.120281208300208498e+00, 1.544764033379846691e+00,
157
                  0.000000000000000000e+00, 3.721469736246234561e+00, -1.083434721745241625e+01, 2.901590918368040395e+00,
158
                  -3.602037909234679258e+00, 0.000000000000000000e+00, 2.736307835089097917e+00, -5.037400262764839987e+00,
159
                  -1.163050013241316849e+00, 6.565863507998260573e+00, 1.872406036485896097e+00, 2.249439295570562880e+00,
160
                  3.276076277814265136e+00, 5.747730113795930684e+00, -2.084335807954610154e+00, 1.812930768433161921e+00,
161
                  0.000000000000000000e+00, -4.068875727535363751e+00, -4.509432609364653205e-02, -1.424182063303933710e+01,
162
                  -1.743400430675688639e+01, 0.000000000000000000e+00, 0.000000000000000000e+00, -8.986019040369217947e+00,
163
                  -2.005955598483518898e+00, 1.514163405869717538e+00, 4.060752357984299010e+00, 1.405971170124569403e+00,
164
                  1.383171915541985708e+00, 4.654452090729912506e+00, -3.395023560174311950e+00, 0.000000000000000000e+00,
165
                  0.000000000000000000e+00, -8.562968788250293173e+00, -1.939561462845156514e+00, 2.627499899415196793e+00,
166
                  4.949794698120698833e+00, 4.355655772643094448e-01, 0.000000000000000000e+00, -1.055190553626396577e+00,
167
                  4.757318838337171840e+00, 3.966536148163406938e+00, 0.000000000000000000e+00, -1.190662117721104352e+01,
168
                  -1.673945042186458121e+00, 0.000000000000000000e+00, -1.203943763219820356e-02, -1.411827841131889194e+00,
169
                  -7.623501643009024109e-01, -6.774873775798392117e+00, 0.000000000000000000e+00, 0.000000000000000000e+00,
170
                  0.000000000000000000e+00, 0.000000000000000000e+00, -1.755294779557688090e+00, 1.542887322103192238e+00,
171
                  0.000000000000000000e+00, -8.228978371972577310e-01, 0.000000000000000000e+00, -5.379142925264499553e+00,
172
                  -1.144060263986041326e+00, 0.000000000000000000e+00, 0.000000000000000000e+00, 4.731108583634047626e+00,
173
                  -1.569393147397664556e+00, -3.449886418134247568e-01, 0.000000000000000000e+00, 1.658412661295906920e+00,
174
                  -5.077151059809188460e+00, -7.326467579034271260e+00, -1.190177296658179840e+00, 0.000000000000000000e+00,
175
                  0.000000000000000000e+00, 0.000000000000000000e+00, -1.914781807241187739e+00, -5.438446604150855457e+00,
176
                  -5.988893208768400811e+00, -7.886849112491050029e+00, -9.355574940159534947e+00, -1.682361325340106006e+01,
177
                  -7.609538696398503888e+00, -7.363350786768400269e+00, -7.366039984795356155e+00, -7.051111570136543882e+00,
178
                  2.337391373249395610e+00, -4.374845402801011574e+01, -3.610863365629191080e+00, 7.684297617701028571e+01,
179
                  2.162851395732025139e+01, 1.066280518306870562e+01, 8.109257308306457901e+01, 5.149561395669890906e+00,
180
                  0.000000000000000000e+00, 3.219993054481156136e+00, 0.000000000000000000e+00, 2.093519725422254396e+01,
181
                  -5.225298528278367272e+00, 0.000000000000000000e+00, 2.159597932230871820e+00, -5.205637201784965384e+01,
182
                  1.601979388461561982e+01, 6.945290207097973401e+00, 8.036724740759808583e-01, 4.712266457087280536e+00,
183
                  2.146353485778652370e+01, 3.470089369007970248e+01, 9.468591086256607170e+00, 9.760488656497257054e-01,
184
                  0.000000000000000000e+00, 0.000000000000000000e+00, 0.000000000000000000e+00, 9.008837970422939323e-01,
185
                  0.000000000000000000e+00, 1.462843531299845168e+01, 0.000000000000000000e+00, 0.000000000000000000e+00,
186
                  -1.179406942091425847e+01, 0.000000000000000000e+00, 1.642473653464513816e+01, 1.387228776263151175e+01,
187
                  0.000000000000000000e+00, 1.613129141280310108e+01, 0.000000000000000000e+00, -1.077318890268341045e+00,
188
                  4.189407459072477802e-01, 0.000000000000000000e+00, -1.570052145651456899e+00, 0.000000000000000000e+00,
189
                  1.120834605828141939e+01, 4.286417457736029490e+01, 0.000000000000000000e+00, 2.938378293327098945e+01,
190
                  1.194087082487160956e+01, 0.000000000000000000e+00, -9.951431855637998813e-02, 3.844291513997798448e-01,
191
                  2.362333099868798669e+01, -1.002532136112976957e+01, 2.427817537309562823e+01, 0.000000000000000000e+00,
192
                  1.076329692188489773e+01, 1.760895870067486157e+00, 2.080295785135324849e+01, -4.335217053626006134e+01,
193
                  -6.272369476984676062e-01, 5.165768790797590881e+00, -4.507215926635629311e-01, 0.000000000000000000e+00,
194
                  -4.242472062530233679e+00, -4.931831554080153168e+00, -2.806203935735193777e+00, -2.670377941558885126e+01,
195
                  0.000000000000000000e+00, -2.124688439238133242e+01, 0.000000000000000000e+00, 0.000000000000000000e+00,
196
                  2.452415244698852970e+00, -1.173727222080745092e+00, 0.000000000000000000e+00, 0.000000000000000000e+00,
197
                  -1.458125295680756039e+01, -1.757703406512062827e+01, 0.000000000000000000e+00, 3.943626521423988951e+00,
198
                  0.000000000000000000e+00, -4.006095410470026152e+00, 1.727171067402430538e+01, -3.412620901789366457e+01,
199
                  0.000000000000000000e+00, 1.760073934312834254e+01, 3.266082201875645552e+01, 0.000000000000000000e+00,
200
                  0.000000000000000000e+00, 0.000000000000000000e+00, 1.514535424913179362e+01, 0.000000000000000000e+00,
201
                  0.000000000000000000e+00, -3.100487758075622935e-01, 0.000000000000000000e+00, 2.387863228159451978e+01,
202
                  1.237098847411416891e+01, 1.154430573879687560e-02, 7.976366278729441817e+00, 0.000000000000000000e+00,
203
                  -6.296727640787388447e-01, 1.406230674131906255e+01, 1.430275589872723430e+01, -2.231764570537816184e+00,
204
                  0.000000000000000000e+00, 5.003869692542436631e+00, 0.000000000000000000e+00, -5.482127427587509594e+00,
205
                  -8.830547931126154992e+00, -5.376776036224484301e+01, -2.918517871695104304e+01, -1.009022417771788049e+01,
206
                  -4.811775051355994037e+00, -1.188016976215758547e+01, -2.055483647266791536e+01, -2.482333959706277327e+01,
207
                  -1.048392515070836950e+01, -3.837352144714887459e+01, 0.000000000000000000e+00, -9.298440675063780247e+00,
208
                  0.000000000000000000e+00, 3.584086297861655890e+00, 0.000000000000000000e+00, 0.000000000000000000e+00,
209
                  0.000000000000000000e+00, 0.000000000000000000e+00, 0.000000000000000000e+00, 1.184271790014085113e+00,
210
                  1.594266439891793219e+01, 0.000000000000000000e+00, 8.473235161049382569e+00, 0.000000000000000000e+00,
211
                  0.000000000000000000e+00, 0.000000000000000000e+00, 6.748879951595517568e+00, 0.000000000000000000e+00,
212
                  0.000000000000000000e+00, -1.057534737660506430e+01, 0.000000000000000000e+00, 0.000000000000000000e+00,
213
                  0.000000000000000000e+00, -3.179879192807419841e+01, 0.000000000000000000e+00, 5.000324879565139824e+00,
214
                  0.000000000000000000e+00, 1.229183419446936654e+00, 0.000000000000000000e+00, 0.000000000000000000e+00,
215
                  0.000000000000000000e+00, 0.000000000000000000e+00, 0.000000000000000000e+00, 0.000000000000000000e+00,
216
                  0.000000000000000000e+00, 0.000000000000000000e+00, 0.000000000000000000e+00, 0.000000000000000000e+00,
217
                  0.000000000000000000e+00, 0.000000000000000000e+00, 0.000000000000000000e+00, 0.000000000000000000e+00,
218
                  4.127983063177185663e+00, 6.616705680943091750e+00, 5.848245769217652601e+00, -1.818944631334333550e+01,
219
                  0.000000000000000000e+00, 0.000000000000000000e+00, 0.000000000000000000e+00, 0.000000000000000000e+00,
220
                  0.000000000000000000e+00, 0.000000000000000000e+00, 0.000000000000000000e+00, 0.000000000000000000e+00,
221
                  2.694838778746875274e+00, 0.000000000000000000e+00, 1.463145767737777625e+01, -4.924734438569850603e+00,
222
                  0.000000000000000000e+00, 1.877377621310543088e+00, 0.000000000000000000e+00, 0.000000000000000000e+00,
223
                  1.971941442729244764e+00, 0.000000000000000000e+00, 0.000000000000000000e+00, 0.000000000000000000e+00,
224
                  0.000000000000000000e+00, 0.000000000000000000e+00, 0.000000000000000000e+00, 0.000000000000000000e+00,
225
                  0.000000000000000000e+00, 0.000000000000000000e+00, 1.732809836566829187e+00, 2.700285877421266534e+01,
226
                  2.915978562591383216e+00, 0.000000000000000000e+00, 0.000000000000000000e+00, -6.999629705176019456e+00,
227
                  0.000000000000000000e+00, 0.000000000000000000e+00, 0.000000000000000000e+00, 1.089611710258455268e+01,
228
                  0.000000000000000000e+00, 0.000000000000000000e+00, 0.000000000000000000e+00, 0.000000000000000000e+00,
229
                  2.121018958070171934e+00, 0.000000000000000000e+00, 0.000000000000000000e+00, 0.000000000000000000e+00,
230
                  -7.416250358067024706e+00, -1.263327458973565065e+01, 0.000000000000000000e+00, 0.000000000000000000e+00,
231
                  0.000000000000000000e+00, 0.000000000000000000e+00, 0.000000000000000000e+00, 2.241612733384156897e+01,
232
                  0.000000000000000000e+00, 8.607688079645482659e+00, 0.000000000000000000e+00, 0.000000000000000000e+00,
233
                  0.000000000000000000e+00, 0.000000000000000000e+00, 1.750217629228628269e+01, 0.000000000000000000e+00,
234
                  0.000000000000000000e+00, 0.000000000000000000e+00, -1.957769005108392690e+01, 0.000000000000000000e+00,
235
                  0.000000000000000000e+00, 0.000000000000000000e+00, 0.000000000000000000e+00, 0.000000000000000000e+00,
236
                  0.000000000000000000e+00, -3.242393079195928784e+00, 0.000000000000000000e+00, 0.000000000000000000e+00,
237
                  0.000000000000000000e+00, 0.000000000000000000e+00, 0.000000000000000000e+00, 0.000000000000000000e+00,
238
                  0.000000000000000000e+00, 0.000000000000000000e+00, 1.348338590741638932e+01, 0.000000000000000000e+00,
239
                  -2.000312276678208392e-02, -7.776608146776987640e-01, 0.000000000000000000e+00, 0.000000000000000000e+00,
240
                  0.000000000000000000e+00, -5.387825733845168941e+00, 0.000000000000000000e+00, 2.153516224136292934e+01,
241
                  0.000000000000000000e+00, 0.000000000000000000e+00, -9.635140703414636576e+00, 2.603288107669730511e+00,
242
};
243
244
/* **************************************** */
245
246
/**
247
 * \fn void ndpi_merge_splt_arrays (const uint16_t *pkt_len, const pkt_timeval *pkt_time,
248
 const uint16_t *pkt_len_twin, const pkt_timeval *pkt_time_twin,
249
 pkt_timeval start_time, pkt_timeval start_time_twin,
250
 uint16_t s_idx, uint16_t r_idx,
251
 uint16_t *merged_lens, uint16_t *merged_times,
252
 uint32_t max_num_pkt_len, uint32_t max_merged_num_pkts)
253
 * \param pkt_len length of the packet
254
 * \param pkt_time time of the packet
255
 * \param pkt_len_twin length of the twin packet
256
 * \param pkt_time_twin time of the twin packet
257
 * \param start_time start time
258
 * \param start_time_twin start time of twin
259
 * \param s_idx s index in the merge
260
 * \param r_idx r index in the merge
261
 * \param merged_lens length of the merge
262
 * \param merged_times time of the merge
263
 * \param max_merged_num_pkts number of packets merged
264
 * \return none
265
 */
266
void
267
ndpi_merge_splt_arrays (const uint16_t *pkt_len, const pkt_timeval *pkt_time,
268
                        const uint16_t *pkt_len_twin, const pkt_timeval *pkt_time_twin,
269
                        pkt_timeval start_time, pkt_timeval start_time_twin,
270
                        uint16_t s_idx, uint16_t r_idx,
271
                        uint16_t *merged_lens, uint16_t *merged_times)
272
11.4M
{
273
11.4M
  int s,r;
274
11.4M
  pkt_timeval ts_start;
275
11.4M
  pkt_timeval tmp, tmp_r;
276
11.4M
  pkt_timeval start_m;
277
278
11.4M
  ndpi_timer_clear(&ts_start);
279
280
11.4M
  if(r_idx + s_idx == 0) {
281
205k
    return ;
282
11.2M
  } else if(r_idx == 0) {
283
7.55M
    ts_start = pkt_time[0];
284
7.55M
    tmp = pkt_time[0];
285
7.55M
    ndpi_timer_sub(&tmp, &start_time, &start_m);
286
7.55M
  } else if(s_idx == 0) {
287
498k
    ts_start = pkt_time_twin[0];
288
498k
    tmp = pkt_time_twin[0];
289
498k
    ndpi_timer_sub(&tmp, &start_time_twin, &start_m);
290
3.15M
  } else {
291
3.15M
    if(ndpi_timer_lt(&start_time, &start_time_twin)) {
292
2.89M
      ts_start = pkt_time[0];
293
2.89M
      tmp = pkt_time[0];
294
2.89M
      ndpi_timer_sub(&tmp, &start_time, &start_m);
295
2.89M
    } else {
296
      //      ts_start = pkt_time_twin[0];
297
264k
      tmp = pkt_time_twin[0];
298
264k
      ndpi_timer_sub(&tmp, &start_time_twin, &start_m);
299
264k
    }
300
3.15M
  }
301
11.2M
  s = r = 0;
302
45.4M
  while ((s < s_idx) || (r < r_idx)) {
303
34.2M
    if(s >= s_idx) {
304
4.40M
      merged_lens[s+r] = pkt_len_twin[r];
305
4.40M
      tmp = pkt_time_twin[r];
306
4.40M
      ndpi_timer_sub(&tmp, &ts_start, &tmp_r);
307
4.40M
      merged_times[s+r] = ndpi_timeval_to_milliseconds(tmp_r);
308
4.40M
      if(merged_times[s+r] == 0)
309
2.24M
  merged_times[s+r] = ndpi_timeval_to_microseconds(tmp_r);
310
4.40M
      ts_start = tmp;
311
4.40M
      r++;
312
29.8M
    } else if(r >= r_idx) {
313
18.5M
      merged_lens[s+r] = pkt_len[s];
314
18.5M
      tmp = pkt_time[s];
315
18.5M
      ndpi_timer_sub(&tmp, &ts_start, &tmp_r);
316
18.5M
      merged_times[s+r] = ndpi_timeval_to_milliseconds(tmp_r);
317
18.5M
      if(merged_times[s+r] == 0)
318
15.0M
  merged_times[s+r] = ndpi_timeval_to_microseconds(tmp_r);
319
18.5M
      ts_start = tmp;
320
18.5M
      s++;
321
18.5M
    } else {
322
11.2M
      if(ndpi_timer_lt(&pkt_time[s], &pkt_time_twin[r])) {
323
6.05M
  merged_lens[s+r] = pkt_len[s];
324
6.05M
  tmp = pkt_time[s];
325
6.05M
  ndpi_timer_sub(&tmp, &ts_start, &tmp_r);
326
6.05M
  merged_times[s+r] = ndpi_timeval_to_milliseconds(tmp_r);
327
6.05M
  if(merged_times[s+r] == 0)
328
4.25M
    merged_times[s+r] = ndpi_timeval_to_microseconds(tmp_r);
329
6.05M
  ts_start = tmp;
330
6.05M
  s++;
331
6.05M
      } else {
332
5.20M
  merged_lens[s+r] = pkt_len_twin[r];
333
5.20M
  tmp = pkt_time_twin[r];
334
5.20M
  ndpi_timer_sub(&tmp, &ts_start, &tmp_r);
335
5.20M
  merged_times[s+r] = ndpi_timeval_to_milliseconds(tmp_r);
336
5.20M
  if(merged_times[s+r] == 0)
337
1.87M
    merged_times[s+r] = ndpi_timeval_to_microseconds(tmp_r);
338
5.20M
  ts_start = tmp;
339
5.20M
  r++;
340
5.20M
      }
341
11.2M
    }
342
34.2M
  }
343
11.2M
  merged_times[0] = ndpi_timeval_to_milliseconds(start_m);
344
11.2M
  if(merged_times[0] == 0)
345
9.01M
    merged_times[0] = ndpi_timeval_to_microseconds(start_m);
346
11.2M
}
347
348
/* **************************************** */
349
350
/* transform lens array to Markov chain */
351
static void
352
ndpi_get_mc_rep_lens (uint16_t *lens, float *length_mc, uint16_t num_packets)
353
11.4M
{
354
11.4M
  float row_sum;
355
11.4M
  int prev_packet_size = 0;
356
11.4M
  int cur_packet_size = 0;
357
11.4M
  int i, j;
358
359
1.15G
  for (i = 0; i < MC_BINS_LEN*MC_BINS_LEN; i++) { // init to 0
360
1.14G
    length_mc[i] = 0.0;
361
1.14G
  }
362
363
11.4M
  if(num_packets == 0) {
364
    // nothing to do
365
11.2M
  } else if(num_packets == 1) {
366
4.54M
    cur_packet_size = (int)min(lens[0]/(float)MC_BIN_SIZE_LEN,(uint16_t)MC_BINS_LEN-1);
367
4.54M
    length_mc[cur_packet_size + cur_packet_size*MC_BINS_LEN] = 1.0;
368
6.66M
  } else {
369
29.6M
    for (i = 1; i < num_packets; i++) {
370
23.0M
      prev_packet_size = (int)min((uint16_t)(lens[i-1]/(float)MC_BIN_SIZE_LEN),(uint16_t)MC_BINS_LEN-1);
371
23.0M
      cur_packet_size = (int)min((uint16_t)(lens[i]/(float)MC_BIN_SIZE_LEN),(uint16_t)MC_BINS_LEN-1);
372
23.0M
      length_mc[prev_packet_size*MC_BINS_LEN + cur_packet_size] += 1.0;
373
23.0M
    }
374
    // normalize rows of Markov chain
375
73.3M
    for (i = 0; i < MC_BINS_LEN; i++) {
376
      // find sum
377
66.6M
      row_sum = 0.0;
378
733M
      for (j = 0; j < MC_BINS_LEN; j++) {
379
666M
  row_sum += length_mc[i*MC_BINS_LEN+j];
380
666M
      }
381
66.6M
      if(row_sum != 0.0) {
382
111M
  for (j = 0; j < MC_BINS_LEN; j++) {
383
101M
    length_mc[i*MC_BINS_LEN+j] /= row_sum;
384
101M
  }
385
10.1M
      }
386
66.6M
    }
387
6.66M
  }
388
11.4M
}
389
390
/* **************************************** */
391
392
/* transform times array to Markov chain */
393
void
394
ndpi_get_mc_rep_times (uint16_t *times, float *time_mc, uint16_t num_packets)
395
11.4M
{
396
11.4M
  float row_sum;
397
11.4M
  int prev_packet_time = 0;
398
11.4M
  int cur_packet_time = 0;
399
11.4M
  int i, j;
400
401
1.15G
  for (i = 0; i < MC_BINS_TIME*MC_BINS_TIME; i++) { // init to 0
402
1.14G
    time_mc[i] = 0.0;
403
1.14G
  }
404
11.4M
  if(num_packets == 0) {
405
    // nothing to do
406
11.2M
  } else if(num_packets == 1) {
407
4.54M
    cur_packet_time = (int)min(times[0]/(float)MC_BIN_SIZE_TIME,(uint16_t)MC_BINS_TIME-1);
408
4.54M
    time_mc[cur_packet_time + cur_packet_time*MC_BINS_TIME] = 1.0;
409
6.66M
  } else {
410
29.6M
    for (i = 1; i < num_packets; i++) {
411
23.0M
      prev_packet_time = (int)min((uint16_t)(times[i-1]/(float)MC_BIN_SIZE_TIME),(uint16_t)MC_BINS_TIME-1);
412
23.0M
      cur_packet_time = (int)min((uint16_t)(times[i]/(float)MC_BIN_SIZE_TIME),(uint16_t)MC_BINS_TIME-1);
413
23.0M
      time_mc[prev_packet_time*MC_BINS_TIME + cur_packet_time] += 1.0;
414
23.0M
    }
415
    // normalize rows of Markov chain
416
73.3M
    for (i = 0; i < MC_BINS_TIME; i++) {
417
      // find sum
418
66.6M
      row_sum = 0.0;
419
733M
      for (j = 0; j < MC_BINS_TIME; j++) {
420
666M
  row_sum += time_mc[i*MC_BINS_TIME+j];
421
666M
      }
422
66.6M
      if(row_sum != 0.0) {
423
129M
  for (j = 0; j < MC_BINS_TIME; j++) {
424
118M
    time_mc[i*MC_BINS_TIME+j] /= row_sum;
425
118M
  }
426
11.8M
      }
427
66.6M
    }
428
6.66M
  }
429
11.4M
}
430
431
/* **************************************** */
432
433
/**
434
 * \fn float classify (const unsigned short *pkt_len, const pkt_timeval *pkt_time,
435
 const unsigned short *pkt_len_twin, const pkt_timeval *pkt_time_twin,
436
 pkt_timeval start_time, pkt_timeval start_time_twin, uint32_t max_num_pkt_len,
437
 uint16_t sp, uint16_t dp, uint32_t op, uint32_t ip, uint32_t np_o, uint32_t np_i,
438
 uint32_t ob, uint32_t ib, uint16_t use_bd, const uint32_t *bd, const uint32_t *bd_t)
439
 * \param pkt_len length of the packet
440
 * \param pkt_time time of the packet
441
 * \param pkt_len_twin length of the packet twin
442
 * \param pkt_time_twin time of the packet twin
443
 * \param start_time start time
444
 * \param start_time_twin start time of the twin
445
 * \param max_num_pkt_len maximum len of number of packets
446
 * \param sp
447
 * \param dp
448
 * \param op
449
 * \param ip
450
 * \param np_o
451
 * \param np_i
452
 * \param ob
453
 * \param ib
454
 * \param use_bd
455
 * \param *bd pointer to bd
456
 * \param *bd_t pointer to bd type
457
 * \return float score
458
 */
459
float
460
ndpi_classify (const unsigned short *pkt_len, const pkt_timeval *pkt_time,
461
               const unsigned short *pkt_len_twin, const pkt_timeval *pkt_time_twin,
462
               pkt_timeval start_time, pkt_timeval start_time_twin, uint32_t max_num_pkt_len,
463
               uint16_t sp, uint16_t dp, uint32_t op, uint32_t ip, uint32_t np_o, uint32_t np_i,
464
11.5M
               uint32_t ob, uint32_t ib, uint16_t use_bd, const uint32_t *bd, const uint32_t *bd_t) {
465
466
11.5M
  float features[NUM_PARAMETERS_BD_LOGREG] = {1.0};
467
11.5M
  float mc_lens[MC_BINS_LEN*MC_BINS_LEN];
468
11.5M
  float mc_times[MC_BINS_TIME*MC_BINS_TIME];
469
11.5M
  uint32_t i;
470
11.5M
  float score = 0.0;
471
472
11.5M
  uint32_t op_n = min(np_o, max_num_pkt_len);
473
11.5M
  uint32_t ip_n = min(np_i, max_num_pkt_len);
474
11.5M
  uint16_t *merged_lens = NULL;
475
11.5M
  uint16_t *merged_times = NULL;
476
477
5.36G
  for (i = 1; i < NUM_PARAMETERS_BD_LOGREG; i++) {
478
5.35G
    features[i] = 0.0;
479
5.35G
  }
480
481
11.5M
  merged_lens = ndpi_calloc(1, sizeof(uint16_t)*(op_n + ip_n));
482
11.5M
  merged_times = ndpi_calloc(1, sizeof(uint16_t)*(op_n + ip_n));
483
484
11.5M
  if(!merged_lens || !merged_times) {
485
141k
    ndpi_free(merged_lens);
486
141k
    ndpi_free(merged_times);
487
141k
    return(score);
488
141k
  }
489
490
  // fill out meta data
491
11.4M
  features[1] = (float)dp; // destination port
492
11.4M
  features[2] = (float)sp; // source port
493
11.4M
  features[3] = (float)ip; // inbound packets
494
11.4M
  features[4] = (float)op; // outbound packets
495
11.4M
  features[5] = (float)ib; // inbound bytes
496
11.4M
  features[6] = (float)ob; // outbound bytes
497
11.4M
  features[7] = 0.0;// skipping 7 until we process the pkt_time arrays
498
499
  // find the raw features
500
11.4M
  ndpi_merge_splt_arrays(pkt_len, pkt_time, pkt_len_twin, pkt_time_twin, start_time, start_time_twin, op_n, ip_n,
501
11.4M
       merged_lens, merged_times);
502
503
  // find new duration
504
45.6M
  for (i = 0; i < op_n+ip_n; i++) {
505
34.2M
    features[7] += (float)merged_times[i];
506
34.2M
  }
507
508
  // get the Markov chain representation for the lengths
509
11.4M
  ndpi_get_mc_rep_lens(merged_lens, mc_lens, op_n+ip_n);
510
511
  // get the Markov chain representation for the times
512
11.4M
  ndpi_get_mc_rep_times(merged_times, mc_times, op_n+ip_n);
513
514
  // fill out lens/times in feature vector
515
1.15G
  for (i = 0; i < MC_BINS_LEN*MC_BINS_LEN; i++) {
516
1.14G
    features[i+8] = mc_lens[i]; // lengths
517
1.14G
  }
518
1.15G
  for (i = 0; i < MC_BINS_TIME*MC_BINS_TIME; i++) {
519
1.14G
    features[i+8+MC_BINS_LEN*MC_BINS_LEN] = mc_times[i]; // times
520
1.14G
  }
521
522
  // fill out byte distribution features
523
11.4M
  if(ob+ib > 100 && use_bd) {
524
1.81G
    for (i = 0; i < NUM_BD_VALUES; i++) {
525
1.80G
      if(pkt_len_twin != NULL) {
526
882M
  features[i+8+MC_BINS_LEN*MC_BINS_LEN+MC_BINS_TIME*MC_BINS_TIME] = (bd[i]+bd_t[i])/((float)(ob+ib));
527
925M
      } else {
528
925M
  features[i+8+MC_BINS_LEN*MC_BINS_LEN+MC_BINS_TIME*MC_BINS_TIME] = bd[i]/((float)(ob));
529
925M
      }
530
1.80G
    }
531
532
7.06M
    score = ndpi_parameters_bd[0];
533
3.27G
    for (i = 1; i < NUM_PARAMETERS_BD_LOGREG; i++) {
534
3.26G
      score += features[i]*ndpi_parameters_bd[i];
535
3.26G
    }
536
7.06M
  } else {
537
910M
    for (i = 0; i < NUM_PARAMETERS_SPLT_LOGREG; i++) {
538
906M
      score += features[i]*ndpi_parameters_splt[i];
539
906M
    }
540
4.35M
  }
541
542
11.4M
  score = min(-score,500.0); // check b/c overflow
543
544
11.4M
  ndpi_free(merged_lens);
545
11.4M
  ndpi_free(merged_times);
546
547
11.4M
  return 1.0/(1.0+exp(score));
548
11.5M
}
549
550
/* **************************************** */
551
552
/**
553
 * \fn void update_params (char *splt_params, char *bd_params)
554
 * \brief if a user supplies new parameter files, update parameters splt/bd
555
 * \param param_type type of new parameters to update
556
 * \param params file name with new parameters
557
 * \reutrn none
558
 */
559
void
560
ndpi_update_params (classifier_type_codes_t param_type, const char *param_file)
561
51.9k
{
562
51.9k
  float param = 0.0;
563
51.9k
  FILE *fp;
564
51.9k
  int count;
565
566
51.9k
  switch (param_type) {
567
17.3k
  case (SPLT_PARAM_TYPE):
568
17.3k
    count = 0;
569
17.3k
    fp = fopen(param_file,"r");
570
17.3k
    if(fp != NULL) {
571
3.60M
      while (fscanf(fp, "%f", &param) != EOF) {
572
3.60M
  ndpi_parameters_splt[count] = param;
573
3.60M
  count++;
574
3.60M
  if(count >= NUM_PARAMETERS_SPLT_LOGREG) {
575
17.3k
    break;
576
17.3k
  }
577
3.60M
      }
578
17.3k
      fclose(fp);
579
17.3k
    }
580
17.3k
    break;
581
582
17.3k
  case (BD_PARAM_TYPE):
583
17.3k
    count = 0;
584
17.3k
    fp = fopen(param_file,"r");
585
17.3k
    if(fp != NULL) {
586
8.03M
      while (fscanf(fp, "%f", &param) != EOF) {
587
8.03M
  ndpi_parameters_bd[count] = param;
588
8.03M
  count++;
589
8.03M
  if(count >= NUM_PARAMETERS_BD_LOGREG) {
590
17.3k
    break;
591
17.3k
  }
592
8.03M
      }
593
17.3k
      fclose(fp);
594
17.3k
    }
595
17.3k
    break;
596
597
17.3k
  default:
598
#if 0
599
    printf("error: unknown paramerter type (%d)", param_type);
600
#endif
601
17.3k
    break;
602
51.9k
  }
603
51.9k
}
604
605
/* **************************************** */
606
607
/* *********************************************************************
608
 * ---------------------------------------------------------------------
609
 *                      Time functions
610
 * For portability and static analysis, we define our own timer
611
 * comparison functions (rather than use non-standard
612
 * timercmp/timersub macros)
613
 * ---------------------------------------------------------------------
614
 * *********************************************************************
615
 */
616
617
/**
618
 * \brief Compare two times to see if they are equal
619
 * \param a First time value
620
 * \param b Second time value
621
 * \return 1 if equal, 0 otherwise
622
 */
623
unsigned int
624
ndpi_timer_eq(const pkt_timeval *a,
625
              const pkt_timeval *b)
626
0
{
627
0
  if(a->tv_sec == b->tv_sec && a->tv_usec == b->tv_usec) {
628
0
    return 1;
629
0
  }
630
631
0
  return 0;
632
0
}
633
634
/* **************************************** */
635
636
unsigned int
637
ndpi_timer_lt(const pkt_timeval *a,
638
              const pkt_timeval *b)
639
14.4M
{
640
14.4M
  return (a->tv_sec == b->tv_sec) ?
641
10.4M
    (a->tv_usec < b->tv_usec):(a->tv_sec < b->tv_sec);
642
14.4M
}
643
644
/**
645
 * \brief Calculate the difference betwen two times (result = a - b)
646
 * \param a First time value
647
 * \param b Second time value
648
 * \param result The difference between the two time values
649
 * \return none
650
 */
651
void
652
ndpi_timer_sub(const pkt_timeval *a,
653
               const pkt_timeval *b,
654
               pkt_timeval *result)
655
58.6M
{
656
58.6M
  result->tv_sec = (unsigned long long)a->tv_sec - (unsigned long long)b->tv_sec;
657
58.6M
  result->tv_usec = (unsigned long long)a->tv_usec - (unsigned long long)b->tv_usec;
658
58.6M
  if(result->tv_usec < 0) {
659
3.35M
    --result->tv_sec;
660
3.35M
    result->tv_usec += 1000000;
661
3.35M
  }
662
58.6M
}
663
664
/* **************************************** */
665
666
/**
667
 * \brief Zeroize a timeval.
668
 * \param a Timeval to zero out
669
 * \return none
670
 */
671
void
672
ndpi_timer_clear(pkt_timeval *a)
673
11.4M
{
674
11.4M
  a->tv_sec = a->tv_usec = 0;
675
11.4M
}
676
677
/* **************************************** */
678
679
/**
680
 * \brief Calculate the milliseconds representation of a timeval.
681
 * \param ts Timeval
682
 * \return unsigned int (64bit) - Milliseconds
683
 */
684
u_int64_t
685
ndpi_timeval_to_milliseconds(pkt_timeval ts)
686
58.3M
{
687
58.3M
  u_int64_t sec = ts.tv_sec;
688
58.3M
  u_int64_t usec = ts.tv_usec;
689
58.3M
  return usec / 1000 + sec * 1000;
690
58.3M
}
691
692
/* **************************************** */
693
694
/**
695
 * \brief Calculate the microseconds representation of a timeval.
696
 * \param ts Timeval
697
 * \return unsigned int (64bit) - Microseconds
698
 */
699
u_int64_t
700
ndpi_timeval_to_microseconds(pkt_timeval ts)
701
32.4M
{
702
32.4M
  u_int64_t sec = ts.tv_sec;
703
32.4M
  u_int64_t usec = ts.tv_usec;
704
32.4M
  return usec + sec * 1000 * 1000;
705
32.4M
}
706
707
/* **************************************** */
708
709
void
710
ndpi_log_timestamp(char *log_ts, uint32_t log_ts_len)
711
6.96k
{
712
6.96k
  pkt_timeval tv;
713
6.96k
  time_t nowtime;
714
6.96k
  struct tm nowtm_r = { 0 };
715
6.96k
  char tmbuf[NDPI_TIMESTAMP_LEN];
716
717
6.96k
  gettimeofday(&tv, NULL);
718
6.96k
  nowtime = tv.tv_sec;
719
#if defined(WIN32) || defined(_MSC_VER)
720
  /* localtime() on Windows is thread-safe */
721
  struct tm * nowtm_r_ptr = localtime(&nowtime);
722
  nowtm_r = *nowtm_r_ptr;
723
#else
724
6.96k
  localtime_r(&nowtime, &nowtm_r);
725
6.96k
#endif
726
6.96k
  strftime(tmbuf, NDPI_TIMESTAMP_LEN, "%H:%M:%S", &nowtm_r);
727
6.96k
  ndpi_snprintf(log_ts, log_ts_len, "%s.%06ld", tmbuf, (long)tv.tv_usec);
728
6.96k
}