1 /*-
2  * Copyright (c) 2002, 2003, 2004 Lev Walkin <vlm@lionet.info>.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  * $Id: storage.h,v 1.11 2004/11/12 06:38:03 vlm Exp $
27  */
28 
29 #ifndef	__STORAGE_H__
30 #define	__STORAGE_H__
31 
32 #include "headers.h"
33 
34 /*
35  * Structure describing the single flow.
36  */
37 typedef struct flow_s {
38 	/*
39 	 * Flow source and destination.
40 	 */
41 	struct in_addr src;	/* Source IP address */
42 	struct in_addr dst;	/* Destination IP address */
43 
44 	/* Ports gathered when "capture-ports enable" is set */
45 	int	src_port;	/* Source IP port (-1 if not available) */
46 	int	dst_port;	/* Destination IP port (-1 if not available) */
47 
48 	/*
49 	 * Flow counters.
50 	 */
51 	unsigned long long bytes;
52 	size_t	packets;
53 
54 	/*
55 	 * Things meaningful if NetFlow is enabled.
56 	 */
57 	void	*ifSource;	/* Packet source */
58 	u_char	src_mask;	/* Source IP prefix mask bits */
59 	u_char	dst_mask;	/* Destination IP prefix mask bits */
60 	u_char	ip_p;		/* IP Protocol */
61 	u_char	ip_tos;		/* IP TypeOfService */
62 	u_char	tcp_flags;	/* TCP flags */
63 	int	ifInIndex;	/* SNMP index of the input interface, 0-based */
64 	int	ifOutIndex;	/* SNMP index of the output interface */
65 
66 	double	seen_first;	/* First packet in the flow */
67 	double	seen_last;	/* Last packet in the flow */
68 
69 	char ifInName[IFNAMSIZ];
70 	char ifOutName[IFNAMSIZ];
71 } flow_t;
72 #define	FLOW_EMPTY_VALUE { {0}, {0}, -1, -1 }	/* Used in static inits */
73 
74 /*
75  * Wrapper to include the flow into a hash.
76  */
77 typedef struct flow_el_s {
78 
79 	flow_t flow;	/* Flow itself */
80 
81 	/*
82 	 * Hash value of the flow.
83 	 */
84 	int hash_value;
85 
86 	/*
87 	 * Place in the bucket.
88 	 */
89 	struct flow_el_s *bucket_prev;
90 	struct flow_el_s *bucket_next;
91 
92 	/*
93 	 * Place in the global list.
94 	 */
95 	struct flow_el_s *hash_next;
96 } flow_el_t;
97 
98 
99 /*
100  * Hash of flows.
101  */
102 typedef struct flow_storage_s {
103 	flow_el_t **buckets;	/* Hash buckets */
104 	flow_el_t *head;	/* Linked list of elements */
105 	int numbuckets;		/* Number of bytes allocated */
106 	int entries;		/* Number of flow elements linked in */
107 
108 	time_t	create_time;	/* Hash creation time */
109 
110 	time_t	first_miss;	/* Time when problems started to happen */
111 	long long missed_packets;	/* Number of lost packets */
112 	long long missed_bytes;		/* Number of lost bytes */
113 	uint32_t missed_flows;	/* Missed NetFlow flows */
114 	uint32_t flows_count;	/* Number of NetFlow flows seen so far */
115 
116 	pthread_mutex_t storage_lock;
117 } flow_storage_t;
118 
119 /*
120  * Active, checkpoint and NetFlow storages (flow caches).
121  */
122 extern flow_storage_t active_storage;
123 extern flow_storage_t checkpoint_storage;
124 extern flow_storage_t netflow_storage;
125 
126 #define	lock_storage(foo)	pthread_mutex_lock(&(foo)->storage_lock)
127 #define	unlock_storage(foo)	pthread_mutex_unlock(&(foo)->storage_lock)
128 
129 /*
130  * Atomically add flow counters into the list of flows.
131  * flow will NOT be consumed (yet may be modified): you may allocate it
132  * on the stack. The function may allocate new flow_el_t object or update
133  * existing one.
134  * If allocation fails, it will increase .missed_* counters in the storage
135  * and return -1.
136  */
137 typedef enum {
138 	AGG_NONE	= 0x00,	/* Do not aggregate */
139 	AGG_IPS		= 0x01,	/* Aggregate IP addresses */
140 	AGG_PORTS	= 0x02,	/* Aggregate Port numbers */
141 	AGG_ALL		= 0x03,	/* Aggregate everything */
142 } agg_e;
143 int flow_update(flow_storage_t *storage, flow_t *flow, agg_e aggregate_flow);
144 
145 
146 /*
147  * Remove flows from the storage.
148  * Operation is atomic.
149  */
150 void clear_storage(flow_storage_t *storage, int do_not_lock_storage);
151 
152 /*
153  * Move main storage in place of checkpoint.
154  * Operation is atomic.
155  */
156 void save_checkpoint(flow_storage_t *main, flow_storage_t *checkpoint);
157 
158 /*
159  * Get a table with flows (array of flow_t).
160  * If return value is 0, r_flows and r_size will be initialized
161  * to point to a newly allocated table of flows.
162  * You must lock storage before calling this function!
163  */
164 int get_flow_table(flow_storage_t *storage, flow_t **r_flows, int *r_size);
165 
166 #endif	/* __STORAGE_H__ */
167