Imported Upstream version 1.4.14
[platform/upstream/iptables.git] / extensions / libipt_LOG.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <syslog.h>
4 #include <xtables.h>
5 #include <linux/netfilter_ipv4/ipt_LOG.h>
6
7 #define LOG_DEFAULT_LEVEL LOG_WARNING
8
9 #ifndef IPT_LOG_UID /* Old kernel */
10 #define IPT_LOG_UID     0x08    /* Log UID owning local socket */
11 #undef  IPT_LOG_MASK
12 #define IPT_LOG_MASK    0x0f
13 #endif
14
15 enum {
16         O_LOG_LEVEL = 0,
17         O_LOG_PREFIX,
18         O_LOG_TCPSEQ,
19         O_LOG_TCPOPTS,
20         O_LOG_IPOPTS,
21         O_LOG_UID,
22         O_LOG_MAC,
23 };
24
25 static void LOG_help(void)
26 {
27         printf(
28 "LOG target options:\n"
29 " --log-level level             Level of logging (numeric or see syslog.conf)\n"
30 " --log-prefix prefix           Prefix log messages with this prefix.\n\n"
31 " --log-tcp-sequence            Log TCP sequence numbers.\n\n"
32 " --log-tcp-options             Log TCP options.\n\n"
33 " --log-ip-options              Log IP options.\n\n"
34 " --log-uid                     Log UID owning the local socket.\n\n"
35 " --log-macdecode               Decode MAC addresses and protocol.\n\n");
36 }
37
38 #define s struct ipt_log_info
39 static const struct xt_option_entry LOG_opts[] = {
40         {.name = "log-level", .id = O_LOG_LEVEL, .type = XTTYPE_SYSLOGLEVEL,
41          .flags = XTOPT_PUT, XTOPT_POINTER(s, level)},
42         {.name = "log-prefix", .id = O_LOG_PREFIX, .type = XTTYPE_STRING,
43          .flags = XTOPT_PUT, XTOPT_POINTER(s, prefix), .min = 1},
44         {.name = "log-tcp-sequence", .id = O_LOG_TCPSEQ, .type = XTTYPE_NONE},
45         {.name = "log-tcp-options", .id = O_LOG_TCPOPTS, .type = XTTYPE_NONE},
46         {.name = "log-ip-options", .id = O_LOG_IPOPTS, .type = XTTYPE_NONE},
47         {.name = "log-uid", .id = O_LOG_UID, .type = XTTYPE_NONE},
48         {.name = "log-macdecode", .id = O_LOG_MAC, .type = XTTYPE_NONE},
49         XTOPT_TABLEEND,
50 };
51 #undef s
52
53 static void LOG_init(struct xt_entry_target *t)
54 {
55         struct ipt_log_info *loginfo = (struct ipt_log_info *)t->data;
56
57         loginfo->level = LOG_DEFAULT_LEVEL;
58
59 }
60
61 struct ipt_log_names {
62         const char *name;
63         unsigned int level;
64 };
65
66 static const struct ipt_log_names ipt_log_names[]
67 = { { .name = "alert",   .level = LOG_ALERT },
68     { .name = "crit",    .level = LOG_CRIT },
69     { .name = "debug",   .level = LOG_DEBUG },
70     { .name = "emerg",   .level = LOG_EMERG },
71     { .name = "error",   .level = LOG_ERR },            /* DEPRECATED */
72     { .name = "info",    .level = LOG_INFO },
73     { .name = "notice",  .level = LOG_NOTICE },
74     { .name = "panic",   .level = LOG_EMERG },          /* DEPRECATED */
75     { .name = "warning", .level = LOG_WARNING }
76 };
77
78 static void LOG_parse(struct xt_option_call *cb)
79 {
80         struct ipt_log_info *info = cb->data;
81
82         xtables_option_parse(cb);
83         switch (cb->entry->id) {
84         case O_LOG_PREFIX:
85                 if (strchr(cb->arg, '\n') != NULL)
86                         xtables_error(PARAMETER_PROBLEM,
87                                    "Newlines not allowed in --log-prefix");
88                 break;
89         case O_LOG_TCPSEQ:
90                 info->logflags |= IPT_LOG_TCPSEQ;
91                 break;
92         case O_LOG_TCPOPTS:
93                 info->logflags |= IPT_LOG_TCPOPT;
94                 break;
95         case O_LOG_IPOPTS:
96                 info->logflags |= IPT_LOG_IPOPT;
97                 break;
98         case O_LOG_UID:
99                 info->logflags |= IPT_LOG_UID;
100                 break;
101         case O_LOG_MAC:
102                 info->logflags |= IPT_LOG_MACDECODE;
103                 break;
104         }
105 }
106
107 static void LOG_print(const void *ip, const struct xt_entry_target *target,
108                       int numeric)
109 {
110         const struct ipt_log_info *loginfo
111                 = (const struct ipt_log_info *)target->data;
112         unsigned int i = 0;
113
114         printf(" LOG");
115         if (numeric)
116                 printf(" flags %u level %u",
117                        loginfo->logflags, loginfo->level);
118         else {
119                 for (i = 0; i < ARRAY_SIZE(ipt_log_names); ++i)
120                         if (loginfo->level == ipt_log_names[i].level) {
121                                 printf(" level %s", ipt_log_names[i].name);
122                                 break;
123                         }
124                 if (i == ARRAY_SIZE(ipt_log_names))
125                         printf(" UNKNOWN level %u", loginfo->level);
126                 if (loginfo->logflags & IPT_LOG_TCPSEQ)
127                         printf(" tcp-sequence");
128                 if (loginfo->logflags & IPT_LOG_TCPOPT)
129                         printf(" tcp-options");
130                 if (loginfo->logflags & IPT_LOG_IPOPT)
131                         printf(" ip-options");
132                 if (loginfo->logflags & IPT_LOG_UID)
133                         printf(" uid");
134                 if (loginfo->logflags & IPT_LOG_MACDECODE)
135                         printf(" macdecode");
136                 if (loginfo->logflags & ~(IPT_LOG_MASK))
137                         printf(" unknown-flags");
138         }
139
140         if (strcmp(loginfo->prefix, "") != 0)
141                 printf(" prefix \"%s\"", loginfo->prefix);
142 }
143
144 static void LOG_save(const void *ip, const struct xt_entry_target *target)
145 {
146         const struct ipt_log_info *loginfo
147                 = (const struct ipt_log_info *)target->data;
148
149         if (strcmp(loginfo->prefix, "") != 0) {
150                 printf(" --log-prefix");
151                 xtables_save_string(loginfo->prefix);
152         }
153
154         if (loginfo->level != LOG_DEFAULT_LEVEL)
155                 printf(" --log-level %d", loginfo->level);
156
157         if (loginfo->logflags & IPT_LOG_TCPSEQ)
158                 printf(" --log-tcp-sequence");
159         if (loginfo->logflags & IPT_LOG_TCPOPT)
160                 printf(" --log-tcp-options");
161         if (loginfo->logflags & IPT_LOG_IPOPT)
162                 printf(" --log-ip-options");
163         if (loginfo->logflags & IPT_LOG_UID)
164                 printf(" --log-uid");
165         if (loginfo->logflags & IPT_LOG_MACDECODE)
166                 printf(" --log-macdecode");
167 }
168
169 static struct xtables_target log_tg_reg = {
170         .name          = "LOG",
171         .version       = XTABLES_VERSION,
172         .family        = NFPROTO_IPV4,
173         .size          = XT_ALIGN(sizeof(struct ipt_log_info)),
174         .userspacesize = XT_ALIGN(sizeof(struct ipt_log_info)),
175         .help          = LOG_help,
176         .init          = LOG_init,
177         .print         = LOG_print,
178         .save          = LOG_save,
179         .x6_parse      = LOG_parse,
180         .x6_options    = LOG_opts,
181 };
182
183 void _init(void)
184 {
185         xtables_register_target(&log_tg_reg);
186 }