Coverage Report

Created: 2025-11-06 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ndpi/src/lib/ndpi_fingerprint.c
Line
Count
Source
1
/*
2
 * ndpi_fingerprint.c
3
 *
4
 * Copyright (C) 2011-25 - ntop.org and contributors
5
 *
6
 * nDPI is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU Lesser General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * nDPI is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public License
17
 * along with nDPI.  If not, see <http://www.gnu.org/licenses/>.
18
 *
19
 */
20
21
22
#include <stdlib.h>
23
#include <errno.h>
24
#include <math.h>
25
#include <sys/types.h>
26
27
#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_UNKNOWN
28
29
#include "ndpi_config.h"
30
#include "ndpi_api.h"
31
#include "ndpi_private.h"
32
33
#include "ndpi_os_fingerprint.c.inc"
34
35
36
/* ************************************************************** */
37
38
0
void ndpi_load_tcp_fingerprints(struct ndpi_detection_module_struct *ndpi_str) {
39
40
0
  if(ndpi_str->tcp_fingerprint_hashmap ||
41
0
     ndpi_hash_init(&ndpi_str->tcp_fingerprint_hashmap) == 0) {
42
0
    u_int i;
43
    
44
0
    for(i=0; tcp_fps[i].fingerprint != NULL; i++)
45
0
      ndpi_add_tcp_fingerprint(ndpi_str, (char*)tcp_fps[i].fingerprint, tcp_fps[i].os);
46
0
  }
47
0
}
48
49
/* ************************************************************** */
50
51
ndpi_os ndpi_get_os_from_tcp_fingerprint(struct ndpi_detection_module_struct *ndpi_str,
52
0
           char *tcp_fingerprint) {  
53
0
  if(tcp_fingerprint && (ndpi_str->tcp_fingerprint_hashmap != NULL)) {
54
0
    u_int64_t ret;
55
    
56
0
    if(ndpi_hash_find_entry(ndpi_str->tcp_fingerprint_hashmap,
57
0
          tcp_fingerprint, strlen(tcp_fingerprint), &ret) == 0)
58
0
      return(ret);
59
0
  }
60
61
0
  return(ndpi_os_unknown);
62
0
}
63
64
/* ************************************************************** */
65
66
/*
67
  Add a new TCP fingerprint
68
69
  Return code:
70
  0   OK
71
  -1  Duplicated fingerprint
72
  -2  Unable to add a new entry
73
 */
74
int ndpi_add_tcp_fingerprint(struct ndpi_detection_module_struct *ndpi_str,
75
0
           char *fingerprint, ndpi_os os) {
76
0
  u_int len;
77
0
  u_int64_t ret;
78
79
0
  len = strlen(fingerprint);
80
81
0
  if((ndpi_str->tcp_fingerprint_hashmap != NULL)
82
0
     && (ndpi_hash_find_entry(ndpi_str->tcp_fingerprint_hashmap, fingerprint, len, &ret) == 0)) {
83
    /* Duplicate fingerprint found */
84
0
    return(-1);
85
0
  } else {
86
0
    if(ndpi_hash_add_entry(&ndpi_str->tcp_fingerprint_hashmap, fingerprint, len,
87
0
         (u_int64_t)os) == 0) {
88
0
      return(0);
89
0
    } else
90
0
      return(-2);
91
0
  }
92
0
}
93
94
/* ******************************************************************** */
95
96
/*
97
 * Format:
98
 *
99
 * <TCP fingerprint>,<numeric OS>
100
 * Example: 2_64_14600_8c07a80cc645,3
101
 *
102
 */
103
int ndpi_load_tcp_fingerprint_file(struct ndpi_detection_module_struct *ndpi_str, const char *path)
104
0
{
105
0
  int rc;
106
0
  FILE *fd;
107
108
0
  if(!ndpi_str || !path)
109
0
    return(-1);
110
111
0
  fd = fopen(path, "r");
112
0
  if(fd == NULL) {
113
0
    NDPI_LOG_ERR(ndpi_str, "Unable to open file %s [%s]\n", path, strerror(errno));
114
0
    return -1;
115
0
  }
116
117
0
  rc = load_tcp_fingerprint_file_fd(ndpi_str, fd);
118
119
0
  fclose(fd);
120
121
0
  return rc;
122
0
}
123
124
/* ******************************************************************** */
125
126
0
int load_tcp_fingerprint_file_fd(struct ndpi_detection_module_struct *ndpi_str, FILE *fd) {
127
0
  char buffer[128];
128
0
  int num = 0;
129
130
0
  if(!ndpi_str || !fd)
131
0
    return(-1);
132
133
0
  if(ndpi_str->tcp_fingerprint_hashmap == NULL
134
0
     && ndpi_hash_init(&ndpi_str->tcp_fingerprint_hashmap) != 0)
135
0
    return(-1);
136
137
0
  while (fgets(buffer, sizeof(buffer), fd) != NULL) {
138
0
    char *fingerprint, *os, *tmp;
139
0
    ndpi_os os_num;
140
0
    size_t len = strlen(buffer);
141
142
0
    if(len <= 1 || buffer[0] == '#')
143
0
      continue;
144
145
0
    fingerprint = strtok_r(buffer, "\t", &tmp);
146
0
    if(!fingerprint) continue;
147
148
0
    os = strtok_r(NULL, "\t", &tmp);
149
0
    if(!os) continue; else os_num = (ndpi_os)atoi(os);
150
151
0
    if(os_num >= ndpi_os_MAX_OS) continue;
152
153
0
    if(ndpi_add_tcp_fingerprint(ndpi_str, fingerprint, os_num) == 0)
154
0
      num++;
155
0
  }
156
157
0
  return num;
158
0
}
159
160
161