* functions. Use the "Client interface" functions defined at bottom.
* ------------------------------------------------------------------- */
+/* ----------------------------------
+ * Copy a tcp_connection_t
+ *
+ * Returns 0 on success, -1 otherwise.
+ * ----------------------------------*/
+int copy_tcp_connection(
+ tcp_connection_t * p_dest_connection,
+ const tcp_connection_t * p_source_connection
+ )
+{
+ if ( !p_dest_connection || !p_source_connection )
+ return (-1);
+
+ p_dest_connection->local_addr = p_source_connection->local_addr;
+ p_dest_connection->local_port = p_source_connection->local_port;
+ p_dest_connection->remote_addr = p_source_connection->remote_addr;
+ p_dest_connection->remote_port = p_source_connection->remote_port;
+ p_dest_connection->age = p_source_connection->age;
+
+ return 0;
+}
+
/* -----------------------------------------------------------------------------
* Open-addressed hash implementation requires that we supply two hash functions
* and a match function to compare two hash elements for identity.
p_monitor1 = (tcp_port_monitor_t *)p_data1;
p_monitor2 = (tcp_port_monitor_t *)p_data2;
- return (p_monitor1->port_range_begin == p_monitor1->port_range_begin &&
- p_monitor2->port_range_end == p_monitor2->port_range_end);
+ return (p_monitor1->port_range_begin == p_monitor2->port_range_begin &&
+ p_monitor1->port_range_end == p_monitor2->port_range_end);
}
/* ---------------------------------------------------------------------------
#ifdef HASH_DEBUG
fprintf(stderr,"--- num vacated is %d, vacated factor is %.3f\n", p_monitor->hash.vacated, vacated_load );
#endif
- if ( vacated_load <= TCP_CONNECIION_HASH_MAX_VACATED_RATIO )
+ if ( vacated_load <= TCP_CONNECTION_HASH_MAX_VACATED_RATIO )
{
/* hash is fine and needs no rebalancing */
return;
void * p_void
)
{
- /* Run through the monitori's connections and rebuild the peek table
+ /* Run through the monitor's connections and rebuild the peek table
* of connection pointers. This is done so peeking into the monitor
* can be done in O(1) time instead of O(n) time for each peek. */
if ( !p_monitor || !p_void )
return;
+ /* This p_connection is on caller's stack and not the heap. If we are interested,
+ * we will create a copy of the connection (on the heap) and add it to our list. */
tcp_connection_t *p_connection = (tcp_connection_t *)p_void;
/* inspect the local port number of the connection to see if we're interested. */
/* it's already in the hash. reset the age of the connection. */
if ( p_connection != NULL )
{
- p_connection->age = TCP_CONNECIION_STARTING_AGE;
+ p_connection->age = TCP_CONNECTION_STARTING_AGE;
}
return;
if ( (p_node = (tcp_connection_node_t *) calloc(1, sizeof(tcp_connection_node_t))) == NULL )
return;
- p_node->connection = *p_connection; /* bitwise copy of the struct */
- p_node->connection.age = TCP_CONNECIION_STARTING_AGE;
+ /* copy the connection data */
+ if ( copy_tcp_connection( &p_node->connection, p_connection ) != 0 )
+ {
+ /* error copying the connection data. deallocate p_node to avoid leaks and return. */
+ free( p_node );
+ return;
+ }
+
+ p_node->connection.age = TCP_CONNECTION_STARTING_AGE;
p_node->p_next = NULL;
/* insert it into the monitor's hash table */
The requested monitor value is copied into a client-supplied char buffer.
Returns 0 on success, -1 otherwise. */
int peek_tcp_port_monitor(
- tcp_port_monitor_t * p_monitor,
+ const tcp_port_monitor_t * p_monitor,
int item,
int connection_index,
char * p_buffer,
FILE *fp;
char buf[256];
tcp_connection_t conn;
- unsigned long state;
+ unsigned long inode,uid,state;
if ( !p_collection )
return;
/* read all tcp connections */
while (fgets (buf, sizeof (buf), fp) != NULL) {
- if ( sscanf (buf, "%*d: %lx:%lx %lx:%lx %lx %*x:%*x %*x:%*x %*x %lu %*d %lu",
- (unsigned long *)&conn.local_addr, (unsigned long *)&conn.local_port,
- (unsigned long *)&conn.remote_addr, (unsigned long *)&conn.remote_port,
- (unsigned long *)&state, (unsigned long *)&conn.uid, (unsigned long *)&conn.inode) != 7 )
+ if ( sscanf (buf, "%*d: %lx:%hx %lx:%hx %lx %*x:%*x %*x:%*x %*x %lu %*d %lu",
+ (unsigned long *)&conn.local_addr, &conn.local_port,
+ (unsigned long *)&conn.remote_addr, &conn.remote_port,
+ (unsigned long *)&state, (unsigned long *)&uid, (unsigned long *)&inode) != 7 )
fprintf( stderr, "/proc/net/tcp: bad file format\n" );
- if ((conn.inode == 0) || (state != TCP_ESTABLISHED)) continue;
+ if ((inode == 0) || (state != TCP_ESTABLISHED)) continue;
/* show the connection to each port monitor. */
for_each_tcp_port_monitor_in_collection(
/* Clients need a way to find monitors */
tcp_port_monitor_t * find_tcp_port_monitor(
- tcp_port_monitor_collection_t * p_collection,
+ const tcp_port_monitor_collection_t * p_collection,
in_port_t port_range_begin,
in_port_t port_range_end
)