Coverage Report

Created: 2026-04-04 07:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ndpi/src/lib/protocols/netflow.c
Line
Count
Source
1
/*
2
 * netflow.c
3
 *
4
 * Copyright (C) 2011-26 - ntop.org
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
#include "ndpi_protocol_ids.h"
22
23
#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_NETFLOW
24
25
#include "ndpi_api.h"
26
#include "ndpi_private.h"
27
28
29
#ifdef WIN32
30
extern int gettimeofday(struct timeval * tp, struct timezone * tzp);
31
#endif
32
2.60k
#define do_gettimeofday(a) gettimeofday(a, NULL)
33
34
struct flow_ver1_rec {
35
  u_int32_t srcaddr;    /* Source IP Address */
36
  u_int32_t dstaddr;    /* Destination IP Address */
37
  u_int32_t nexthop;    /* Next hop router's IP Address */
38
  u_int16_t input;      /* Input interface index */
39
  u_int16_t output;     /* Output interface index */
40
  u_int32_t dPkts;      /* Packets sent in Duration */
41
  u_int32_t dOctets;    /* Octets sent in Duration */
42
  u_int32_t first;      /* SysUptime at start of flow */
43
  u_int32_t last;       /* and of last packet of the flow */
44
  u_int16_t srcport;    /* TCP/UDP source port number (.e.g, FTP, Telnet, etc.,or equivalent) */
45
  u_int16_t dstport;    /* TCP/UDP destination port number (.e.g, FTP, Telnet, etc.,or equivalent) */
46
  u_int16_t pad;        /* pad to word boundary */
47
  u_int8_t  proto;      /* IP protocol, e.g., 6=TCP, 17=UDP, etc... */
48
  u_int8_t  tos;        /* IP Type-of-Service */
49
  u_int8_t  pad2[7];    /* pad to word boundary */
50
};
51
52
struct flow_ver5_rec {
53
  u_int32_t srcaddr;    /* Source IP Address */
54
  u_int32_t dstaddr;    /* Destination IP Address */
55
  u_int32_t nexthop;    /* Next hop router's IP Address */
56
  u_int16_t input;      /* Input interface index */
57
  u_int16_t output;     /* Output interface index */
58
  u_int32_t dPkts;      /* Packets sent in Duration (milliseconds between 1st
59
         & last packet in this flow)*/
60
  u_int32_t dOctets;    /* Octets sent in Duration (milliseconds between 1st
61
         & last packet in  this flow)*/
62
  u_int32_t first;      /* SysUptime at start of flow */
63
  u_int32_t last;       /* and of last packet of the flow */
64
  u_int16_t srcport;    /* TCP/UDP source port number (.e.g, FTP, Telnet, etc.,or equivalent) */
65
  u_int16_t dstport;    /* TCP/UDP destination port number (.e.g, FTP, Telnet, etc.,or equivalent) */
66
  u_int8_t pad1;        /* pad to word boundary */
67
  u_int8_t tcp_flags;   /* Cumulative OR of tcp flags */
68
  u_int8_t proto;        /* IP protocol, e.g., 6=TCP, 17=UDP, etc... */
69
  u_int8_t tos;         /* IP Type-of-Service */
70
  u_int16_t src_as;     /* source peer/origin Autonomous System */
71
  u_int16_t dst_as;     /* dst peer/origin Autonomous System */
72
  u_int8_t src_mask;    /* source route's mask bits */
73
  u_int8_t dst_mask;    /* destination route's mask bits */
74
  u_int16_t pad2;       /* pad to word boundary */
75
};
76
77
struct flow_ver7_rec {
78
  u_int32_t srcaddr;    /* Source IP Address */
79
  u_int32_t dstaddr;    /* Destination IP Address */
80
  u_int32_t nexthop;    /* Next hop router's IP Address */
81
  u_int16_t input;      /* Input interface index */
82
  u_int16_t output;     /* Output interface index */
83
  u_int32_t dPkts;      /* Packets sent in Duration */
84
  u_int32_t dOctets;    /* Octets sent in Duration */
85
  u_int32_t first;      /* SysUptime at start of flow */
86
  u_int32_t last;       /* and of last packet of the flow */
87
  u_int16_t srcport;    /* TCP/UDP source port number (.e.g, FTP, Telnet, etc.,or equivalent) */
88
  u_int16_t dstport;    /* TCP/UDP destination port number (.e.g, FTP, Telnet, etc.,or equivalent) */
89
  u_int8_t  flags;      /* Shortcut mode(dest only,src only,full flows*/
90
  u_int8_t  tcp_flags;  /* Cumulative OR of tcp flags */
91
  u_int8_t  proto;      /* IP protocol, e.g., 6=TCP, 17=UDP, etc... */
92
  u_int8_t  tos;        /* IP Type-of-Service */
93
  u_int16_t dst_as;     /* dst peer/origin Autonomous System */
94
  u_int16_t src_as;     /* source peer/origin Autonomous System */
95
  u_int8_t  dst_mask;   /* destination route's mask bits */
96
  u_int8_t  src_mask;   /* source route's mask bits */
97
  u_int16_t pad2;       /* pad to word boundary */
98
  u_int32_t router_sc;  /* Router which is shortcut by switch */
99
};
100
101
static void ndpi_search_netflow(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
102
1.00M
{
103
1.00M
  struct ndpi_packet_struct *packet = &ndpi_struct->packet;
104
  // const u_int8_t *packet_payload = packet->payload;
105
1.00M
  u_int32_t payload_len = packet->payload_packet_len;
106
1.00M
  time_t now;
107
1.00M
  struct timeval now_tv;
108
109
1.00M
  NDPI_LOG_DBG(ndpi_struct, "search netflow\n");
110
111
1.00M
  if((packet->udp != NULL) && (payload_len >= 24)) {
112
796k
    u_int16_t version = (packet->payload[0] << 8) + packet->payload[1], uptime_offset;
113
796k
    u_int32_t when, *_when;
114
796k
    u_int16_t n = (packet->payload[2] << 8) + packet->payload[3], expected_len = 0;
115
116
796k
    switch(version) {
117
15.1k
    case 1:
118
18.7k
    case 5:
119
19.1k
    case 7:
120
20.6k
    case 9:
121
20.6k
      if((n == 0) || (n > 30)) {
122
15.4k
  NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow);
123
15.4k
  return;
124
15.4k
      }
125
      
126
5.24k
      switch(version) {
127
3.60k
      case 1:
128
3.60k
  expected_len = n * sizeof(struct flow_ver1_rec) + 16 /* header */;
129
3.60k
  break;
130
131
397
      case 5:
132
397
  expected_len = n * sizeof(struct flow_ver5_rec) + 24 /* header */;
133
397
  break;
134
135
161
      case 7:
136
161
  expected_len = n * sizeof(struct flow_ver7_rec) + 24 /* header */;
137
161
  break;
138
139
1.08k
      case 9:
140
  /* We need to check the template */
141
1.08k
  break;
142
5.24k
      }
143
144
5.24k
      if((expected_len > 0) && (expected_len != payload_len)) {
145
3.05k
  NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow);
146
3.05k
  return;
147
3.05k
      }
148
149
2.18k
      uptime_offset = 8;
150
2.18k
      break;
151
152
743
    case 10: /* IPFIX */
153
743
      {      
154
743
  u_int16_t ipfix_len = n;
155
156
743
  if(ipfix_len != payload_len) {
157
325
    NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow);
158
325
    return;
159
325
  }
160
743
      }    
161
418
      uptime_offset = 4;
162
418
      break;
163
      
164
774k
    default:
165
774k
      NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow);
166
774k
      return;
167
796k
    }
168
169
2.60k
    _when = (u_int32_t*)&packet->payload[uptime_offset]; /* Sysuptime */
170
2.60k
    when = ntohl(*_when);
171
172
2.60k
    do_gettimeofday(&now_tv);
173
2.60k
    now = now_tv.tv_sec;
174
175
2.60k
    if(((version == 1) && (when == 0))
176
2.54k
       || ((when >= 946684800 /* 1/1/2000 */) && (when <= (u_int32_t)now))) {
177
201
      NDPI_LOG_INFO(ndpi_struct, "found netflow\n");
178
201
      ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_NETFLOW, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI);
179
201
      return;
180
201
    }
181
2.60k
  } else
182
207k
    NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow);
183
1.00M
}
184
185
void init_netflow_dissector(struct ndpi_detection_module_struct *ndpi_struct)
186
15.7k
{
187
15.7k
  ndpi_register_dissector("NetFlow", ndpi_struct,
188
15.7k
                     ndpi_search_netflow,
189
15.7k
                     NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD,
190
15.7k
                     1, NDPI_PROTOCOL_NETFLOW);
191
15.7k
}
192