scan ports as short. debian bug# 359974
[monky] / src / libtcp-portmon.c
index 7b3a3dc..5881cc9 100644 (file)
  * 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.
@@ -209,8 +231,8 @@ int monitor_match_function( const void *p_data1, const void *p_data2 )
    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);
 }
 
 /* ---------------------------------------------------------------------------
@@ -328,7 +350,7 @@ void maintain_tcp_port_monitor_hash(
 #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;
@@ -360,7 +382,7 @@ void rebuild_tcp_port_monitor_peek_table(
        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. */
 
@@ -397,6 +419,8 @@ void show_connection_to_tcp_port_monitor(
    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. */
@@ -413,7 +437,7 @@ void show_connection_to_tcp_port_monitor(
                /* 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;
@@ -436,8 +460,15 @@ void show_connection_to_tcp_port_monitor(
        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 */
@@ -590,7 +621,7 @@ tcp_port_monitor_t * create_tcp_port_monitor(
    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,
@@ -763,7 +794,7 @@ void update_tcp_port_monitor_collection(
        FILE *fp;
         char buf[256];
         tcp_connection_t conn;
-        unsigned long state;
+        unsigned long inode,uid,state;
 
        if ( !p_collection )
                return;
@@ -785,14 +816,14 @@ void update_tcp_port_monitor_collection(
         /* 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(
@@ -871,7 +902,7 @@ int insert_tcp_port_monitor_into_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
        )