41ac4234f4089af125f4376b67f7292cbbdf088f
[monky] / src / libtcp-portmon.h
1 /* $Id$ */
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
45 /* -------------------------------------------------------------------
46  * IMPLEMENTATION INTERFACE
47  *
48  * Implementation-specific interface begins here.  Clients should not
49  * manipulate these structures directly, nor call the defined helper
50  * functions.  Use the "Client interface" functions defined at bottom.
51  * ------------------------------------------------------------------- */
52
53 /* The inventory of peekable items within the port monitor. */
54 enum tcp_port_monitor_peekables {
55         COUNT = 0,
56         REMOTEIP,
57         REMOTEHOST,
58         REMOTEPORT,
59         REMOTESERVICE,
60         LOCALIP,
61         LOCALHOST,
62         LOCALPORT,
63         LOCALSERVICE
64 };
65
66 /* ------------------------------------------------------------------------
67  * A single tcp connection
68  *
69  * The age variable provides the mechanism for removing connections if they
70  * are not seen again in subsequent update cycles.
71  * ------------------------------------------------------------------------ */
72 typedef struct _tcp_connection_t {
73         /* connection's key in monitor hash */
74         gchar key[TCP_CONNECTION_HASH_KEY_SIZE];
75         in_addr_t local_addr;
76         in_port_t local_port;
77         in_addr_t remote_addr;
78         in_port_t remote_port;
79         int age;
80 } tcp_connection_t;
81
82 /* ----------------------------------
83  * Copy a connection
84  *
85  * Returns 0 on success, -1 otherwise
86  * ---------------------------------- */
87 int copy_tcp_connection(tcp_connection_t *p_dest_connection,
88         const tcp_connection_t *p_source_connection);
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         /* monitor's key in collection hash */
111         gchar key[TCP_PORT_MONITOR_HASH_KEY_SIZE];
112         /* start of monitor port range */
113         in_port_t port_range_begin;
114         /* begin = end to monitor a single port */
115         in_port_t port_range_end;
116         /* list of connections for this monitor */
117         tcp_connection_list_t connection_list;
118         /* hash table of pointers into connection list */
119         GHashTable *hash;
120         /* array of connection pointers for O(1) peeking */
121         tcp_connection_t **p_peek;
122         /* max number of connections */
123         unsigned int max_port_monitor_connections;
124 } tcp_port_monitor_t;
125
126 /* ------------------------
127  * A port monitor node/list
128  * ------------------------ */
129 typedef struct _tcp_port_monitor_node_t {
130         tcp_port_monitor_t *p_monitor;
131         struct _tcp_port_monitor_node_t *p_next;
132 } tcp_port_monitor_node_t;
133
134 typedef struct __tcp_port_monitor_list_t {
135         tcp_port_monitor_node_t *p_head;
136         tcp_port_monitor_node_t *p_tail;
137 } tcp_port_monitor_list_t;
138
139 /* ---------------------------------------
140  * A port monitor utility function typedef
141  * --------------------------------------- */
142 typedef void (*tcp_port_monitor_function_ptr_t)(tcp_port_monitor_t *p_monitor,
143         void *p_void);
144
145 /* -------------------------------------------
146  * Port monitor utility functions implementing
147  * tcp_port_monitor_function_ptr_t
148  * ------------------------------------------- */
149 void destroy_tcp_port_monitor(tcp_port_monitor_t *p_monitor,
150         void *p_void /* (use NULL for this function) */);
151
152 void age_tcp_port_monitor(tcp_port_monitor_t *p_monitor,
153         void *p_void /* (use NULL for this function) */);
154
155 void rebuild_tcp_port_monitor_peek_table(tcp_port_monitor_t *p_monitor,
156         void *p_void /* (use NULL for this function) */);
157
158 void show_connection_to_tcp_port_monitor(tcp_port_monitor_t *p_monitor,
159         void *p_connection /* (client should cast) */);
160
161 /* -----------------------------
162  * A tcp port monitor collection
163  * ----------------------------- */
164 typedef struct _tcp_port_monitor_collection_t {
165         /* list of monitors for this collection */
166         tcp_port_monitor_list_t monitor_list;
167         /* hash table of pointers into collection's monitor list */
168         GHashTable *hash;
169 } tcp_port_monitor_collection_t;
170
171 /* --------------------------------------------------------
172  * Apply a tcp_port_monitor_function_ptr_t function to each
173  * port monitor in the collection.
174  * -------------------------------------------------------- */
175 void for_each_tcp_port_monitor_in_collection(
176         tcp_port_monitor_collection_t *p_collection,
177         tcp_port_monitor_function_ptr_t p_function,
178         void *p_function_args /* (for user arguments) */);
179
180 /* ----------------------------------------------------------------------
181  * CLIENT INTERFACE
182  *
183  * Clients should call only those functions below this line.
184  * ---------------------------------------------------------------------- */
185
186 /* struct to hold monitor creation arguments */
187 typedef struct _tcp_port_monitor_args_t {
188         /* monitor supports tracking at most this many connections */
189         int max_port_monitor_connections;
190 } tcp_port_monitor_args_t;
191
192 /* ----------------------------------
193  * Client operations on port monitors
194  * ---------------------------------- */
195
196 /* Clients should first try to "find_tcp_port_monitor" before creating one,
197  * so that there are no redundant monitors. */
198 tcp_port_monitor_t *create_tcp_port_monitor(in_port_t port_range_begin,
199         in_port_t port_range_end, tcp_port_monitor_args_t *p_creation_args);
200
201 /* Clients use this function to get connection data from
202  * the indicated port monitor.
203  * The requested monitor value is copied into a client-supplied char buffer.
204  * Returns 0 on success, -1 otherwise. */
205 int peek_tcp_port_monitor(const tcp_port_monitor_t *p_monitor,
206         /* (item of interest, from tcp_port_monitor_peekables enum) */
207         int item,
208         /* (0 to number of connections in monitor - 1) */
209         int connection_index,
210         /* buffer to receive requested value */
211         char *p_buffer,
212         /* size of p_buffer */
213         size_t buffer_size);
214
215 /* --------------------------------
216  * Client operations on collections
217  * -------------------------------- */
218
219 /* Create a monitor collection.  Do this one first. */
220 tcp_port_monitor_collection_t *create_tcp_port_monitor_collection(void);
221
222 /* Destroy the monitor collection (and everything it contains).
223  * Do this one last. */
224 void destroy_tcp_port_monitor_collection(
225         tcp_port_monitor_collection_t *p_collection);
226
227 /* Updates the tcp statitics for all monitors within a collection */
228 void update_tcp_port_monitor_collection(
229         tcp_port_monitor_collection_t *p_collection);
230
231 /* After clients create a monitor, use this to add it to the collection.
232  * Returns 0 on success, -1 otherwise. */
233 int insert_tcp_port_monitor_into_collection(
234         tcp_port_monitor_collection_t *p_collection, tcp_port_monitor_t *p_monitor);
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, in_port_t port_range_end);
240
241 #endif