0ff93010ef6812804ad29eb4ac7c61d42676726d
[monky] / src / libtcp-portmon.h
1 /* -*- mode: c; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
2  *
3  * libtcp-portmon.h:  tcp port monitoring library.
4  *
5  * Copyright (C) 2005-2007 Philip Kovacs pkovacs@users.sourceforge.net
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
20  * USA. */
21
22 #ifndef LIBTCP_PORTMON_H
23 #define LIBTCP_PORTMON_H
24
25 #include <sys/types.h>
26 #include <sys/socket.h>
27
28 #include <arpa/inet.h>
29 #include <netinet/in.h>
30 #include <netinet/tcp.h>
31
32 #include <math.h>
33 #include <netdb.h>
34 #include <stdlib.h>
35 #include <stdio.h>
36 #include <string.h>
37
38 #include <glib.h>
39
40 /* connection deleted if unseen again after this # of refreshes */
41 #define TCP_CONNECTION_STARTING_AGE 1
42 #define TCP_CONNECTION_HASH_KEY_SIZE 28
43 #define TCP_PORT_MONITOR_HASH_KEY_SIZE 12
44 #define MAX_PORT_MONITOR_CONNECTIONS_DEFAULT 256
45
46 /* -------------------------------------------------------------------
47  * IMPLEMENTATION INTERFACE
48  *
49  * Implementation-specific interface begins here.  Clients should not
50  * manipulate these structures directly, nor call the defined helper
51  * functions.  Use the "Client interface" functions defined at bottom.
52  * ------------------------------------------------------------------- */
53
54 /* The inventory of peekable items within the port monitor. */
55 enum tcp_port_monitor_peekables {
56         COUNT = 0,
57         REMOTEIP,
58         REMOTEHOST,
59         REMOTEPORT,
60         REMOTESERVICE,
61         LOCALIP,
62         LOCALHOST,
63         LOCALPORT,
64         LOCALSERVICE
65 };
66
67 /* ------------------------------------------------------------------------
68  * A single tcp connection
69  *
70  * The age variable provides the mechanism for removing connections if they
71  * are not seen again in subsequent update cycles.
72  * ------------------------------------------------------------------------ */
73 typedef struct _tcp_connection_t {
74         /* connection's key in monitor hash */
75         gchar key[TCP_CONNECTION_HASH_KEY_SIZE];
76         in_addr_t local_addr;
77         in_port_t local_port;
78         in_addr_t remote_addr;
79         in_port_t remote_port;
80         int age;
81 } tcp_connection_t;
82
83 /* ----------------------------------
84  * Copy a connection
85  *
86  * Returns 0 on success, -1 otherwise
87  * ---------------------------------- */
88 int copy_tcp_connection(tcp_connection_t *p_dest_connection,
89         const tcp_connection_t *p_source_connection);
90
91 /* -------------------------------------------------------------------
92  * A tcp connection node/list
93  *
94  * Connections within each monitor are stored in a double-linked list.
95  * ------------------------------------------------------------------- */
96 typedef struct _tcp_connection_node_t {
97         tcp_connection_t connection;
98         struct _tcp_connection_node_t *p_prev;
99         struct _tcp_connection_node_t *p_next;
100 } tcp_connection_node_t;
101
102 typedef struct _tcp_connection_list_t {
103         tcp_connection_node_t *p_head;
104         tcp_connection_node_t *p_tail;
105 } tcp_connection_list_t;
106
107 /* --------------
108  * A port monitor
109  * -------------- */
110 typedef struct _tcp_port_monitor_t {
111         /* monitor's key in collection hash */
112         gchar key[TCP_PORT_MONITOR_HASH_KEY_SIZE];
113         /* start of monitor port range */
114         in_port_t port_range_begin;
115         /* begin = end to monitor a single port */
116         in_port_t port_range_end;
117         /* list of connections for this monitor */
118         tcp_connection_list_t connection_list;
119         /* hash table of pointers into connection list */
120         GHashTable *hash;
121         /* array of connection pointers for O(1) peeking */
122         tcp_connection_t **p_peek;
123         /* max number of connections */
124         unsigned int max_port_monitor_connections;
125 } tcp_port_monitor_t;
126
127 /* ------------------------
128  * A port monitor node/list
129  * ------------------------ */
130 typedef struct _tcp_port_monitor_node_t {
131         tcp_port_monitor_t *p_monitor;
132         struct _tcp_port_monitor_node_t *p_next;
133 } tcp_port_monitor_node_t;
134
135 typedef struct __tcp_port_monitor_list_t {
136         tcp_port_monitor_node_t *p_head;
137         tcp_port_monitor_node_t *p_tail;
138 } tcp_port_monitor_list_t;
139
140 /* ---------------------------------------
141  * A port monitor utility function typedef
142  * --------------------------------------- */
143 typedef void (*tcp_port_monitor_function_ptr_t)(tcp_port_monitor_t *p_monitor,
144         void *p_void);
145
146 /* -------------------------------------------
147  * Port monitor utility functions implementing
148  * tcp_port_monitor_function_ptr_t
149  * ------------------------------------------- */
150 void destroy_tcp_port_monitor(tcp_port_monitor_t *p_monitor,
151         void *p_void /* (use NULL for this function) */);
152
153 void age_tcp_port_monitor(tcp_port_monitor_t *p_monitor,
154         void *p_void /* (use NULL for this function) */);
155
156 void rebuild_tcp_port_monitor_peek_table(tcp_port_monitor_t *p_monitor,
157         void *p_void /* (use NULL for this function) */);
158
159 void show_connection_to_tcp_port_monitor(tcp_port_monitor_t *p_monitor,
160         void *p_connection /* (client should cast) */);
161
162 /* -----------------------------
163  * A tcp port monitor collection
164  * ----------------------------- */
165 typedef struct _tcp_port_monitor_collection_t {
166         /* list of monitors for this collection */
167         tcp_port_monitor_list_t monitor_list;
168         /* hash table of pointers into collection's monitor list */
169         GHashTable *hash;
170 } tcp_port_monitor_collection_t;
171
172 /* --------------------------------------------------------
173  * Apply a tcp_port_monitor_function_ptr_t function to each
174  * port monitor in the collection.
175  * -------------------------------------------------------- */
176 void for_each_tcp_port_monitor_in_collection(
177         tcp_port_monitor_collection_t *p_collection,
178         tcp_port_monitor_function_ptr_t p_function,
179         void *p_function_args /* (for user arguments) */);
180
181 /* ----------------------------------------------------------------------
182  * CLIENT INTERFACE
183  *
184  * Clients should call only those functions below this line.
185  * ---------------------------------------------------------------------- */
186
187 /* struct to hold monitor creation arguments */
188 typedef struct _tcp_port_monitor_args_t {
189         /* monitor supports tracking at most this many connections */
190         int max_port_monitor_connections;
191 } tcp_port_monitor_args_t;
192
193 /* ----------------------------------
194  * Client operations on port monitors
195  * ---------------------------------- */
196
197 /* Clients should first try to "find_tcp_port_monitor" before creating one,
198  * so that there are no redundant monitors. */
199 tcp_port_monitor_t *create_tcp_port_monitor(in_port_t port_range_begin,
200         in_port_t port_range_end, tcp_port_monitor_args_t *p_creation_args);
201
202 /* Clients use this function to get connection data from
203  * the indicated port monitor.
204  * The requested monitor value is copied into a client-supplied char buffer.
205  * Returns 0 on success, -1 otherwise. */
206 int peek_tcp_port_monitor(const tcp_port_monitor_t *p_monitor,
207         /* (item of interest, from tcp_port_monitor_peekables enum) */
208         int item,
209         /* (0 to number of connections in monitor - 1) */
210         int connection_index,
211         /* buffer to receive requested value */
212         char *p_buffer,
213         /* size of p_buffer */
214         size_t buffer_size);
215
216 /* --------------------------------
217  * Client operations on collections
218  * -------------------------------- */
219
220 /* Create a monitor collection.  Do this one first. */
221 tcp_port_monitor_collection_t *create_tcp_port_monitor_collection(void);
222
223 /* Destroy the monitor collection (and everything it contains).
224  * Do this one last. */
225 void destroy_tcp_port_monitor_collection(
226         tcp_port_monitor_collection_t *p_collection);
227
228 /* Updates the tcp statitics for all monitors within a collection */
229 void update_tcp_port_monitor_collection(
230         tcp_port_monitor_collection_t *p_collection);
231
232 /* After clients create a monitor, use this to add it to the collection.
233  * Returns 0 on success, -1 otherwise. */
234 int insert_tcp_port_monitor_into_collection(
235         tcp_port_monitor_collection_t *p_collection, tcp_port_monitor_t *p_monitor);
236
237 /* Clients need a way to find monitors */
238 tcp_port_monitor_t *find_tcp_port_monitor(
239         const tcp_port_monitor_collection_t *p_collection,
240         in_port_t port_range_begin, in_port_t port_range_end);
241
242 #endif