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