Home | History | Annotate | Download | only in extensions
      1 /* Shared library add-on to iptables to add comment match support.
      2  *
      3  * ChangeLog
      4  *     2003-05-13: Brad Fisher <brad (at) info-link.net>
      5  *         Initial comment match
      6  *     2004-05-12: Brad Fisher <brad (at) info-link.net>
      7  *         Port to patch-o-matic-ng
      8  */
      9 #include <stdio.h>
     10 #include <string.h>
     11 #include <stdlib.h>
     12 #include <getopt.h>
     13 
     14 #include <iptables.h>
     15 #include <linux/netfilter_ipv4/ipt_comment.h>
     16 
     17 /* Function which prints out usage message. */
     18 static void
     19 help(void)
     20 {
     21 	printf(
     22 		"COMMENT match options:\n"
     23 		"--comment COMMENT             Attach a comment to a rule\n\n"
     24 		);
     25 }
     26 
     27 static struct option opts[] = {
     28 	{ "comment", 1, 0, '1' },
     29 	{0}
     30 };
     31 
     32 static void
     33 parse_comment(const char *s, struct ipt_comment_info *info)
     34 {
     35 	int slen = strlen(s);
     36 
     37 	if (slen >= IPT_MAX_COMMENT_LEN) {
     38 		exit_error(PARAMETER_PROBLEM,
     39 			"COMMENT must be shorter than %i characters", IPT_MAX_COMMENT_LEN);
     40 	}
     41 	strcpy((char *)info->comment, s);
     42 }
     43 
     44 /* Function which parses command options; returns true if it
     45    ate an option */
     46 static int
     47 parse(int c, char **argv, int invert, unsigned int *flags,
     48       const struct ipt_entry *entry,
     49       unsigned int *nfcache,
     50       struct ipt_entry_match **match)
     51 {
     52 	struct ipt_comment_info *commentinfo = (struct ipt_comment_info *)(*match)->data;
     53 
     54 	switch (c) {
     55 	case '1':
     56 		check_inverse(argv[optind-1], &invert, &optind, 0);
     57 		if (invert) {
     58 			exit_error(PARAMETER_PROBLEM,
     59 					"Sorry, you can't have an inverted comment");
     60 		}
     61 		parse_comment(argv[optind-1], commentinfo);
     62 		*flags = 1;
     63 		break;
     64 
     65 	default:
     66 		return 0;
     67 	}
     68 	return 1;
     69 }
     70 
     71 /* Final check; must have specified --comment. */
     72 static void
     73 final_check(unsigned int flags)
     74 {
     75 	if (!flags)
     76 		exit_error(PARAMETER_PROBLEM,
     77 			   "COMMENT match: You must specify `--comment'");
     78 }
     79 
     80 /* Prints out the matchinfo. */
     81 static void
     82 print(const struct ipt_ip *ip,
     83       const struct ipt_entry_match *match,
     84       int numeric)
     85 {
     86 	struct ipt_comment_info *commentinfo = (struct ipt_comment_info *)match->data;
     87 
     88 	commentinfo->comment[IPT_MAX_COMMENT_LEN-1] = '\0';
     89 	printf("/* %s */ ", commentinfo->comment);
     90 }
     91 
     92 /* Saves the union ipt_matchinfo in parsable form to stdout. */
     93 static void
     94 save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
     95 {
     96 	struct ipt_comment_info *commentinfo = (struct ipt_comment_info *)match->data;
     97 
     98 	commentinfo->comment[IPT_MAX_COMMENT_LEN-1] = '\0';
     99 	printf("--comment \"%s\" ", commentinfo->comment);
    100 }
    101 
    102 static struct iptables_match comment = {
    103     .next 		= NULL,
    104     .name 		= "comment",
    105     .version 		= IPTABLES_VERSION,
    106     .size 		= IPT_ALIGN(sizeof(struct ipt_comment_info)),
    107     .userspacesize	= IPT_ALIGN(sizeof(struct ipt_comment_info)),
    108     .help		= &help,
    109     .parse 		= &parse,
    110     .final_check 	= &final_check,
    111     .print 		= &print,
    112     .save 		= &save,
    113     .extra_opts		= opts
    114 };
    115 
    116 void ipt_comment_init(void)
    117 {
    118 	register_match(&comment);
    119 }
    120