compile fixes
[libipt_ACCOUNT] / src / ipt_ACCOUNT_cl.c
index 52e6d1f..a1925ec 100644 (file)
@@ -1,25 +1,37 @@
+/***************************************************************************
+ *   Copyright (C) 2004 by Intra2net AG                                    *
+ *   opensource@intra2net.com                                              *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU Lesser General Public License           *
+ *   version 2.1 as published by the Free Software Foundation;             *
+ *                                                                         *
+ ***************************************************************************/
+
 #include <sys/types.h>
 #include <sys/socket.h>
-#include <netinet/in.h>
 
+#include <netinet/in.h>
+#include <linux/if.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
 #include <ipt_ACCOUNT_cl.h>
 
 int ipt_ACCOUNT_init(struct ipt_ACCOUNT_context *ctx)
 {
     memset (ctx, 0, sizeof(struct ipt_ACCOUNT_context));
+    ctx->handle.handle_nr = -1;
     
     ctx->sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
-    if (ctx->sockfd < 0)
-    {
+    if (ctx->sockfd < 0) {
         ctx->sockfd = -1;
-        ctx->error_str = "Can't open socket to kernel. Permission denied or ipt_ACCOUNT module not loaded";
+        ctx->error_str = "Can't open socket to kernel. "
+                         "Permission denied or ipt_ACCOUNT module not loaded";
         return -1;
     }
     
     // 4096 bytes default buffer should save us from reallocations
     // as it fits 200 concurrent active clients
-    if((ctx->data = (void *)malloc(IPT_ACCOUNT_MIN_BUFSIZE)) == NULL)
-    {
+    if((ctx->data = (void *)malloc(IPT_ACCOUNT_MIN_BUFSIZE)) == NULL) {
         close (ctx->sockfd);
         ctx->sockfd = -1;
         ctx->error_str = "Out of memory for data buffer";
@@ -32,9 +44,9 @@ int ipt_ACCOUNT_init(struct ipt_ACCOUNT_context *ctx)
 
 void ipt_ACCOUNT_free_entries(struct ipt_ACCOUNT_context *ctx)
 {
-    if (ctx->handle.handle_nr >= 0)
-    {
-        setsockopt(ctx->sockfd, IPPROTO_IP, IPT_SO_SET_ACCOUNT_HANDLE_FREE, &ctx->handle, sizeof (struct ipt_account_handle_sockopt));
+    if (ctx->handle.handle_nr != -1) {
+        setsockopt(ctx->sockfd, IPPROTO_IP, IPT_SO_SET_ACCOUNT_HANDLE_FREE,
+                   &ctx->handle, sizeof (struct ipt_acc_handle_sockopt));
         ctx->handle.handle_nr = -1;
     }
 
@@ -53,41 +65,43 @@ void ipt_ACCOUNT_deinit(struct ipt_ACCOUNT_context *ctx)
     ctx->sockfd =-1;
 }
 
-int ipt_ACCOUNT_read_entries(struct ipt_ACCOUNT_context *ctx, char *table, char dont_flush)
+int ipt_ACCOUNT_read_entries(struct ipt_ACCOUNT_context *ctx,
+                             const char *table, char dont_flush)
 {
-    unsigned int s = sizeof (struct ipt_account_handle_sockopt);
+    unsigned int s = sizeof (struct ipt_acc_handle_sockopt);
+    unsigned int new_size;
     int rtn;
     
     strncpy(ctx->handle.name, table, ACCOUNT_TABLE_NAME_LEN-1);
     
     // Get table information
     if (!dont_flush)
-        rtn = getsockopt(ctx->sockfd, IPPROTO_IP, IPT_SO_GET_ACCOUNT_PREPARE_READ_FLUSH, &ctx->handle, &s);
+        rtn = getsockopt(ctx->sockfd, IPPROTO_IP,
+                         IPT_SO_GET_ACCOUNT_PREPARE_READ_FLUSH, &ctx->handle, &s);
     else
-        rtn = getsockopt(ctx->sockfd, IPPROTO_IP, IPT_SO_GET_ACCOUNT_PREPARE_READ, &ctx->handle, &s);
+        rtn = getsockopt(ctx->sockfd, IPPROTO_IP, IPT_SO_GET_ACCOUNT_PREPARE_READ,
+                         &ctx->handle, &s);
     
-    if (rtn < 0)
-    {
-        ctx->error_str = "Can't get table information from kernel. Is the table existing?";
+    if (rtn < 0) {
+        ctx->error_str = "Can't get table information from kernel. "
+                         "Is the table existing?";
         return -1;
     }
     
     // Check data buffer size
     ctx->pos = 0;
-    unsigned int new_size = ctx->handle.itemcount * sizeof(struct ipt_account_handle_ip);
+    new_size = ctx->handle.itemcount * sizeof(struct ipt_acc_handle_ip);
     // We want to prevent reallocations all the time
     if (new_size < IPT_ACCOUNT_MIN_BUFSIZE)
         new_size = IPT_ACCOUNT_MIN_BUFSIZE;
     
     // Reallocate if it's too small or twice as big
-    if (ctx->data_size < new_size || ctx->data_size > new_size*2)
-    {
+    if (ctx->data_size < new_size || ctx->data_size > new_size*2) {
         // Free old buffer
         free (ctx->data);
         ctx->data_size = 0;
         
-        if ((ctx->data = (void*)malloc(new_size)) == NULL)
-        {
+        if ((ctx->data = (void*)malloc(new_size)) == NULL) {
             ctx->error_str = "Out of memory for data buffer";
             ipt_ACCOUNT_free_entries(ctx);
             return -1;
@@ -97,80 +111,86 @@ int ipt_ACCOUNT_read_entries(struct ipt_ACCOUNT_context *ctx, char *table, char
     }
     
     // Copy data from kernel
-    memcpy(ctx->data, &ctx->handle, sizeof(struct ipt_account_handle_sockopt));
-    rtn = getsockopt(ctx->sockfd, IPPROTO_IP, IPT_SO_GET_ACCOUNT_GET_DATA, ctx->data, &ctx->data_size);
-    if (rtn < 0)
-    {
-        ctx->error_str = "Can't get data from kernel. Check /var/log/messages for details.";
+    memcpy(ctx->data, &ctx->handle, sizeof(struct ipt_acc_handle_sockopt));
+    rtn = getsockopt(ctx->sockfd, IPPROTO_IP, IPT_SO_GET_ACCOUNT_GET_DATA,
+                     ctx->data, &ctx->data_size);
+    if (rtn < 0) {
+        ctx->error_str = "Can't get data from kernel. "
+                         "Check /var/log/messages for details.";
         ipt_ACCOUNT_free_entries(ctx);
         return -1;
     }
 
     // Free kernel handle but don't reset pos/itemcount
-    setsockopt(ctx->sockfd, IPPROTO_IP, IPT_SO_SET_ACCOUNT_HANDLE_FREE, &ctx->handle, sizeof (struct ipt_account_handle_sockopt));
+    setsockopt(ctx->sockfd, IPPROTO_IP, IPT_SO_SET_ACCOUNT_HANDLE_FREE,
+               &ctx->handle, sizeof (struct ipt_acc_handle_sockopt));
     ctx->handle.handle_nr = -1;
     
     return 0;
 }
 
-struct ipt_account_handle_ip *ipt_ACCOUNT_get_next_entry(struct ipt_ACCOUNT_context *ctx)
+struct ipt_acc_handle_ip *ipt_ACCOUNT_get_next_entry(struct ipt_ACCOUNT_context *ctx)
 {
-    struct ipt_account_handle_ip *rtn;
+    struct ipt_acc_handle_ip *rtn;
     
     // Empty or no more items left to return?
     if (!ctx->handle.itemcount || ctx->pos >= ctx->handle.itemcount)
         return NULL;
     
     // Get next entry
-    rtn = (struct ipt_account_handle_ip *)(ctx->data + ctx->pos*sizeof(struct ipt_account_handle_ip));
+    rtn = (struct ipt_acc_handle_ip *)(ctx->data + ctx->pos
+                                       * sizeof(struct ipt_acc_handle_ip));
     ctx->pos++;
             
     return rtn;
 }
 
-char *addr_to_dotted(unsigned int addr)
+int ipt_ACCOUNT_get_handle_usage(struct ipt_ACCOUNT_context *ctx)
 {
-    static char buf[20];
-    const unsigned char *bytep;
-
-    bytep = (const unsigned char *) &addr;
-    sprintf(buf, "%d.%d.%d.%d", bytep[0], bytep[1], bytep[2], bytep[3]);
-    return buf;
+    unsigned int s = sizeof (struct ipt_acc_handle_sockopt);
+    if (getsockopt(ctx->sockfd, IPPROTO_IP,
+                   IPT_SO_GET_ACCOUNT_GET_HANDLE_USAGE, &ctx->handle, &s) < 0) {
+        ctx->error_str = "Can't get handle usage information from kernel";
+        return -1;
+    }
+    ctx->handle.handle_nr = -1;
+    
+    return ctx->handle.itemcount;
+ }
+    
+int ipt_ACCOUNT_free_all_handles(struct ipt_ACCOUNT_context *ctx)
+{
+    if (setsockopt(ctx->sockfd, IPPROTO_IP,
+                   IPT_SO_SET_ACCOUNT_HANDLE_FREE_ALL, NULL, 0) < 0) {
+        ctx->error_str = "Can't free all kernel handles";
+        return -1;
+    }
+    
+    return 0;
 }
-
-int main(void)
+    
+int ipt_ACCOUNT_get_table_names(struct ipt_ACCOUNT_context *ctx)
 {
-    struct ipt_ACCOUNT_context ctx;
-    struct ipt_account_handle_ip *entry;
-    int i;
-    
-    if(ipt_ACCOUNT_init(&ctx))
-    {
-        printf("Init failed: %s\n", ctx.error_str);
-        exit (-1);
+    int rtn = getsockopt(ctx->sockfd, IPPROTO_IP,
+                         IPT_SO_GET_ACCOUNT_GET_TABLE_NAMES,
+                         ctx->data, &ctx->data_size);
+    if (rtn < 0) {
+        ctx->error_str = "Can't get table names from kernel. Out of memory, "
+                         "MINBUFISZE too small?";
+        return -1;
     }
+    ctx->pos = 0;
+    return 0;
+}
 
-    for (i = 0; i < 3; i++)
-    {
-        printf("Run #%d\n", i);
-        
-        // Get entries from table test
-        if (ipt_ACCOUNT_read_entries(&ctx, "test", 0))
-        {
-            printf("Read failed: %s\n", ctx.error_str);
-            ipt_ACCOUNT_deinit(&ctx);
-            exit (-1);
-        }
+const char *ipt_ACCOUNT_get_next_name(struct ipt_ACCOUNT_context *ctx)
+{
+    const char *rtn;
+    if (((char *)ctx->data)[ctx->pos] == 0)
+        return 0;
+
+    rtn = ctx->data + ctx->pos;
+    ctx->pos += strlen(ctx->data+ctx->pos) + 1;
         
-        // Output and free entries
-        while ((entry = ipt_ACCOUNT_get_next_entry(&ctx)) != NULL)
-        {
-            printf("IP: %s SRC packets: %u bytes: %u DST packets: %u bytes: %u\n",
-                   addr_to_dotted(entry->ip), entry->src_packets, entry->src_bytes, entry->dst_packets, entry->dst_bytes);
-        }
-        sleep(1);
-    }
-            
-    ipt_ACCOUNT_deinit(&ctx);
-    exit (0);
+    return rtn;
 }