1/* 2 Shared library add-on to iptables to add layer 7 matching support. 3 4 http://l7-filter.sf.net 5 6 By Matthew Strait <quadong@users.sf.net>, Dec 2003. 7 8 This program is free software; you can redistribute it and/or 9 modify it under the terms of the GNU General Public License 10 as published by the Free Software Foundation; either version 11 2 of the License, or (at your option) any later version. 12 http://www.gnu.org/licenses/gpl.txt 13*/ 14 15#define _GNU_SOURCE 16#include <stdio.h> 17#include <netdb.h> 18#include <string.h> 19#include <stdlib.h> 20#include <getopt.h> 21#include <ctype.h> 22#include <dirent.h> 23 24#include <iptables.h> 25#include <linux/netfilter_ipv4/ipt_childlevel.h> 26 27/* Function which prints out usage message. */ 28static void help(void) 29{ 30 printf( 31 "CHILDLEVEL match v%s options:\n" 32 "--level <n> : Match childlevel n (0 == master)\n", 33 IPTABLES_VERSION); 34 fputc('\n', stdout); 35} 36 37static struct option opts[] = { 38 { .name = "level", .has_arg = 1, .flag = 0, .val = '1' }, 39 { .name = 0 } 40}; 41 42/* Function which parses command options; returns true if it ate an option */ 43static int parse(int c, char **argv, int invert, unsigned int *flags, 44 const struct ipt_entry *entry, unsigned int *nfcache, 45 struct ipt_entry_match **match) 46{ 47 struct ipt_childlevel_info *childlevelinfo = 48 (struct ipt_childlevel_info *)(*match)->data; 49 50 switch (c) { 51 case '1': 52 check_inverse(optarg, &invert, &optind, 0); 53 childlevelinfo->childlevel = atoi(argv[optind-1]); 54 if (invert) 55 childlevelinfo->invert = 1; 56 *flags = 1; 57 break; 58 default: 59 return 0; 60 } 61 62 return 1; 63} 64 65/* Final check; must have specified --level. */ 66static void final_check(unsigned int flags) 67{ 68 if (!flags) 69 exit_error(PARAMETER_PROBLEM, 70 "CHILDLEVEL match: You must specify `--level'"); 71} 72 73static void print_protocol(int n, int invert, int numeric) 74{ 75 fputs("childlevel ", stdout); 76 if (invert) fputc('!', stdout); 77 printf("%d ", n); 78} 79 80/* Prints out the matchinfo. */ 81static void print(const struct ipt_ip *ip, 82 const struct ipt_entry_match *match, 83 int numeric) 84{ 85 printf("CHILDLEVEL "); 86 87 print_protocol(((struct ipt_childlevel_info *)match->data)->childlevel, 88 ((struct ipt_childlevel_info *)match->data)->invert, numeric); 89} 90/* Saves the union ipt_matchinfo in parsable form to stdout. */ 91static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match) 92{ 93 const struct ipt_childlevel_info *info = 94 (const struct ipt_childlevel_info*) match->data; 95 96 printf("--childlevel %s%d ", (info->invert) ? "! ": "", info->childlevel); 97} 98 99static struct iptables_match childlevel = { 100 .name = "childlevel", 101 .version = IPTABLES_VERSION, 102 .size = IPT_ALIGN(sizeof(struct ipt_childlevel_info)), 103 .userspacesize = IPT_ALIGN(sizeof(struct ipt_childlevel_info)), 104 .help = &help, 105 .parse = &parse, 106 .final_check = &final_check, 107 .print = &print, 108 .save = &save, 109 .extra_opts = opts 110}; 111 112void _init(void) 113{ 114 register_match(&childlevel); 115} 116