1
0

softflowd.c 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007
  1. /*
  2. * Copyright 2002 Damien Miller <djm@mindrot.org> All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. * 1. Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * 2. Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. *
  13. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  14. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  15. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  16. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  17. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  18. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  19. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  20. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  21. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  22. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  23. */
  24. /*
  25. * This is software implementation of Cisco's NetFlow(tm) traffic
  26. * reporting system. It operates by listening (via libpcap) on a
  27. * promiscuous interface and tracking traffic flows.
  28. *
  29. * Traffic flows are recorded by source/destination/protocol
  30. * IP address or, in the case of TCP and UDP, by
  31. * src_addr:src_port/dest_addr:dest_port/protocol
  32. *
  33. * Flows expire automatically after a period of inactivity (default: 1
  34. * hour) They may also be evicted (in order of age) in situations where
  35. * there are more flows than slots available.
  36. *
  37. * Netflow compatible packets are sent to a specified target host upon
  38. * flow expiry.
  39. *
  40. * As this implementation watches traffic promiscuously, it is likely to
  41. * place significant load on hosts or gateways on which it is installed.
  42. */
  43. #include "common.h"
  44. #include "sys-tree.h"
  45. #include "convtime.h"
  46. #include "softflowd.h"
  47. #include "treetype.h"
  48. #include "freelist.h"
  49. #include "log.h"
  50. #include <pcap.h>
  51. /* Global variables */
  52. static int verbose_flag = 0; /* Debugging flag */
  53. static u_int16_t if_index = 0; /* "manual" interface index */
  54. /* Signal handler flags */
  55. static volatile sig_atomic_t graceful_shutdown_request = 0;
  56. /* Context for libpcap callback functions */
  57. struct CB_CTXT {
  58. struct FLOWTRACK *ft;
  59. int linktype;
  60. int fatal;
  61. int want_v6;
  62. };
  63. /* Describes a datalink header and how to extract v4/v6 frames from it */
  64. struct DATALINK {
  65. int dlt; /* BPF datalink type */
  66. int skiplen; /* Number of bytes to skip datalink header */
  67. int ft_off; /* Datalink frametype offset */
  68. int ft_len; /* Datalink frametype length */
  69. int ft_is_be; /* Set if frametype is big-endian */
  70. u_int32_t ft_mask; /* Mask applied to frametype */
  71. u_int32_t ft_v4; /* IPv4 frametype */
  72. u_int32_t ft_v6; /* IPv6 frametype */
  73. };
  74. /* Datalink types that we know about */
  75. static const struct DATALINK lt[] = {
  76. { DLT_EN10MB, 14, 12, 2, 1, 0xffffffff, 0x0800, 0x86dd },
  77. { DLT_PPP, 5, 3, 2, 1, 0xffffffff, 0x0021, 0x0057 },
  78. #ifdef DLT_LINUX_SLL
  79. { DLT_LINUX_SLL,16, 14, 2, 1, 0xffffffff, 0x0800, 0x86dd },
  80. #endif
  81. { DLT_RAW, 0, 0, 1, 1, 0x000000f0, 0x0040, 0x0060 },
  82. { DLT_NULL, 4, 0, 4, 0, 0xffffffff, AF_INET, AF_INET6 },
  83. #ifdef DLT_LOOP
  84. { DLT_LOOP, 4, 0, 4, 1, 0xffffffff, AF_INET, AF_INET6 },
  85. #endif
  86. { -1, -1, -1, -1, -1, 0x00000000, 0xffff, 0xffff },
  87. };
  88. /* Netflow send functions */
  89. typedef int (netflow_send_func_t)(struct FLOW **, int, int, u_int16_t,
  90. u_int64_t *, struct timeval *, int, struct OPTION *);
  91. struct NETFLOW_SENDER {
  92. int version;
  93. netflow_send_func_t *func;
  94. int v6_capable;
  95. };
  96. /* Array of NetFlow export function that we know of. NB. nf[0] is default */
  97. static const struct NETFLOW_SENDER nf[] = {
  98. { 5, send_netflow_v5, 0 },
  99. { 1, send_netflow_v1, 0 },
  100. { 9, send_netflow_v9, 1 },
  101. { -1, NULL, 0 },
  102. };
  103. /* Describes a location where we send NetFlow packets to */
  104. struct NETFLOW_TARGET {
  105. int fd;
  106. const struct NETFLOW_SENDER *dialect;
  107. };
  108. /* Signal handlers */
  109. static void sighand_graceful_shutdown(int signum)
  110. {
  111. graceful_shutdown_request = signum;
  112. }
  113. static void sighand_other(int signum)
  114. {
  115. /* XXX: this may not be completely safe */
  116. logit(LOG_WARNING, "Exiting immediately on unexpected signal %d",
  117. signum);
  118. _exit(0);
  119. }
  120. /*
  121. * This is the flow comparison function.
  122. */
  123. static int
  124. flow_compare(struct FLOW *a, struct FLOW *b)
  125. {
  126. /* Be careful to avoid signed vs unsigned issues here */
  127. int r;
  128. if (a->af != b->af)
  129. return (a->af > b->af ? 1 : -1);
  130. if ((r = memcmp(&a->addr[0], &b->addr[0], sizeof(a->addr[0]))) != 0)
  131. return (r > 0 ? 1 : -1);
  132. if ((r = memcmp(&a->addr[1], &b->addr[1], sizeof(a->addr[1]))) != 0)
  133. return (r > 0 ? 1 : -1);
  134. #ifdef notyet
  135. if (a->ip6_flowlabel[0] != 0 && b->ip6_flowlabel[0] != 0 &&
  136. a->ip6_flowlabel[0] != b->ip6_flowlabel[0])
  137. return (a->ip6_flowlabel[0] > b->ip6_flowlabel[0] ? 1 : -1);
  138. if (a->ip6_flowlabel[1] != 0 && b->ip6_flowlabel[1] != 0 &&
  139. a->ip6_flowlabel[1] != b->ip6_flowlabel[1])
  140. return (a->ip6_flowlabel[1] > b->ip6_flowlabel[1] ? 1 : -1);
  141. #endif
  142. if (a->protocol != b->protocol)
  143. return (a->protocol > b->protocol ? 1 : -1);
  144. if (a->port[0] != b->port[0])
  145. return (ntohs(a->port[0]) > ntohs(b->port[0]) ? 1 : -1);
  146. if (a->port[1] != b->port[1])
  147. return (ntohs(a->port[1]) > ntohs(b->port[1]) ? 1 : -1);
  148. return (0);
  149. }
  150. /* Generate functions for flow tree */
  151. FLOW_PROTOTYPE(FLOWS, FLOW, trp, flow_compare);
  152. FLOW_GENERATE(FLOWS, FLOW, trp, flow_compare);
  153. /*
  154. * This is the expiry comparison function.
  155. */
  156. static int
  157. expiry_compare(struct EXPIRY *a, struct EXPIRY *b)
  158. {
  159. if (a->expires_at != b->expires_at)
  160. return (a->expires_at > b->expires_at ? 1 : -1);
  161. /* Make expiry entries unique by comparing flow sequence */
  162. if (a->flow->flow_seq != b->flow->flow_seq)
  163. return (a->flow->flow_seq > b->flow->flow_seq ? 1 : -1);
  164. return (0);
  165. }
  166. /* Generate functions for flow tree */
  167. EXPIRY_PROTOTYPE(EXPIRIES, EXPIRY, trp, expiry_compare);
  168. EXPIRY_GENERATE(EXPIRIES, EXPIRY, trp, expiry_compare);
  169. static struct FLOW *
  170. flow_get(struct FLOWTRACK *ft)
  171. {
  172. return freelist_get(&ft->flow_freelist);
  173. }
  174. static void
  175. flow_put(struct FLOWTRACK *ft, struct FLOW *flow)
  176. {
  177. return freelist_put(&ft->flow_freelist, flow);
  178. }
  179. static struct EXPIRY *
  180. expiry_get(struct FLOWTRACK *ft)
  181. {
  182. return freelist_get(&ft->expiry_freelist);
  183. }
  184. static void
  185. expiry_put(struct FLOWTRACK *ft, struct EXPIRY *expiry)
  186. {
  187. return freelist_put(&ft->expiry_freelist, expiry);
  188. }
  189. #if 0
  190. /* Dump a packet */
  191. static void
  192. dump_packet(const u_int8_t *p, int len)
  193. {
  194. char buf[1024], tmp[3];
  195. int i;
  196. for (*buf = '\0', i = 0; i < len; i++) {
  197. snprintf(tmp, sizeof(tmp), "%02x%s", p[i], i % 2 ? " " : "");
  198. if (strlcat(buf, tmp, sizeof(buf) - 4) >= sizeof(buf) - 4) {
  199. strlcat(buf, "...", sizeof(buf));
  200. break;
  201. }
  202. }
  203. logit(LOG_INFO, "packet len %d: %s", len, buf);
  204. }
  205. #endif
  206. /* Format a time in an ISOish format */
  207. static const char *
  208. format_time(time_t t)
  209. {
  210. struct tm *tm;
  211. static char buf[32];
  212. tm = gmtime(&t);
  213. strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S", tm);
  214. return (buf);
  215. }
  216. /* Format a flow in a verbose and ugly way */
  217. static const char *
  218. format_flow(struct FLOW *flow)
  219. {
  220. char addr1[64], addr2[64], stime[32], ftime[32];
  221. static char buf[1024];
  222. inet_ntop(flow->af, &flow->addr[0], addr1, sizeof(addr1));
  223. inet_ntop(flow->af, &flow->addr[1], addr2, sizeof(addr2));
  224. snprintf(stime, sizeof(ftime), "%s",
  225. format_time(flow->flow_start.tv_sec));
  226. snprintf(ftime, sizeof(ftime), "%s",
  227. format_time(flow->flow_last.tv_sec));
  228. snprintf(buf, sizeof(buf), "seq:%"PRIu64" [%s]:%hu <> [%s]:%hu proto:%u "
  229. "octets>:%u packets>:%u octets<:%u packets<:%u "
  230. "start:%s.%03ld finish:%s.%03ld tcp>:%02x tcp<:%02x "
  231. "flowlabel>:%08x flowlabel<:%08x ",
  232. flow->flow_seq,
  233. addr1, ntohs(flow->port[0]), addr2, ntohs(flow->port[1]),
  234. (int)flow->protocol,
  235. flow->octets[0], flow->packets[0],
  236. flow->octets[1], flow->packets[1],
  237. stime, (flow->flow_start.tv_usec + 500) / 1000,
  238. ftime, (flow->flow_last.tv_usec + 500) / 1000,
  239. flow->tcp_flags[0], flow->tcp_flags[1],
  240. flow->ip6_flowlabel[0], flow->ip6_flowlabel[1]);
  241. return (buf);
  242. }
  243. /* Format a flow in a brief way */
  244. static const char *
  245. format_flow_brief(struct FLOW *flow)
  246. {
  247. char addr1[64], addr2[64];
  248. static char buf[1024];
  249. inet_ntop(flow->af, &flow->addr[0], addr1, sizeof(addr1));
  250. inet_ntop(flow->af, &flow->addr[1], addr2, sizeof(addr2));
  251. snprintf(buf, sizeof(buf),
  252. "seq:%"PRIu64" [%s]:%hu <> [%s]:%hu proto:%u",
  253. flow->flow_seq,
  254. addr1, ntohs(flow->port[0]), addr2, ntohs(flow->port[1]),
  255. (int)flow->protocol);
  256. return (buf);
  257. }
  258. /* Fill in transport-layer (tcp/udp) portions of flow record */
  259. static int
  260. transport_to_flowrec(struct FLOW *flow, const u_int8_t *pkt,
  261. const size_t caplen, int isfrag, int protocol, int ndx)
  262. {
  263. const struct tcphdr *tcp = (const struct tcphdr *)pkt;
  264. const struct udphdr *udp = (const struct udphdr *)pkt;
  265. const struct icmp *icmp = (const struct icmp *)pkt;
  266. /*
  267. * XXX to keep flow in proper canonical format, it may be necessary to
  268. * swap the array slots based on the order of the port numbers does
  269. * this matter in practice??? I don't think so - return flows will
  270. * always match, because of their symmetrical addr/ports
  271. */
  272. switch (protocol) {
  273. case IPPROTO_TCP:
  274. /* Check for runt packet, but don't error out on short frags */
  275. if (caplen < sizeof(*tcp))
  276. return (isfrag ? 0 : 1);
  277. flow->port[ndx] = tcp->th_sport;
  278. flow->port[ndx ^ 1] = tcp->th_dport;
  279. flow->tcp_flags[ndx] |= tcp->th_flags;
  280. break;
  281. case IPPROTO_UDP:
  282. /* Check for runt packet, but don't error out on short frags */
  283. if (caplen < sizeof(*udp))
  284. return (isfrag ? 0 : 1);
  285. flow->port[ndx] = udp->uh_sport;
  286. flow->port[ndx ^ 1] = udp->uh_dport;
  287. break;
  288. case IPPROTO_ICMP:
  289. /*
  290. * Encode ICMP type * 256 + code into dest port like
  291. * Cisco routers
  292. */
  293. flow->port[ndx] = 0;
  294. flow->port[ndx ^ 1] = htons(icmp->icmp_type * 256 +
  295. icmp->icmp_code);
  296. break;
  297. }
  298. return (0);
  299. }
  300. /* Convert a IPv4 packet to a partial flow record (used for comparison) */
  301. static int
  302. ipv4_to_flowrec(struct FLOW *flow, const u_int8_t *pkt, size_t caplen,
  303. size_t len, int *isfrag, int af)
  304. {
  305. const struct ip *ip = (const struct ip *)pkt;
  306. int ndx;
  307. if (caplen < 20 || caplen < ip->ip_hl * 4)
  308. return (-1); /* Runt packet */
  309. if (ip->ip_v != 4)
  310. return (-1); /* Unsupported IP version */
  311. /* Prepare to store flow in canonical format */
  312. ndx = memcmp(&ip->ip_src, &ip->ip_dst, sizeof(ip->ip_src)) > 0 ? 1 : 0;
  313. flow->af = af;
  314. flow->addr[ndx].v4 = ip->ip_src;
  315. flow->addr[ndx ^ 1].v4 = ip->ip_dst;
  316. flow->protocol = ip->ip_p;
  317. flow->octets[ndx] = len;
  318. flow->packets[ndx] = 1;
  319. *isfrag = (ntohs(ip->ip_off) & (IP_OFFMASK|IP_MF)) ? 1 : 0;
  320. /* Don't try to examine higher level headers if not first fragment */
  321. if (*isfrag && (ntohs(ip->ip_off) & IP_OFFMASK) != 0)
  322. return (0);
  323. return (transport_to_flowrec(flow, pkt + (ip->ip_hl * 4),
  324. caplen - (ip->ip_hl * 4), *isfrag, ip->ip_p, ndx));
  325. }
  326. /* Convert a IPv6 packet to a partial flow record (used for comparison) */
  327. static int
  328. ipv6_to_flowrec(struct FLOW *flow, const u_int8_t *pkt, size_t caplen,
  329. size_t len, int *isfrag, int af)
  330. {
  331. const struct ip6_hdr *ip6 = (const struct ip6_hdr *)pkt;
  332. const struct ip6_ext *eh6;
  333. const struct ip6_frag *fh6;
  334. int ndx, nxt;
  335. if (caplen < sizeof(*ip6))
  336. return (-1); /* Runt packet */
  337. if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION)
  338. return (-1); /* Unsupported IPv6 version */
  339. /* Prepare to store flow in canonical format */
  340. ndx = memcmp(&ip6->ip6_src, &ip6->ip6_dst,
  341. sizeof(ip6->ip6_src)) > 0 ? 1 : 0;
  342. flow->af = af;
  343. flow->ip6_flowlabel[ndx] = ip6->ip6_flow & IPV6_FLOWLABEL_MASK;
  344. flow->addr[ndx].v6 = ip6->ip6_src;
  345. flow->addr[ndx ^ 1].v6 = ip6->ip6_dst;
  346. flow->octets[ndx] = len;
  347. flow->packets[ndx] = 1;
  348. *isfrag = 0;
  349. nxt = ip6->ip6_nxt;
  350. pkt += sizeof(*ip6);
  351. caplen -= sizeof(*ip6);
  352. /* Now loop through headers, looking for transport header */
  353. for (;;) {
  354. eh6 = (const struct ip6_ext *)pkt;
  355. if (nxt == IPPROTO_HOPOPTS ||
  356. nxt == IPPROTO_ROUTING ||
  357. nxt == IPPROTO_DSTOPTS) {
  358. if (caplen < sizeof(*eh6) ||
  359. caplen < (eh6->ip6e_len + 1) << 3)
  360. return (1); /* Runt */
  361. nxt = eh6->ip6e_nxt;
  362. pkt += (eh6->ip6e_len + 1) << 3;
  363. caplen -= (eh6->ip6e_len + 1) << 3;
  364. } else if (nxt == IPPROTO_FRAGMENT) {
  365. *isfrag = 1;
  366. fh6 = (const struct ip6_frag *)eh6;
  367. if (caplen < sizeof(*fh6))
  368. return (1); /* Runt */
  369. /*
  370. * Don't try to examine higher level headers if
  371. * not first fragment
  372. */
  373. if ((fh6->ip6f_offlg & IP6F_OFF_MASK) != 0)
  374. return (0);
  375. nxt = fh6->ip6f_nxt;
  376. pkt += sizeof(*fh6);
  377. caplen -= sizeof(*fh6);
  378. } else
  379. break;
  380. }
  381. flow->protocol = nxt;
  382. return (transport_to_flowrec(flow, pkt, caplen, *isfrag, nxt, ndx));
  383. }
  384. static void
  385. flow_update_expiry(struct FLOWTRACK *ft, struct FLOW *flow)
  386. {
  387. EXPIRY_REMOVE(EXPIRIES, &ft->expiries, flow->expiry);
  388. /* Flows over 2 GiB traffic */
  389. if (flow->octets[0] > (1U << 31) || flow->octets[1] > (1U << 31)) {
  390. flow->expiry->expires_at = 0;
  391. flow->expiry->reason = R_OVERBYTES;
  392. goto out;
  393. }
  394. /* Flows over maximum life seconds */
  395. if (ft->maximum_lifetime != 0 &&
  396. flow->flow_last.tv_sec - flow->flow_start.tv_sec >
  397. ft->maximum_lifetime) {
  398. flow->expiry->expires_at = 0;
  399. flow->expiry->reason = R_MAXLIFE;
  400. goto out;
  401. }
  402. if (flow->protocol == IPPROTO_TCP) {
  403. /* Reset TCP flows */
  404. if (ft->tcp_rst_timeout != 0 &&
  405. ((flow->tcp_flags[0] & TH_RST) ||
  406. (flow->tcp_flags[1] & TH_RST))) {
  407. flow->expiry->expires_at = flow->flow_last.tv_sec +
  408. ft->tcp_rst_timeout;
  409. flow->expiry->reason = R_TCP_RST;
  410. goto out;
  411. }
  412. /* Finished TCP flows */
  413. if (ft->tcp_fin_timeout != 0 &&
  414. ((flow->tcp_flags[0] & TH_FIN) &&
  415. (flow->tcp_flags[1] & TH_FIN))) {
  416. flow->expiry->expires_at = flow->flow_last.tv_sec +
  417. ft->tcp_fin_timeout;
  418. flow->expiry->reason = R_TCP_FIN;
  419. goto out;
  420. }
  421. /* TCP flows */
  422. if (ft->tcp_timeout != 0) {
  423. flow->expiry->expires_at = flow->flow_last.tv_sec +
  424. ft->tcp_timeout;
  425. flow->expiry->reason = R_TCP;
  426. goto out;
  427. }
  428. }
  429. if (ft->udp_timeout != 0 && flow->protocol == IPPROTO_UDP) {
  430. /* UDP flows */
  431. flow->expiry->expires_at = flow->flow_last.tv_sec +
  432. ft->udp_timeout;
  433. flow->expiry->reason = R_UDP;
  434. goto out;
  435. }
  436. if (ft->icmp_timeout != 0 &&
  437. ((flow->af == AF_INET && flow->protocol == IPPROTO_ICMP) ||
  438. ((flow->af == AF_INET6 && flow->protocol == IPPROTO_ICMPV6)))) {
  439. /* ICMP flows */
  440. flow->expiry->expires_at = flow->flow_last.tv_sec +
  441. ft->icmp_timeout;
  442. flow->expiry->reason = R_ICMP;
  443. goto out;
  444. }
  445. /* Everything else */
  446. flow->expiry->expires_at = flow->flow_last.tv_sec +
  447. ft->general_timeout;
  448. flow->expiry->reason = R_GENERAL;
  449. out:
  450. if (ft->maximum_lifetime != 0 && flow->expiry->expires_at != 0) {
  451. flow->expiry->expires_at = MIN(flow->expiry->expires_at,
  452. flow->flow_start.tv_sec + ft->maximum_lifetime);
  453. }
  454. EXPIRY_INSERT(EXPIRIES, &ft->expiries, flow->expiry);
  455. }
  456. /* Return values from process_packet */
  457. #define PP_OK 0
  458. #define PP_BAD_PACKET -2
  459. #define PP_MALLOC_FAIL -3
  460. /*
  461. * Main per-packet processing function. Take a packet (provided by
  462. * libpcap) and attempt to find a matching flow. If no such flow exists,
  463. * then create one.
  464. *
  465. * Also marks flows for fast expiry, based on flow or packet attributes
  466. * (the actual expiry is performed elsewhere)
  467. */
  468. static int
  469. process_packet(struct FLOWTRACK *ft, const u_int8_t *pkt, int af,
  470. const u_int32_t caplen, const u_int32_t len,
  471. const struct timeval *received_time)
  472. {
  473. struct FLOW tmp, *flow;
  474. int frag;
  475. ft->total_packets++;
  476. /* Convert the IP packet to a flow identity */
  477. memset(&tmp, 0, sizeof(tmp));
  478. switch (af) {
  479. case AF_INET:
  480. if (ipv4_to_flowrec(&tmp, pkt, caplen, len, &frag, af) == -1)
  481. goto bad;
  482. break;
  483. case AF_INET6:
  484. if (ipv6_to_flowrec(&tmp, pkt, caplen, len, &frag, af) == -1)
  485. goto bad;
  486. break;
  487. default:
  488. bad:
  489. ft->bad_packets++;
  490. return (PP_BAD_PACKET);
  491. }
  492. if (frag)
  493. ft->frag_packets++;
  494. /* Zero out bits of the flow that aren't relevant to tracking level */
  495. switch (ft->track_level) {
  496. case TRACK_IP_ONLY:
  497. tmp.protocol = 0;
  498. /* FALLTHROUGH */
  499. case TRACK_IP_PROTO:
  500. tmp.port[0] = tmp.port[1] = 0;
  501. tmp.tcp_flags[0] = tmp.tcp_flags[1] = 0;
  502. /* FALLTHROUGH */
  503. case TRACK_FULL:
  504. break;
  505. }
  506. /* If a matching flow does not exist, create and insert one */
  507. if ((flow = FLOW_FIND(FLOWS, &ft->flows, &tmp)) == NULL) {
  508. /* Allocate and fill in the flow */
  509. if ((flow = flow_get(ft)) == NULL) {
  510. logit(LOG_ERR, "process_packet: flow_get failed",
  511. sizeof(*flow));
  512. return (PP_MALLOC_FAIL);
  513. }
  514. memcpy(flow, &tmp, sizeof(*flow));
  515. memcpy(&flow->flow_start, received_time,
  516. sizeof(flow->flow_start));
  517. flow->flow_seq = ft->next_flow_seq++;
  518. FLOW_INSERT(FLOWS, &ft->flows, flow);
  519. /* Allocate and fill in the associated expiry event */
  520. if ((flow->expiry = expiry_get(ft)) == NULL) {
  521. logit(LOG_ERR, "process_packet: expiry_get failed",
  522. sizeof(*flow->expiry));
  523. return (PP_MALLOC_FAIL);
  524. }
  525. flow->expiry->flow = flow;
  526. /* Must be non-zero (0 means expire immediately) */
  527. flow->expiry->expires_at = 1;
  528. flow->expiry->reason = R_GENERAL;
  529. EXPIRY_INSERT(EXPIRIES, &ft->expiries, flow->expiry);
  530. ft->num_flows++;
  531. if (verbose_flag)
  532. logit(LOG_DEBUG, "ADD FLOW %s",
  533. format_flow_brief(flow));
  534. } else {
  535. /* Update flow statistics */
  536. flow->packets[0] += tmp.packets[0];
  537. flow->octets[0] += tmp.octets[0];
  538. flow->tcp_flags[0] |= tmp.tcp_flags[0];
  539. flow->packets[1] += tmp.packets[1];
  540. flow->octets[1] += tmp.octets[1];
  541. flow->tcp_flags[1] |= tmp.tcp_flags[1];
  542. }
  543. memcpy(&flow->flow_last, received_time, sizeof(flow->flow_last));
  544. if (flow->expiry->expires_at != 0)
  545. flow_update_expiry(ft, flow);
  546. return (PP_OK);
  547. }
  548. /*
  549. * Subtract two timevals. Returns (t1 - t2) in milliseconds.
  550. */
  551. u_int32_t
  552. timeval_sub_ms(const struct timeval *t1, const struct timeval *t2)
  553. {
  554. struct timeval res;
  555. res.tv_sec = t1->tv_sec - t2->tv_sec;
  556. res.tv_usec = t1->tv_usec - t2->tv_usec;
  557. if (res.tv_usec < 0) {
  558. res.tv_usec += 1000000L;
  559. res.tv_sec--;
  560. }
  561. return ((u_int32_t)res.tv_sec * 1000 + (u_int32_t)res.tv_usec / 1000);
  562. }
  563. static void
  564. update_statistic(struct STATISTIC *s, double new, double n)
  565. {
  566. if (n == 1.0) {
  567. s->min = s->mean = s->max = new;
  568. return;
  569. }
  570. s->min = MIN(s->min, new);
  571. s->max = MAX(s->max, new);
  572. s->mean = s->mean + ((new - s->mean) / n);
  573. }
  574. /* Update global statistics */
  575. static void
  576. update_statistics(struct FLOWTRACK *ft, struct FLOW *flow)
  577. {
  578. double tmp;
  579. static double n = 1.0;
  580. ft->flows_expired++;
  581. ft->flows_pp[flow->protocol % 256]++;
  582. tmp = (double)flow->flow_last.tv_sec +
  583. ((double)flow->flow_last.tv_usec / 1000000.0);
  584. tmp -= (double)flow->flow_start.tv_sec +
  585. ((double)flow->flow_start.tv_usec / 1000000.0);
  586. if (tmp < 0.0)
  587. tmp = 0.0;
  588. update_statistic(&ft->duration, tmp, n);
  589. update_statistic(&ft->duration_pp[flow->protocol], tmp,
  590. (double)ft->flows_pp[flow->protocol % 256]);
  591. tmp = flow->octets[0] + flow->octets[1];
  592. update_statistic(&ft->octets, tmp, n);
  593. ft->octets_pp[flow->protocol % 256] += tmp;
  594. tmp = flow->packets[0] + flow->packets[1];
  595. update_statistic(&ft->packets, tmp, n);
  596. ft->packets_pp[flow->protocol % 256] += tmp;
  597. n++;
  598. }
  599. static void
  600. update_expiry_stats(struct FLOWTRACK *ft, struct EXPIRY *e)
  601. {
  602. switch (e->reason) {
  603. case R_GENERAL:
  604. ft->expired_general++;
  605. break;
  606. case R_TCP:
  607. ft->expired_tcp++;
  608. break;
  609. case R_TCP_RST:
  610. ft->expired_tcp_rst++;
  611. break;
  612. case R_TCP_FIN:
  613. ft->expired_tcp_fin++;
  614. break;
  615. case R_UDP:
  616. ft->expired_udp++;
  617. break;
  618. case R_ICMP:
  619. ft->expired_icmp++;
  620. break;
  621. case R_MAXLIFE:
  622. ft->expired_maxlife++;
  623. break;
  624. case R_OVERBYTES:
  625. ft->expired_overbytes++;
  626. break;
  627. case R_OVERFLOWS:
  628. ft->expired_maxflows++;
  629. break;
  630. case R_FLUSH:
  631. ft->expired_flush++;
  632. break;
  633. }
  634. }
  635. /* How long before the next expiry event in millisecond */
  636. static int
  637. next_expire(struct FLOWTRACK *ft)
  638. {
  639. struct EXPIRY *expiry;
  640. struct timeval now;
  641. u_int32_t expires_at, ret, fudge;
  642. gettimeofday(&now, NULL);
  643. if ((expiry = EXPIRY_MIN(EXPIRIES, &ft->expiries)) == NULL)
  644. return (-1); /* indefinite */
  645. expires_at = expiry->expires_at;
  646. /* Don't cluster urgent expiries */
  647. if (expires_at == 0 && (expiry->reason == R_OVERBYTES ||
  648. expiry->reason == R_OVERFLOWS || expiry->reason == R_FLUSH))
  649. return (0); /* Now */
  650. /* Cluster expiries by expiry_interval */
  651. if (ft->expiry_interval > 1) {
  652. if ((fudge = expires_at % ft->expiry_interval) > 0)
  653. expires_at += ft->expiry_interval - fudge;
  654. }
  655. if (expires_at < now.tv_sec)
  656. return (0); /* Now */
  657. ret = 999 + (expires_at - now.tv_sec) * 1000;
  658. return (ret);
  659. }
  660. /*
  661. * Scan the tree of expiry events and process expired flows. If zap_all
  662. * is set, then forcibly expire all flows.
  663. */
  664. #define CE_EXPIRE_NORMAL 0 /* Normal expiry processing */
  665. #define CE_EXPIRE_ALL -1 /* Expire all flows immediately */
  666. #define CE_EXPIRE_FORCED 1 /* Only expire force-expired flows */
  667. static int
  668. check_expired(struct FLOWTRACK *ft, struct NETFLOW_TARGET *target, int ex)
  669. {
  670. struct FLOW **expired_flows, **oldexp;
  671. int num_expired, i, r;
  672. struct timeval now;
  673. struct EXPIRY *expiry, *nexpiry;
  674. gettimeofday(&now, NULL);
  675. r = 0;
  676. num_expired = 0;
  677. expired_flows = NULL;
  678. if (verbose_flag)
  679. logit(LOG_DEBUG, "Starting expiry scan: mode %d", ex);
  680. for(expiry = EXPIRY_MIN(EXPIRIES, &ft->expiries);
  681. expiry != NULL;
  682. expiry = nexpiry) {
  683. nexpiry = EXPIRY_NEXT(EXPIRIES, &ft->expiries, expiry);
  684. if ((expiry->expires_at == 0) || (ex == CE_EXPIRE_ALL) ||
  685. (ex != CE_EXPIRE_FORCED &&
  686. (expiry->expires_at < now.tv_sec))) {
  687. /* Flow has expired */
  688. if (ft->maximum_lifetime != 0 &&
  689. expiry->flow->flow_last.tv_sec -
  690. expiry->flow->flow_start.tv_sec >=
  691. ft->maximum_lifetime)
  692. expiry->reason = R_MAXLIFE;
  693. if (verbose_flag)
  694. logit(LOG_DEBUG,
  695. "Queuing flow seq:%"PRIu64" (%p) for expiry "
  696. "reason %d", expiry->flow->flow_seq,
  697. expiry->flow, expiry->reason);
  698. /* Add to array of expired flows */
  699. oldexp = expired_flows;
  700. expired_flows = realloc(expired_flows,
  701. sizeof(*expired_flows) * (num_expired + 1));
  702. /* Don't fatal on realloc failures */
  703. if (expired_flows == NULL)
  704. expired_flows = oldexp;
  705. else {
  706. expired_flows[num_expired] = expiry->flow;
  707. num_expired++;
  708. }
  709. if (ex == CE_EXPIRE_ALL)
  710. expiry->reason = R_FLUSH;
  711. update_expiry_stats(ft, expiry);
  712. /* Remove from flow tree, destroy expiry event */
  713. FLOW_REMOVE(FLOWS, &ft->flows, expiry->flow);
  714. EXPIRY_REMOVE(EXPIRIES, &ft->expiries, expiry);
  715. expiry->flow->expiry = NULL;
  716. expiry_put(ft, expiry);
  717. ft->num_flows--;
  718. }
  719. }
  720. if (verbose_flag)
  721. logit(LOG_DEBUG, "Finished scan %d flow(s) to be evicted",
  722. num_expired);
  723. /* Processing for expired flows */
  724. if (num_expired > 0) {
  725. if (target != NULL && target->fd != -1) {
  726. r = target->dialect->func(expired_flows, num_expired,
  727. target->fd, if_index, &ft->flows_exported,
  728. &ft->system_boot_time, verbose_flag, &ft->option);
  729. if (verbose_flag)
  730. logit(LOG_DEBUG, "sent %d netflow packets", r);
  731. if (r > 0) {
  732. ft->packets_sent += r;
  733. /* XXX what if r < num_expired * 2 ? */
  734. } else {
  735. ft->flows_dropped += num_expired * 2;
  736. }
  737. }
  738. for (i = 0; i < num_expired; i++) {
  739. if (verbose_flag) {
  740. logit(LOG_DEBUG, "EXPIRED: %s (%p)",
  741. format_flow(expired_flows[i]),
  742. expired_flows[i]);
  743. }
  744. update_statistics(ft, expired_flows[i]);
  745. flow_put(ft, expired_flows[i]);
  746. }
  747. free(expired_flows);
  748. }
  749. return (r == -1 ? -1 : num_expired);
  750. }
  751. /*
  752. * Force expiry of num_to_expire flows (e.g. when flow table overfull)
  753. */
  754. static void
  755. force_expire(struct FLOWTRACK *ft, u_int32_t num_to_expire)
  756. {
  757. struct EXPIRY *expiry, **expiryv;
  758. int i;
  759. /* XXX move all overflow processing here (maybe) */
  760. if (verbose_flag)
  761. logit(LOG_INFO, "Forcing expiry of %d flows",
  762. num_to_expire);
  763. /*
  764. * Do this in two steps, as it is dangerous to change a key on
  765. * a tree entry without first removing it and then re-adding it.
  766. * It is even worse when this has to be done during a FOREACH :)
  767. * To get around this, we make a list of expired flows and _then_
  768. * alter them
  769. */
  770. if ((expiryv = calloc(num_to_expire, sizeof(*expiryv))) == NULL) {
  771. /*
  772. * On malloc failure, expire ALL flows. I assume that
  773. * setting all the keys in a tree to the same value is
  774. * safe.
  775. */
  776. logit(LOG_ERR, "Out of memory while expiring flows - "
  777. "all flows expired");
  778. EXPIRY_FOREACH(expiry, EXPIRIES, &ft->expiries) {
  779. expiry->expires_at = 0;
  780. expiry->reason = R_OVERFLOWS;
  781. ft->flows_force_expired++;
  782. }
  783. return;
  784. }
  785. /* Make the list of flows to expire */
  786. i = 0;
  787. EXPIRY_FOREACH(expiry, EXPIRIES, &ft->expiries) {
  788. if (i >= num_to_expire)
  789. break;
  790. expiryv[i++] = expiry;
  791. }
  792. if (i < num_to_expire) {
  793. logit(LOG_ERR, "Needed to expire %d flows, "
  794. "but only %d active", num_to_expire, i);
  795. num_to_expire = i;
  796. }
  797. for(i = 0; i < num_to_expire; i++) {
  798. EXPIRY_REMOVE(EXPIRIES, &ft->expiries, expiryv[i]);
  799. expiryv[i]->expires_at = 0;
  800. expiryv[i]->reason = R_OVERFLOWS;
  801. EXPIRY_INSERT(EXPIRIES, &ft->expiries, expiryv[i]);
  802. }
  803. ft->flows_force_expired += num_to_expire;
  804. free(expiryv);
  805. /* XXX - this is overcomplicated, perhaps use a separate queue */
  806. }
  807. /* Delete all flows that we know about without processing */
  808. static int
  809. delete_all_flows(struct FLOWTRACK *ft)
  810. {
  811. struct FLOW *flow, *nflow;
  812. int i;
  813. i = 0;
  814. for(flow = FLOW_MIN(FLOWS, &ft->flows); flow != NULL; flow = nflow) {
  815. nflow = FLOW_NEXT(FLOWS, &ft->flows, flow);
  816. FLOW_REMOVE(FLOWS, &ft->flows, flow);
  817. EXPIRY_REMOVE(EXPIRIES, &ft->expiries, flow->expiry);
  818. expiry_put(ft, flow->expiry);
  819. ft->num_flows--;
  820. flow_put(ft, flow);
  821. i++;
  822. }
  823. return (i);
  824. }
  825. /*
  826. * Log our current status.
  827. * Includes summary counters and (in verbose mode) the list of current flows
  828. * and the tree of expiry events.
  829. */
  830. static int
  831. statistics(struct FLOWTRACK *ft, FILE *out, pcap_t *pcap)
  832. {
  833. int i;
  834. struct protoent *pe;
  835. char proto[32];
  836. struct pcap_stat ps;
  837. fprintf(out, "Number of active flows: %d\n", ft->num_flows);
  838. fprintf(out, "Packets processed: %"PRIu64"\n", ft->total_packets);
  839. if (ft->non_sampled_packets)
  840. fprintf(out, "Packets non-sampled: %"PRIu64"\n",
  841. ft->non_sampled_packets);
  842. fprintf(out, "Fragments: %"PRIu64"\n", ft->frag_packets);
  843. fprintf(out, "Ignored packets: %"PRIu64" (%"PRIu64" non-IP, %"PRIu64" too short)\n",
  844. ft->non_ip_packets + ft->bad_packets, ft->non_ip_packets, ft->bad_packets);
  845. fprintf(out, "Flows expired: %"PRIu64" (%"PRIu64" forced)\n",
  846. ft->flows_expired, ft->flows_force_expired);
  847. fprintf(out, "Flows exported: %"PRIu64" in %"PRIu64" packets (%"PRIu64" failures)\n",
  848. ft->flows_exported, ft->packets_sent, ft->flows_dropped);
  849. if (pcap_stats(pcap, &ps) == 0) {
  850. fprintf(out, "Packets received by libpcap: %lu\n",
  851. (unsigned long)ps.ps_recv);
  852. fprintf(out, "Packets dropped by libpcap: %lu\n",
  853. (unsigned long)ps.ps_drop);
  854. fprintf(out, "Packets dropped by interface: %lu\n",
  855. (unsigned long)ps.ps_ifdrop);
  856. }
  857. fprintf(out, "\n");
  858. if (ft->flows_expired != 0) {
  859. fprintf(out, "Expired flow statistics: minimum average maximum\n");
  860. fprintf(out, " Flow bytes: %12.0f %12.0f %12.0f\n",
  861. ft->octets.min, ft->octets.mean, ft->octets.max);
  862. fprintf(out, " Flow packets: %12.0f %12.0f %12.0f\n",
  863. ft->packets.min, ft->packets.mean, ft->packets.max);
  864. fprintf(out, " Duration: %12.2fs %12.2fs %12.2fs\n",
  865. ft->duration.min, ft->duration.mean, ft->duration.max);
  866. fprintf(out, "\n");
  867. fprintf(out, "Expired flow reasons:\n");
  868. fprintf(out, " tcp = %9"PRIu64" tcp.rst = %9"PRIu64" "
  869. "tcp.fin = %9"PRIu64"\n", ft->expired_tcp, ft->expired_tcp_rst,
  870. ft->expired_tcp_fin);
  871. fprintf(out, " udp = %9"PRIu64" icmp = %9"PRIu64" "
  872. "general = %9"PRIu64"\n", ft->expired_udp, ft->expired_icmp,
  873. ft->expired_general);
  874. fprintf(out, " maxlife = %9"PRIu64"\n", ft->expired_maxlife);
  875. fprintf(out, "over 2 GiB = %9"PRIu64"\n", ft->expired_overbytes);
  876. fprintf(out, " maxflows = %9"PRIu64"\n", ft->expired_maxflows);
  877. fprintf(out, " flushed = %9"PRIu64"\n", ft->expired_flush);
  878. fprintf(out, "\n");
  879. fprintf(out, "Per-protocol statistics: Octets "
  880. "Packets Avg Life Max Life\n");
  881. for(i = 0; i < 256; i++) {
  882. if (ft->packets_pp[i]) {
  883. pe = getprotobynumber(i);
  884. snprintf(proto, sizeof(proto), "%s (%d)",
  885. pe != NULL ? pe->p_name : "Unknown", i);
  886. fprintf(out, " %17s: %14"PRIu64" %12"PRIu64" %8.2fs "
  887. "%10.2fs\n", proto,
  888. ft->octets_pp[i],
  889. ft->packets_pp[i],
  890. ft->duration_pp[i].mean,
  891. ft->duration_pp[i].max);
  892. }
  893. }
  894. }
  895. return (0);
  896. }
  897. static void
  898. dump_flows(struct FLOWTRACK *ft, FILE *out)
  899. {
  900. struct EXPIRY *expiry;
  901. time_t now;
  902. now = time(NULL);
  903. EXPIRY_FOREACH(expiry, EXPIRIES, &ft->expiries) {
  904. fprintf(out, "ACTIVE %s\n", format_flow(expiry->flow));
  905. if ((long int) expiry->expires_at - now < 0) {
  906. fprintf(out,
  907. "EXPIRY EVENT for flow %"PRIu64" now%s\n",
  908. expiry->flow->flow_seq,
  909. expiry->expires_at == 0 ? " (FORCED)": "");
  910. } else {
  911. fprintf(out,
  912. "EXPIRY EVENT for flow %"PRIu64" in %ld seconds\n",
  913. expiry->flow->flow_seq,
  914. (long int) expiry->expires_at - now);
  915. }
  916. fprintf(out, "\n");
  917. }
  918. }
  919. /*
  920. * Figure out how many bytes to skip from front of packet to get past
  921. * datalink headers. If pkt is specified, also check whether determine
  922. * whether or not it is one that we are interested in (IPv4 or IPv6 for now)
  923. *
  924. * Returns number of bytes to skip or -1 to indicate that entire
  925. * packet should be skipped
  926. */
  927. static int
  928. datalink_check(int linktype, const u_int8_t *pkt, u_int32_t caplen, int *af)
  929. {
  930. int i, j;
  931. u_int32_t frametype;
  932. static const struct DATALINK *dl = NULL;
  933. /* Try to cache last used linktype */
  934. if (dl == NULL || dl->dlt != linktype) {
  935. for (i = 0; lt[i].dlt != linktype && lt[i].dlt != -1; i++)
  936. ;
  937. dl = &lt[i];
  938. }
  939. if (dl->dlt == -1 || pkt == NULL)
  940. return (dl->dlt);
  941. if (caplen <= dl->skiplen)
  942. return (-1);
  943. /* Suck out the frametype */
  944. frametype = 0;
  945. if (dl->ft_is_be) {
  946. for (j = 0; j < dl->ft_len; j++) {
  947. frametype <<= 8;
  948. frametype |= pkt[j + dl->ft_off];
  949. }
  950. } else {
  951. for (j = dl->ft_len - 1; j >= 0 ; j--) {
  952. frametype <<= 8;
  953. frametype |= pkt[j + dl->ft_off];
  954. }
  955. }
  956. frametype &= dl->ft_mask;
  957. if (frametype == dl->ft_v4)
  958. *af = AF_INET;
  959. else if (frametype == dl->ft_v6)
  960. *af = AF_INET6;
  961. else
  962. return (-1);
  963. return (dl->skiplen);
  964. }
  965. /*
  966. * Per-packet callback function from libpcap. Pass the packet (if it is IP)
  967. * sans datalink headers to process_packet.
  968. */
  969. static void
  970. flow_cb(u_char *user_data, const struct pcap_pkthdr* phdr,
  971. const u_char *pkt)
  972. {
  973. int s, af;
  974. struct CB_CTXT *cb_ctxt = (struct CB_CTXT *)user_data;
  975. struct timeval tv;
  976. if (cb_ctxt->ft->option.sample &&
  977. (cb_ctxt->ft->total_packets +
  978. cb_ctxt->ft->non_sampled_packets) %
  979. cb_ctxt->ft->option.sample > 0) {
  980. cb_ctxt->ft->non_sampled_packets++;
  981. return;
  982. }
  983. s = datalink_check(cb_ctxt->linktype, pkt, phdr->caplen, &af);
  984. if (s < 0 || (!cb_ctxt->want_v6 && af == AF_INET6)) {
  985. cb_ctxt->ft->non_ip_packets++;
  986. } else {
  987. tv.tv_sec = phdr->ts.tv_sec;
  988. tv.tv_usec = phdr->ts.tv_usec;
  989. if (process_packet(cb_ctxt->ft, pkt + s, af,
  990. phdr->caplen - s, phdr->len - s, &tv) == PP_MALLOC_FAIL)
  991. cb_ctxt->fatal = 1;
  992. }
  993. }
  994. static void
  995. print_timeouts(struct FLOWTRACK *ft, FILE *out)
  996. {
  997. fprintf(out, " TCP timeout: %ds\n", ft->tcp_timeout);
  998. fprintf(out, " TCP post-RST timeout: %ds\n", ft->tcp_rst_timeout);
  999. fprintf(out, " TCP post-FIN timeout: %ds\n", ft->tcp_fin_timeout);
  1000. fprintf(out, " UDP timeout: %ds\n", ft->udp_timeout);
  1001. fprintf(out, " ICMP timeout: %ds\n", ft->icmp_timeout);
  1002. fprintf(out, " General timeout: %ds\n", ft->general_timeout);
  1003. fprintf(out, " Maximum lifetime: %ds\n", ft->maximum_lifetime);
  1004. fprintf(out, " Expiry interval: %ds\n", ft->expiry_interval);
  1005. }
  1006. static int
  1007. accept_control(int lsock, struct NETFLOW_TARGET *target, struct FLOWTRACK *ft,
  1008. pcap_t *pcap, int *exit_request, int *stop_collection_flag)
  1009. {
  1010. unsigned char buf[64], *p;
  1011. FILE *ctlf;
  1012. int fd, ret;
  1013. if ((fd = accept(lsock, NULL, NULL)) == -1) {
  1014. logit(LOG_ERR, "ctl accept: %s - exiting",
  1015. strerror(errno));
  1016. return(-1);
  1017. }
  1018. if ((ctlf = fdopen(fd, "r+")) == NULL) {
  1019. logit(LOG_ERR, "fdopen: %s - exiting\n",
  1020. strerror(errno));
  1021. close(fd);
  1022. return (-1);
  1023. }
  1024. setlinebuf(ctlf);
  1025. if (fgets(buf, sizeof(buf), ctlf) == NULL) {
  1026. logit(LOG_ERR, "Control socket yielded no data");
  1027. return (0);
  1028. }
  1029. if ((p = strchr(buf, '\n')) != NULL)
  1030. *p = '\0';
  1031. if (verbose_flag)
  1032. logit(LOG_DEBUG, "Control socket \"%s\"", buf);
  1033. /* XXX - use dispatch table */
  1034. ret = -1;
  1035. if (strcmp(buf, "help") == 0) {
  1036. fprintf(ctlf, "Valid control words are:\n");
  1037. fprintf(ctlf, "\tdebug+ debug- delete-all dump-flows exit "
  1038. "expire-all\n");
  1039. fprintf(ctlf, "\tshutdown start-gather statistics stop-gather "
  1040. "timeouts\n");
  1041. fprintf(ctlf, "\tsend-template\n");
  1042. ret = 0;
  1043. } else if (strcmp(buf, "shutdown") == 0) {
  1044. fprintf(ctlf, "softflowd[%u]: Shutting down gracefully...\n",
  1045. getpid());
  1046. graceful_shutdown_request = 1;
  1047. ret = 1;
  1048. } else if (strcmp(buf, "exit") == 0) {
  1049. fprintf(ctlf, "softflowd[%u]: Exiting now...\n", getpid());
  1050. *exit_request = 1;
  1051. ret = 1;
  1052. } else if (strcmp(buf, "expire-all") == 0) {
  1053. netflow9_resend_template();
  1054. fprintf(ctlf, "softflowd[%u]: Expired %d flows.\n", getpid(),
  1055. check_expired(ft, target, CE_EXPIRE_ALL));
  1056. ret = 0;
  1057. } else if (strcmp(buf, "send-template") == 0) {
  1058. netflow9_resend_template();
  1059. fprintf(ctlf, "softflowd[%u]: Template will be sent at "
  1060. "next flow export\n", getpid());
  1061. ret = 0;
  1062. } else if (strcmp(buf, "delete-all") == 0) {
  1063. fprintf(ctlf, "softflowd[%u]: Deleted %d flows.\n", getpid(),
  1064. delete_all_flows(ft));
  1065. ret = 0;
  1066. } else if (strcmp(buf, "statistics") == 0) {
  1067. fprintf(ctlf, "softflowd[%u]: Accumulated statistics "
  1068. "since %s UTC:\n", getpid(),
  1069. format_time(ft->system_boot_time.tv_sec));
  1070. statistics(ft, ctlf, pcap);
  1071. ret = 0;
  1072. } else if (strcmp(buf, "debug+") == 0) {
  1073. fprintf(ctlf, "softflowd[%u]: Debug level increased.\n",
  1074. getpid());
  1075. verbose_flag = 1;
  1076. ret = 0;
  1077. } else if (strcmp(buf, "debug-") == 0) {
  1078. fprintf(ctlf, "softflowd[%u]: Debug level decreased.\n",
  1079. getpid());
  1080. verbose_flag = 0;
  1081. ret = 0;
  1082. } else if (strcmp(buf, "stop-gather") == 0) {
  1083. fprintf(ctlf, "softflowd[%u]: Data collection stopped.\n",
  1084. getpid());
  1085. *stop_collection_flag = 1;
  1086. ret = 0;
  1087. } else if (strcmp(buf, "start-gather") == 0) {
  1088. fprintf(ctlf, "softflowd[%u]: Data collection resumed.\n",
  1089. getpid());
  1090. *stop_collection_flag = 0;
  1091. ret = 0;
  1092. } else if (strcmp(buf, "dump-flows") == 0) {
  1093. fprintf(ctlf, "softflowd[%u]: Dumping flow data:\n",
  1094. getpid());
  1095. dump_flows(ft, ctlf);
  1096. ret = 0;
  1097. } else if (strcmp(buf, "timeouts") == 0) {
  1098. fprintf(ctlf, "softflowd[%u]: Printing timeouts:\n",
  1099. getpid());
  1100. print_timeouts(ft, ctlf);
  1101. ret = 0;
  1102. } else {
  1103. fprintf(ctlf, "Unknown control commmand \"%s\"\n", buf);
  1104. ret = 0;
  1105. }
  1106. fclose(ctlf);
  1107. close(fd);
  1108. return (ret);
  1109. }
  1110. static int
  1111. connsock(struct sockaddr_storage *addr, socklen_t len, int hoplimit)
  1112. {
  1113. int s;
  1114. unsigned int h6;
  1115. unsigned char h4;
  1116. struct sockaddr_in *in4 = (struct sockaddr_in *)addr;
  1117. struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)addr;
  1118. if ((s = socket(addr->ss_family, SOCK_DGRAM, 0)) == -1) {
  1119. fprintf(stderr, "socket() error: %s\n",
  1120. strerror(errno));
  1121. exit(1);
  1122. }
  1123. if (connect(s, (struct sockaddr*)addr, len) == -1) {
  1124. fprintf(stderr, "connect() error: %s\n",
  1125. strerror(errno));
  1126. exit(1);
  1127. }
  1128. switch (addr->ss_family) {
  1129. case AF_INET:
  1130. /* Default to link-local TTL for multicast addresses */
  1131. if (hoplimit == -1 && IN_MULTICAST(in4->sin_addr.s_addr))
  1132. hoplimit = 1;
  1133. if (hoplimit == -1)
  1134. break;
  1135. h4 = hoplimit;
  1136. if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL,
  1137. &h4, sizeof(h4)) == -1) {
  1138. fprintf(stderr, "setsockopt(IP_MULTICAST_TTL, "
  1139. "%u): %s\n", h4, strerror(errno));
  1140. exit(1);
  1141. }
  1142. break;
  1143. case AF_INET6:
  1144. /* Default to link-local hoplimit for multicast addresses */
  1145. if (hoplimit == -1 && IN6_IS_ADDR_MULTICAST(&in6->sin6_addr))
  1146. hoplimit = 1;
  1147. if (hoplimit == -1)
  1148. break;
  1149. h6 = hoplimit;
  1150. if (setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
  1151. &h6, sizeof(h6)) == -1) {
  1152. fprintf(stderr, "setsockopt(IPV6_MULTICAST_HOPS, %u): "
  1153. "%s\n", h6, strerror(errno));
  1154. exit(1);
  1155. }
  1156. }
  1157. return(s);
  1158. }
  1159. static int
  1160. unix_listener(const char *path)
  1161. {
  1162. struct sockaddr_un addr;
  1163. socklen_t addrlen;
  1164. int s;
  1165. memset(&addr, '\0', sizeof(addr));
  1166. addr.sun_family = AF_UNIX;
  1167. if (strlcpy(addr.sun_path, path, sizeof(addr.sun_path)) >=
  1168. sizeof(addr.sun_path)) {
  1169. fprintf(stderr, "control socket path too long\n");
  1170. exit(1);
  1171. }
  1172. addr.sun_path[sizeof(addr.sun_path) - 1] = '\0';
  1173. addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(path) + 1;
  1174. #ifdef SOCK_HAS_LEN
  1175. addr.sun_len = addrlen;
  1176. #endif
  1177. if ((s = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
  1178. fprintf(stderr, "unix domain socket() error: %s\n",
  1179. strerror(errno));
  1180. exit(1);
  1181. }
  1182. unlink(path);
  1183. if (bind(s, (struct sockaddr*)&addr, addrlen) == -1) {
  1184. fprintf(stderr, "unix domain bind(\"%s\") error: %s\n",
  1185. addr.sun_path, strerror(errno));
  1186. exit(1);
  1187. }
  1188. if (listen(s, 64) == -1) {
  1189. fprintf(stderr, "unix domain listen() error: %s\n",
  1190. strerror(errno));
  1191. exit(1);
  1192. }
  1193. return (s);
  1194. }
  1195. static void
  1196. setup_packet_capture(struct pcap **pcap, int *linktype,
  1197. char *dev, char *capfile, char *bpf_prog, int need_v6)
  1198. {
  1199. char ebuf[PCAP_ERRBUF_SIZE];
  1200. struct bpf_program prog_c;
  1201. u_int32_t bpf_mask, bpf_net;
  1202. /* Open pcap */
  1203. if (dev != NULL) {
  1204. if ((*pcap = pcap_open_live(dev,
  1205. need_v6 ? LIBPCAP_SNAPLEN_V6 : LIBPCAP_SNAPLEN_V4,
  1206. 1, 0, ebuf)) == NULL) {
  1207. fprintf(stderr, "pcap_open_live: %s\n", ebuf);
  1208. exit(1);
  1209. }
  1210. if (pcap_lookupnet(dev, &bpf_net, &bpf_mask, ebuf) == -1)
  1211. bpf_net = bpf_mask = 0;
  1212. } else {
  1213. if ((*pcap = pcap_open_offline(capfile, ebuf)) == NULL) {
  1214. fprintf(stderr, "pcap_open_offline(%s): %s\n",
  1215. capfile, ebuf);
  1216. exit(1);
  1217. }
  1218. bpf_net = bpf_mask = 0;
  1219. }
  1220. *linktype = pcap_datalink(*pcap);
  1221. if (datalink_check(*linktype, NULL, 0, NULL) == -1) {
  1222. fprintf(stderr, "Unsupported datalink type %d\n", *linktype);
  1223. exit(1);
  1224. }
  1225. /* Attach BPF filter, if specified */
  1226. if (bpf_prog != NULL) {
  1227. if (pcap_compile(*pcap, &prog_c, bpf_prog, 1, bpf_mask) == -1) {
  1228. fprintf(stderr, "pcap_compile(\"%s\"): %s\n",
  1229. bpf_prog, pcap_geterr(*pcap));
  1230. exit(1);
  1231. }
  1232. if (pcap_setfilter(*pcap, &prog_c) == -1) {
  1233. fprintf(stderr, "pcap_setfilter: %s\n",
  1234. pcap_geterr(*pcap));
  1235. exit(1);
  1236. }
  1237. }
  1238. #ifdef BIOCLOCK
  1239. /*
  1240. * If we are reading from an device (not a file), then
  1241. * lock the underlying BPF device to prevent changes in the
  1242. * unprivileged child
  1243. */
  1244. if (dev != NULL && ioctl(pcap_fileno(*pcap), BIOCLOCK) < 0) {
  1245. fprintf(stderr, "ioctl(BIOCLOCK) failed: %s\n",
  1246. strerror(errno));
  1247. exit(1);
  1248. }
  1249. #endif
  1250. }
  1251. static void
  1252. init_flowtrack(struct FLOWTRACK *ft)
  1253. {
  1254. /* Set up flow-tracking structure */
  1255. memset(ft, '\0', sizeof(*ft));
  1256. ft->next_flow_seq = 1;
  1257. FLOW_INIT(&ft->flows);
  1258. EXPIRY_INIT(&ft->expiries);
  1259. freelist_init(&ft->flow_freelist, sizeof(struct FLOW));
  1260. freelist_init(&ft->expiry_freelist, sizeof(struct EXPIRY));
  1261. ft->max_flows = DEFAULT_MAX_FLOWS;
  1262. ft->track_level = TRACK_FULL;
  1263. ft->tcp_timeout = DEFAULT_TCP_TIMEOUT;
  1264. ft->tcp_rst_timeout = DEFAULT_TCP_RST_TIMEOUT;
  1265. ft->tcp_fin_timeout = DEFAULT_TCP_FIN_TIMEOUT;
  1266. ft->udp_timeout = DEFAULT_UDP_TIMEOUT;
  1267. ft->icmp_timeout = DEFAULT_ICMP_TIMEOUT;
  1268. ft->general_timeout = DEFAULT_GENERAL_TIMEOUT;
  1269. ft->maximum_lifetime = DEFAULT_MAXIMUM_LIFETIME;
  1270. ft->expiry_interval = DEFAULT_EXPIRY_INTERVAL;
  1271. }
  1272. static char *
  1273. argv_join(int argc, char **argv)
  1274. {
  1275. int i;
  1276. size_t ret_len;
  1277. char *ret;
  1278. ret_len = 0;
  1279. ret = NULL;
  1280. for (i = 0; i < argc; i++) {
  1281. ret_len += strlen(argv[i]);
  1282. if ((ret = realloc(ret, ret_len + 2)) == NULL) {
  1283. fprintf(stderr, "Memory allocation failed.\n");
  1284. exit(1);
  1285. }
  1286. if (i == 0)
  1287. ret[0] = '\0';
  1288. else {
  1289. ret_len++; /* Make room for ' ' */
  1290. strlcat(ret, " ", ret_len + 1);
  1291. }
  1292. strlcat(ret, argv[i], ret_len + 1);
  1293. }
  1294. return (ret);
  1295. }
  1296. /* Display commandline usage information */
  1297. static void
  1298. usage(void)
  1299. {
  1300. fprintf(stderr,
  1301. "Usage: %s [options] [bpf_program]\n"
  1302. "This is %s version %s. Valid commandline options:\n"
  1303. " -i [idx:]interface Specify interface to listen on\n"
  1304. " -r pcap_file Specify packet capture file to read\n"
  1305. " -t timeout=time Specify named timeout\n"
  1306. " -m max_flows Specify maximum number of flows to track (default %d)\n"
  1307. " -n host:port Send Cisco NetFlow(tm)-compatible packets to host:port\n"
  1308. " -p pidfile Record pid in specified file\n"
  1309. " (default: %s)\n"
  1310. " -c pidfile Location of control socket\n"
  1311. " (default: %s)\n"
  1312. " -v 1|5|9 NetFlow export packet version\n"
  1313. " -L hoplimit Set TTL/hoplimit for export datagrams\n"
  1314. " -T full|proto|ip Set flow tracking level (default: full)\n"
  1315. " -6 Track IPv6 flows, regardless of whether selected \n"
  1316. " NetFlow export protocol supports it\n"
  1317. " -d Don't daemonise (run in foreground)\n"
  1318. " -D Debug mode: foreground + verbosity + track v6 flows\n"
  1319. " -s sampling_rate Specify periodical sampling rate (denominator)\n"
  1320. " -h Display this help\n"
  1321. "\n"
  1322. "Valid timeout names and default values:\n"
  1323. " tcp (default %6d)"
  1324. " tcp.rst (default %6d)"
  1325. " tcp.fin (default %6d)\n"
  1326. " udp (default %6d)"
  1327. " icmp (default %6d)"
  1328. " general (default %6d)\n"
  1329. " maxlife (default %6d)"
  1330. " expint (default %6d)\n"
  1331. "\n" ,
  1332. PROGNAME, PROGNAME, PROGVER, DEFAULT_MAX_FLOWS, DEFAULT_PIDFILE,
  1333. DEFAULT_CTLSOCK, DEFAULT_TCP_TIMEOUT, DEFAULT_TCP_RST_TIMEOUT,
  1334. DEFAULT_TCP_FIN_TIMEOUT, DEFAULT_UDP_TIMEOUT, DEFAULT_ICMP_TIMEOUT,
  1335. DEFAULT_GENERAL_TIMEOUT, DEFAULT_MAXIMUM_LIFETIME,
  1336. DEFAULT_EXPIRY_INTERVAL);
  1337. }
  1338. static void
  1339. set_timeout(struct FLOWTRACK *ft, const char *to_spec)
  1340. {
  1341. char *name, *value;
  1342. int timeout;
  1343. if ((name = strdup(to_spec)) == NULL) {
  1344. fprintf(stderr, "Out of memory\n");
  1345. exit(1);
  1346. }
  1347. if ((value = strchr(name, '=')) == NULL ||
  1348. *(++value) == '\0') {
  1349. fprintf(stderr, "Invalid -t option \"%s\".\n", name);
  1350. usage();
  1351. exit(1);
  1352. }
  1353. *(value - 1) = '\0';
  1354. timeout = convtime(value);
  1355. if (timeout < 0) {
  1356. fprintf(stderr, "Invalid -t timeout.\n");
  1357. usage();
  1358. exit(1);
  1359. }
  1360. if (strcmp(name, "tcp") == 0)
  1361. ft->tcp_timeout = timeout;
  1362. else if (strcmp(name, "tcp.rst") == 0)
  1363. ft->tcp_rst_timeout = timeout;
  1364. else if (strcmp(name, "tcp.fin") == 0)
  1365. ft->tcp_fin_timeout = timeout;
  1366. else if (strcmp(name, "udp") == 0)
  1367. ft->udp_timeout = timeout;
  1368. else if (strcmp(name, "icmp") == 0)
  1369. ft->icmp_timeout = timeout;
  1370. else if (strcmp(name, "general") == 0)
  1371. ft->general_timeout = timeout;
  1372. else if (strcmp(name, "maxlife") == 0)
  1373. ft->maximum_lifetime = timeout;
  1374. else if (strcmp(name, "expint") == 0)
  1375. ft->expiry_interval = timeout;
  1376. else {
  1377. fprintf(stderr, "Invalid -t name.\n");
  1378. usage();
  1379. exit(1);
  1380. }
  1381. if (ft->general_timeout == 0) {
  1382. fprintf(stderr, "\"general\" flow timeout must be "
  1383. "greater than zero\n");
  1384. exit(1);
  1385. }
  1386. free(name);
  1387. }
  1388. static void
  1389. parse_hostport(const char *s, struct sockaddr *addr, socklen_t *len)
  1390. {
  1391. char *orig, *host, *port;
  1392. struct addrinfo hints, *res;
  1393. int herr;
  1394. if ((host = orig = strdup(s)) == NULL) {
  1395. fprintf(stderr, "Out of memory\n");
  1396. exit(1);
  1397. }
  1398. if ((port = strrchr(host, ':')) == NULL ||
  1399. *(++port) == '\0' || *host == '\0') {
  1400. fprintf(stderr, "Invalid -n argument.\n");
  1401. usage();
  1402. exit(1);
  1403. }
  1404. *(port - 1) = '\0';
  1405. /* Accept [host]:port for numeric IPv6 addresses */
  1406. if (*host == '[' && *(port - 2) == ']') {
  1407. host++;
  1408. *(port - 2) = '\0';
  1409. }
  1410. memset(&hints, '\0', sizeof(hints));
  1411. hints.ai_socktype = SOCK_DGRAM;
  1412. if ((herr = getaddrinfo(host, port, &hints, &res)) == -1) {
  1413. fprintf(stderr, "Address lookup failed: %s\n",
  1414. gai_strerror(herr));
  1415. exit(1);
  1416. }
  1417. if (res == NULL || res->ai_addr == NULL) {
  1418. fprintf(stderr, "No addresses found for [%s]:%s\n", host, port);
  1419. exit(1);
  1420. }
  1421. if (res->ai_addrlen > *len) {
  1422. fprintf(stderr, "Address too long\n");
  1423. exit(1);
  1424. }
  1425. memcpy(addr, res->ai_addr, res->ai_addrlen);
  1426. free(orig);
  1427. *len = res->ai_addrlen;
  1428. }
  1429. /*
  1430. * Drop privileges and chroot, will exit on failure
  1431. */
  1432. static void
  1433. drop_privs(void)
  1434. {
  1435. struct passwd *pw;
  1436. if ((pw = getpwnam(PRIVDROP_USER)) == NULL) {
  1437. logit(LOG_ERR, "Unable to find unprivileged user \"%s\"",
  1438. PRIVDROP_USER);
  1439. exit(1);
  1440. }
  1441. if (chdir(PRIVDROP_CHROOT_DIR) != 0) {
  1442. logit(LOG_ERR, "Unable to chdir to chroot directory \"%s\": %s",
  1443. PRIVDROP_CHROOT_DIR, strerror(errno));
  1444. exit(1);
  1445. }
  1446. if (chroot(PRIVDROP_CHROOT_DIR) != 0) {
  1447. logit(LOG_ERR, "Unable to chroot to directory \"%s\": %s",
  1448. PRIVDROP_CHROOT_DIR, strerror(errno));
  1449. exit(1);
  1450. }
  1451. if (chdir("/") != 0) {
  1452. logit(LOG_ERR, "Unable to chdir to chroot root: %s",
  1453. strerror(errno));
  1454. exit(1);
  1455. }
  1456. if (setgroups(1, &pw->pw_gid) != 0) {
  1457. logit(LOG_ERR, "Couldn't setgroups (%u): %s",
  1458. (unsigned int)pw->pw_gid, strerror(errno));
  1459. exit(1);
  1460. }
  1461. #if defined(HAVE_SETRESGID)
  1462. if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) == -1) {
  1463. #elif defined(HAVE_SETREGID)
  1464. if (setregid(pw->pw_gid, pw->pw_gid) == -1) {
  1465. #else
  1466. if (setegid(pw->pw_gid) == -1 || setgid(pw->pw_gid) == -1) {
  1467. #endif
  1468. logit(LOG_ERR, "Couldn't set gid (%u): %s",
  1469. (unsigned int)pw->pw_gid, strerror(errno));
  1470. exit(1);
  1471. }
  1472. #if defined(HAVE_SETRESUID)
  1473. if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) == -1) {
  1474. #elif defined(HAVE_SETREUID)
  1475. if (setreuid(pw->pw_uid, pw->pw_uid) == -1) {
  1476. #else
  1477. if (seteuid(pw->pw_uid) == -1 || setuid(pw->pw_uid) == -1) {
  1478. #endif
  1479. logit(LOG_ERR, "Couldn't set uid (%u): %s",
  1480. (unsigned int)pw->pw_uid, strerror(errno));
  1481. exit(1);
  1482. }
  1483. }
  1484. int
  1485. main(int argc, char **argv)
  1486. {
  1487. char *dev, *capfile, *bpf_prog, dest_addr[256], dest_serv[256];
  1488. const char *pidfile_path, *ctlsock_path;
  1489. extern char *optarg;
  1490. extern int optind;
  1491. int ch, dontfork_flag, linktype, ctlsock, i, err, always_v6, r;
  1492. int stop_collection_flag, exit_request, hoplimit;
  1493. pcap_t *pcap = NULL;
  1494. struct sockaddr_storage dest;
  1495. struct FLOWTRACK flowtrack;
  1496. socklen_t dest_len;
  1497. struct NETFLOW_TARGET target;
  1498. struct CB_CTXT cb_ctxt;
  1499. struct pollfd pl[2];
  1500. closefrom(STDERR_FILENO + 1);
  1501. init_flowtrack(&flowtrack);
  1502. memset(&dest, '\0', sizeof(dest));
  1503. dest_len = 0;
  1504. memset(&target, '\0', sizeof(target));
  1505. target.fd = -1;
  1506. target.dialect = &nf[0];
  1507. hoplimit = -1;
  1508. bpf_prog = NULL;
  1509. ctlsock = -1;
  1510. dev = capfile = NULL;
  1511. pidfile_path = DEFAULT_PIDFILE;
  1512. ctlsock_path = DEFAULT_CTLSOCK;
  1513. dontfork_flag = 0;
  1514. always_v6 = 0;
  1515. while ((ch = getopt(argc, argv, "6hdDL:T:i:r:f:t:n:m:p:c:v:s:")) != -1) {
  1516. switch (ch) {
  1517. case '6':
  1518. always_v6 = 1;
  1519. break;
  1520. case 'h':
  1521. usage();
  1522. return (0);
  1523. case 'D':
  1524. verbose_flag = 1;
  1525. always_v6 = 1;
  1526. /* FALLTHROUGH */
  1527. case 'd':
  1528. dontfork_flag = 1;
  1529. break;
  1530. case 'i':
  1531. if (capfile != NULL || dev != NULL) {
  1532. fprintf(stderr, "Packet source already "
  1533. "specified.\n\n");
  1534. usage();
  1535. exit(1);
  1536. }
  1537. dev = strsep(&optarg, ":");
  1538. if (optarg != NULL) {
  1539. if_index = (u_int16_t) atoi(dev);
  1540. dev = optarg;
  1541. }
  1542. if (verbose_flag)
  1543. fprintf(stderr, "Using %s (idx: %d)\n", dev, if_index);
  1544. break;
  1545. case 'r':
  1546. if (capfile != NULL || dev != NULL) {
  1547. fprintf(stderr, "Packet source already "
  1548. "specified.\n\n");
  1549. usage();
  1550. exit(1);
  1551. }
  1552. capfile = optarg;
  1553. dontfork_flag = 1;
  1554. ctlsock_path = NULL;
  1555. break;
  1556. case 't':
  1557. /* Will exit on failure */
  1558. set_timeout(&flowtrack, optarg);
  1559. break;
  1560. case 'T':
  1561. if (strcasecmp(optarg, "full") == 0)
  1562. flowtrack.track_level = TRACK_FULL;
  1563. else if (strcasecmp(optarg, "proto") == 0)
  1564. flowtrack.track_level = TRACK_IP_PROTO;
  1565. else if (strcasecmp(optarg, "ip") == 0)
  1566. flowtrack.track_level = TRACK_IP_ONLY;
  1567. else {
  1568. fprintf(stderr, "Unknown flow tracking "
  1569. "level\n");
  1570. usage();
  1571. exit(1);
  1572. }
  1573. break;
  1574. case 'L':
  1575. hoplimit = atoi(optarg);
  1576. if (hoplimit < 0 || hoplimit > 255) {
  1577. fprintf(stderr, "Invalid hop limit\n\n");
  1578. usage();
  1579. exit(1);
  1580. }
  1581. break;
  1582. case 'm':
  1583. if ((flowtrack.max_flows = atoi(optarg)) < 0) {
  1584. fprintf(stderr, "Invalid maximum flows\n\n");
  1585. usage();
  1586. exit(1);
  1587. }
  1588. break;
  1589. case 'n':
  1590. /* Will exit on failure */
  1591. dest_len = sizeof(dest);
  1592. parse_hostport(optarg, (struct sockaddr *)&dest,
  1593. &dest_len);
  1594. break;
  1595. case 'p':
  1596. pidfile_path = optarg;
  1597. break;
  1598. case 'c':
  1599. if (strcmp(optarg, "none") == 0)
  1600. ctlsock_path = NULL;
  1601. else
  1602. ctlsock_path = optarg;
  1603. break;
  1604. case 'v':
  1605. for(i = 0, r = atoi(optarg); nf[i].version != -1; i++) {
  1606. if (nf[i].version == r)
  1607. break;
  1608. }
  1609. if (nf[i].version == -1) {
  1610. fprintf(stderr, "Invalid NetFlow version\n");
  1611. exit(1);
  1612. }
  1613. target.dialect = &nf[i];
  1614. break;
  1615. case 's':
  1616. flowtrack.option.sample = atoi(optarg);
  1617. if (flowtrack.option.sample < 2) {
  1618. flowtrack.option.sample = 0;
  1619. }
  1620. break;
  1621. default:
  1622. fprintf(stderr, "Invalid commandline option.\n");
  1623. usage();
  1624. exit(1);
  1625. }
  1626. }
  1627. if (capfile == NULL && dev == NULL) {
  1628. fprintf(stderr, "-i or -r option not specified.\n");
  1629. usage();
  1630. exit(1);
  1631. }
  1632. /* join remaining arguments (if any) into bpf program */
  1633. bpf_prog = argv_join(argc - optind, argv + optind);
  1634. /* Will exit on failure */
  1635. setup_packet_capture(&pcap, &linktype, dev, capfile, bpf_prog,
  1636. target.dialect->v6_capable || always_v6);
  1637. /* Netflow send socket */
  1638. if (dest.ss_family != 0) {
  1639. if ((err = getnameinfo((struct sockaddr *)&dest,
  1640. dest_len, dest_addr, sizeof(dest_addr),
  1641. dest_serv, sizeof(dest_serv), NI_NUMERICHOST)) == -1) {
  1642. fprintf(stderr, "getnameinfo: %d\n", err);
  1643. exit(1);
  1644. }
  1645. target.fd = connsock(&dest, dest_len, hoplimit);
  1646. }
  1647. /* Control socket */
  1648. if (ctlsock_path != NULL)
  1649. ctlsock = unix_listener(ctlsock_path); /* Will exit on fail */
  1650. if (dontfork_flag) {
  1651. loginit(PROGNAME, 1);
  1652. } else {
  1653. FILE *pidfile;
  1654. r = daemon(0, 0);
  1655. loginit(PROGNAME, 0);
  1656. if ((pidfile = fopen(pidfile_path, "w")) == NULL) {
  1657. fprintf(stderr, "Couldn't open pidfile %s: %s\n",
  1658. pidfile_path, strerror(errno));
  1659. exit(1);
  1660. }
  1661. fprintf(pidfile, "%u\n", getpid());
  1662. fclose(pidfile);
  1663. signal(SIGINT, sighand_graceful_shutdown);
  1664. signal(SIGTERM, sighand_graceful_shutdown);
  1665. signal(SIGSEGV, sighand_other);
  1666. setprotoent(1);
  1667. drop_privs();
  1668. }
  1669. logit(LOG_NOTICE, "%s v%s starting data collection",
  1670. PROGNAME, PROGVER);
  1671. if (dest.ss_family != 0) {
  1672. logit(LOG_NOTICE, "Exporting flows to [%s]:%s",
  1673. dest_addr, dest_serv);
  1674. }
  1675. /* Main processing loop */
  1676. gettimeofday(&flowtrack.system_boot_time, NULL);
  1677. stop_collection_flag = 0;
  1678. memset(&cb_ctxt, '\0', sizeof(cb_ctxt));
  1679. cb_ctxt.ft = &flowtrack;
  1680. cb_ctxt.linktype = linktype;
  1681. cb_ctxt.want_v6 = target.dialect->v6_capable || always_v6;
  1682. for (r = 0; graceful_shutdown_request == 0; r = 0) {
  1683. /*
  1684. * Silly libpcap's timeout function doesn't work, so we
  1685. * do it here (only if we are reading live)
  1686. */
  1687. if (capfile == NULL) {
  1688. memset(pl, '\0', sizeof(pl));
  1689. /* This can only be set via the control socket */
  1690. if (!stop_collection_flag) {
  1691. pl[0].events = POLLIN|POLLERR|POLLHUP;
  1692. pl[0].fd = pcap_fileno(pcap);
  1693. }
  1694. if (ctlsock != -1) {
  1695. pl[1].fd = ctlsock;
  1696. pl[1].events = POLLIN|POLLERR|POLLHUP;
  1697. }
  1698. r = poll(pl, (ctlsock == -1) ? 1 : 2,
  1699. next_expire(&flowtrack));
  1700. if (r == -1 && errno != EINTR) {
  1701. logit(LOG_ERR, "Exiting on poll: %s",
  1702. strerror(errno));
  1703. break;
  1704. }
  1705. }
  1706. /* Accept connection on control socket if present */
  1707. if (ctlsock != -1 && pl[1].revents != 0) {
  1708. if (accept_control(ctlsock, &target, &flowtrack, pcap,
  1709. &exit_request, &stop_collection_flag) != 0)
  1710. break;
  1711. }
  1712. /* If we have data, run it through libpcap */
  1713. if (!stop_collection_flag &&
  1714. (capfile != NULL || pl[0].revents != 0)) {
  1715. r = pcap_dispatch(pcap, flowtrack.max_flows, flow_cb,
  1716. (void*)&cb_ctxt);
  1717. if (r == -1) {
  1718. logit(LOG_ERR, "Exiting on pcap_dispatch: %s",
  1719. pcap_geterr(pcap));
  1720. break;
  1721. } else if (r == 0 && capfile != NULL) {
  1722. logit(LOG_NOTICE, "Shutting down after "
  1723. "pcap EOF");
  1724. graceful_shutdown_request = 1;
  1725. break;
  1726. }
  1727. }
  1728. r = 0;
  1729. /* Fatal error from per-packet functions */
  1730. if (cb_ctxt.fatal) {
  1731. logit(LOG_WARNING, "Fatal error - exiting immediately");
  1732. break;
  1733. }
  1734. /*
  1735. * Expiry processing happens every recheck_rate seconds
  1736. * or whenever we have exceeded the maximum number of active
  1737. * flows
  1738. */
  1739. if (flowtrack.num_flows > flowtrack.max_flows ||
  1740. next_expire(&flowtrack) == 0) {
  1741. expiry_check:
  1742. /*
  1743. * If we are reading from a capture file, we never
  1744. * expire flows based on time - instead we only
  1745. * expire flows when the flow table is full.
  1746. */
  1747. if (check_expired(&flowtrack, &target,
  1748. capfile == NULL ? CE_EXPIRE_NORMAL :
  1749. CE_EXPIRE_FORCED) < 0)
  1750. logit(LOG_WARNING, "Unable to export flows");
  1751. /*
  1752. * If we are over max_flows, force-expire the oldest
  1753. * out first and immediately reprocess to evict them
  1754. */
  1755. if (flowtrack.num_flows > flowtrack.max_flows) {
  1756. force_expire(&flowtrack,
  1757. flowtrack.num_flows - flowtrack.max_flows);
  1758. goto expiry_check;
  1759. }
  1760. }
  1761. }
  1762. /* Flags set by signal handlers or control socket */
  1763. if (graceful_shutdown_request) {
  1764. logit(LOG_WARNING, "Shutting down on user request");
  1765. check_expired(&flowtrack, &target, CE_EXPIRE_ALL);
  1766. } else if (exit_request)
  1767. logit(LOG_WARNING, "Exiting immediately on user request");
  1768. else
  1769. logit(LOG_ERR, "Exiting immediately on internal error");
  1770. if (capfile != NULL && dontfork_flag)
  1771. statistics(&flowtrack, stdout, pcap);
  1772. pcap_close(pcap);
  1773. if (target.fd != -1)
  1774. close(target.fd);
  1775. unlink(pidfile_path);
  1776. if (ctlsock_path != NULL)
  1777. unlink(ctlsock_path);
  1778. return(r == 0 ? 0 : 1);
  1779. }