linux下的l7源代码

源代码在线查看: l7-filter.cpp

软件大小: 44 K
上传用户: abc171abc171
关键词: linux 源代码
下载地址: 免注册下载 普通下载 VIP

相关代码

				/*				  Functions and classes which track the conntracks for l7-filter.				  				  By Ethan Sommer  and Matthew Strait 				  , (C) 2006-2007				  http://l7-filter.sf.net 								  This program is free software; you can redistribute it and/or				  modify it under the terms of the GNU General Public License				  as published by the Free Software Foundation; either version				  2 of the License, or (at your option) any later version.				  http://www.gnu.org/licenses/gpl.txt								  Based on ctnl_test.c from libnetfilter-conntrack 0.0.31 (C) 2005 by 				  Pablo Neira Ayuso 				   and				  Based on nfqnl_test.c from libnetfilter-queue 0.0.12				*/								using namespace std;				#include 								#include 				#include 								#include 				#include 				#include 				#include 				#include 				#include 								#include "l7-conntrack.h"				#include "l7-queue.h"				#include "l7-classify.h"				#include "util.h"								extern "C" {				#include 				#include 				#include 				}								static l7_conntrack* l7_connection_tracker;				static l7_queue* l7_queue_tracker;				static l7_classify* l7_classifier;								// Configurable parameters				extern int verbosity;				extern int buflen;				extern int maxpackets;				extern string l7dir;				extern unsigned int markmask;				extern unsigned int maskfirstbit;				extern unsigned int masknbits;				extern int clobbermark;								static void handle_sigint(int s) {				  // was there a reason for this?  It just makes it crash on Ctrl-C for me.				  //delete l7_connection_tracker;				  exit(0);				}												//queue functions								/* returns packet id */				static u_int32_t print_pkt (struct nfq_data *tb)				{				  int id = 0;				  struct nfqnl_msg_packet_hdr *ph;				  u_int32_t mark,ifi; 				  int ret;				  char *data;				  				  ph = nfq_get_msg_packet_hdr(tb);				  if(ph){				    id = ntohl(ph->packet_id);				    printf("hw_protocol=0x%04x hook=%u id=%u ",				      ntohs(ph->hw_protocol), ph->hook, id);				  }				  				  mark = nfq_get_nfmark(tb);				  if (mark) printf("mark=%u ", mark);								  ifi = nfq_get_indev(tb);				  if(ifi) printf("indev=%u ", ifi);								  ifi = nfq_get_outdev(tb);				  if(ifi) printf("outdev=%u ", ifi);								  ret = nfq_get_payload(tb, &data);				  if (ret >= 0) printf("payload_len=%d ", ret);								  putchar('\n');								  return id;				}								static int cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg,				  struct nfq_data *nfa, void *data) 				{				  u_int32_t id = print_pkt(nfa);				  l7printf(3, "entering callback\n");				  return nfq_set_verdict(qh, id, NF_ACCEPT, 0, NULL);				}								static void * start_connection_tracking_thread(void *data) 				{				  l7_connection_tracker->start();				  pthread_exit(NULL);				}								static void * start_queue_thread(void * qnum) 				{				  int * queuenum = (int *)qnum;								  l7_queue_tracker->start(*queuenum);				  pthread_exit(NULL);				}								// Checks whether the given mask has all its 1's in a row				// and that it has enough room to work in				static int checkandparsemask(const unsigned int mask)				{				  int i = 0;				  masknbits = 0;								  // it can start with 0 or more 0's				  while((mask >> i)%2 == 0){				    i++;				    if(i >= 32) return false; // it's all zeros!				  }  								  maskfirstbit = i;								  // followed by 0 or more 1's				  while((mask >> i)%2 == 1){ 				    masknbits++;				    i++;				  } 				  if(masknbits < 2) return false; // need at least two bits to work with								  // the rest has to be all 0's				  for(; i < 32; i++)				    if((mask >> i)%2 == 1)				      return false;								  return true;				}								static void handle_cmdline(int & qnum, string & conffilename, 				  int argc, char ** argv)				{				  int dumb = 0; // whether to allow dumb things				  qnum = 0; // default				  buflen = 8*1500; //default (8 large packets worth)				  conffilename = ""; 				  const char *opts = "f:q:vh?sb:dn:p:m:c";								  int done = 0;				  while(!done)				  {				    char c;				    switch(c = getopt(argc, argv, opts))				    {				      case -1:				        done = 1;				        break;				      case 'f':				        conffilename = optarg;				        break;				      case 'p':				        l7dir = optarg;				        break;				      case 'q':				        qnum = strtol(optarg, 0, 10);				        if(qnum == LONG_MIN || qnum == LONG_MAX || qnum < 0 || qnum > 65535){				          cerr 				          exit(1);				        }				        break;				      case 'b':				        buflen = strtol(optarg, 0, 10);				        if(buflen == LONG_MIN || buflen == LONG_MAX || 					   ((buflen < 1 || buflen > 65535) && !dumb)){				          cerr 				            "Valid lengths are 0-65535. (65535 is an arbitrary limit. If you\n"				            "are sure you need more, use the -d switch before this one.)\n";				          exit(1);				        }				        break;				      case 'n':				        maxpackets = strtoll(optarg, 0, 10);				        // never allow maxpackets to be less than one.				        // Allow it to be outside of the range 3-16 only if -d is given				        if(maxpackets == LONG_MIN || maxpackets == LONG_MAX || maxpackets < 1 ||				           ((maxpackets < 3 || maxpackets > 16) && !dumb)){				          cerr 				                  "non-number. Valid number are between 3 and 16. Or if you\n"				                  "give the -d option before this one, I'll allow any\n"				                  "positive integer.\n";				          exit(1);				        }				        break;				      case 'm':					markmask = strtoll(optarg, 0, 0);				        if(errno == ERANGE){				          cerr 				          exit(1);				        }					if(!checkandparsemask(markmask)){				          cerr				                "contiguous\n"				                "For example: 0x0000fff0, but not 0xf000f000.\n"				                "I also need at least two bits to work with.\n";				          exit(1);				        }				        break; 				      case 'c':				        clobbermark = 1;				        break;       				      case 'v':				        verbosity++;				        break;				      case 'd':				        dumb = 1;				        cout 				        break;				      case 's':				        verbosity = -1;				        break;				      case 'h':				      case '?':				      default:				        cerr 				          "l7-filter v" 				          ", (C) 2006-2007 Ethan Sommer, Matthew Strait\n"				          "l7-filter comes with ABSOLUTELY NO WARRANTY. This is free software\n"				          "and you may redistribute it under the terms of the GPLv2.\n"				          "\n"				          "Syntax: l7-filter -f configuration_file [options]\n"				          "\n"				          "Options are:\n"				          "-q queuenumber\tListen to the specified Netfilter queue\n"				          "-v\t\tBe verbose. Mutiple -v options increase the verbosity\n"				          "-s\t\tBe silent except in the case of warnings and errors\n"				          "-b bytes\tStore up to this many bytes of data per connection\n"				          "-n packets\tExamine up to this many packets per connection\n"				          "-p path\t\tLook for patterns in path instead of /etc/l7-protocols\n"				          "-m mask\t\tOnly pay look at and set the given bits of marks\n"				          "-c\t\tClobber existing marks instead of passing them unmodified\n"				          "-d\t\tAllow configurations that are probably ill-advised\n"				          "\n"				          "See also 'man l7-filter'\n";				        exit(1);				        break;				    }				  }								  if(conffilename == ""){				    cerr 				    exit(1);				  }				}								// Checks if the specified module is loaded.  Returns 1 if yes, 0 if no.				static int check_for_module(string mod)				{				  ifstream pm("/proc/modules");				  if(!pm.is_open()){				    cerr 				    return 0;				  }								  string line;				  while(!pm.eof()){				    getline(pm, line);				    if(line.substr(0, mod.size()) == mod)				      return 1;				  }				  				  return 0;				}								static void check_requirements()				{				  if(!check_for_module("ip_conntrack_netlink"))				  {				    cerr 				            "The ip_conntrack_netlink module does not appear to be loaded.\n"				            "Unless you have it compiled into your kernel, please load it\n"				            "and run l7-filter again.\n\n";				    sleep(5); // give time for the user to notice the above.				  }				   				}								int main(int argc, char **argv) 				{				  int rc, qnum;				  string conffilename;				  pthread_t connection_tracking_thread;				  pthread_t queue_tracking_thread;								  check_requirements();								  handle_cmdline(qnum, conffilename, argc, argv);								  signal(SIGINT, handle_sigint);								  l7_classify * l7_classifier = new l7_classify(conffilename);				  l7_connection_tracker = new l7_conntrack(l7_classifier);				  l7_queue_tracker = new l7_queue(l7_connection_tracker);								  //start up the connection tracking thread				  rc = pthread_create(&connection_tracking_thread, NULL,					start_connection_tracking_thread, NULL);								  if(rc){				    cerr 				    exit(1);				  }								  //start up the queue thread				  rc = pthread_create(&queue_tracking_thread, NULL, 					start_queue_thread, (void *)(&qnum));								  if (rc){				    cerr 				    exit(1);				  }								//  pthread_exit(NULL);				  sleep(0xffffffff); // Sleep for 78 years (forever)				}							

相关资源