Merge to iptables-1.3.5
[iptables.git] / extensions / libipt_comment.c
1 /* Shared library add-on to iptables to add comment match support.
2  *
3  * ChangeLog
4  *     2003-05-13: Brad Fisher <brad@info-link.net>
5  *         Initial comment match
6  *     2004-05-12: Brad Fisher <brad@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 _init(void)
117 {
118         register_match(&comment);
119 }