Logo Search packages:      
Sourcecode: netams version File versions  Download package

ds_ipq.c

/*************************************************************************
***   Authentication, authorization, accounting + firewalling package
***   Copyright 1998-2002 Anton Vinokurov <anton@netams.com>
***   Copyright 2002-2008 NeTAMS Development Team
***   This code is GPL v3
***   For latest version and more info, visit this project web page
***   located at http://www.netams.com
***
*************************************************************************/
/* $Id: ds_ipq.c,v 1.47 2008-02-23 08:35:04 anton Exp $ */

#if defined(LINUX) && !defined(IPTBL_NONE)

#include "netams.h"
#include "ds_any.h"

extern "C" {
      #include <linux/netfilter.h>
      #include <libipq.h>
}

/////////////////////////////////////////////////////////////////////////////////////
void ds_ipq_cancel(void *ptr);
/////////////////////////////////////////////////////////////////////////////////////
void ds_ipq(Service_DS *ds) {
      struct ipq_handle *ipq;
      FlowEngine *FE=ds->FE;
        struct timeval start;
      unsigned char *packet=ds->packet;
      int status;
      
        #ifndef IPTBL_OLD
                ipq=ipq_create_handle(0, PF_INET);
        #else
                ipq=ipq_create_handle(0);
        #endif
      
        if (!ipq) {
            aLog(D_ERR, "linux ipq handle failed: %s!\n", ipq_errstr());
            return;
      }
              
        status=ipq_set_mode(ipq, IPQ_COPY_PACKET, sizeof(struct ip)+sizeof(struct tcphdr)
#ifdef LAYER7_FILTER
            +250 /* hope this will be enough */
#endif
                     );
      if(status<0) {
            aLog(D_ERR, "ipq_set_mode failed: %s\n",ipq_errstr());
            return;
      } else {
            aLog(D_INFO, "Capturing first %u bytes of IP packets\n", sizeof(struct ip)+sizeof(struct tcphdr)
#ifdef LAYER7_FILTER
            +250 /* hope this will be enough */
#endif
            );
      }
      
        pthread_cleanup_push(ds_ipq_cancel, (void*)ipq);
        pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);

      aLog(D_INFO,"IPQ packet processing for data-source:%u initialized\n",ds->instance);
      
      ipq_packet_msg_t  *m;
      int                     process_result;
      struct ipv4_key         key;
      bzero(&key, sizeof(struct ipv4_key));
      entry                   *flow_entry;

        while(1) {
            status=ipq_read(ipq, packet, MAX_PKT_SIZE, 1000);
            
            netams_gettimeofday(&start, NULL);
            FE->Expiresearch(&start);
      
            if (status == 0)
                  continue;
            else if(status < 0) {
                  aLog(D_ERR, "ipq_read failed: %s\n",ipq_errstr());
                  continue;
            } 
                  
                switch(ipq_message_type(packet)) {
                  case NLMSG_ERROR:
                        ipq_get_msgerr(packet);
                        aLog(D_ERR, "%s\n", packet);
                        continue;
                  case IPQM_PACKET:
                        break;
                  default:
                        continue;
            }
                  
            m=ipq_get_packet(packet);
            IPv4GetKey((struct ip*) m->payload, &key);
            
            process_result = FE->Process((u_char *)&key, 1, ntohs(((struct ip*)  m->payload)->ip_len), &flow_entry);
            if(process_result == -1) {
                  IPv4FillFlow(&key, flow_entry);

#ifdef LAYER7_FILTER
                  if (ds->layer7_detect!=LAYER7_DETECT_NONE) layer7_addinfo(key.tcp_info.dst_port, flow_entry); 
#endif
                  process_result = FE->FW(flow_entry);
            }
            
            if (process_result) ipq_set_verdict(ipq, m->packet_id, NF_ACCEPT, 0, NULL);
            else ipq_set_verdict(ipq, m->packet_id, NF_DROP, 0, NULL);
            
#ifdef LAYER7_FILTER
            if (ds->layer7_detect!=LAYER7_DETECT_NONE) layer7_checkinfo(key.tcp_info.dst_port, flow_entry, (struct ip*) m->payload); 
#endif
            ds->Measure(&start, m->data_len);
      }
      pthread_cleanup_pop(1);
}
/////////////////////////////////////////////////////////////////////////////////////
void ds_ipq_cancel(void *ptr) {
      if(ptr) ipq_destroy_handle((struct ipq_handle *) ptr);
}
#endif
/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////

Generated by  Doxygen 1.6.0   Back to index