~csurbhi/ubuntu/maverick/iptables/iptable-fix.600195

« back to all changes in this revision

Viewing changes to extensions/libxt_udp.c

  • Committer: Bazaar Package Importer
  • Author(s): Soren Hansen
  • Date: 2008-06-24 15:06:04 UTC
  • mfrom: (5.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20080624150604-5t7r1o1kxq0ycz81
Tags: 1.4.0-4ubuntu1
* Merge from debian unstable, remaining changes:
  - Took references to 2.4 kernel out of doc-base control files (Jordan
    Mantha, Malone #25972) (patches/all/091-fix-2.4-references.patch)
  - Use linux-libc-dev instead of local copy of kernel-headers.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Shared library add-on to iptables to add UDP support. */
 
2
#include <stdio.h>
 
3
#include <netdb.h>
 
4
#include <string.h>
 
5
#include <stdlib.h>
 
6
#include <getopt.h>
 
7
#include <xtables.h>
 
8
#include <linux/netfilter/xt_tcpudp.h>
 
9
 
 
10
/* Function which prints out usage message. */
 
11
static void udp_help(void)
 
12
{
 
13
        printf(
 
14
"UDP v%s options:\n"
 
15
" --source-port [!] port[:port]\n"
 
16
" --sport ...\n"
 
17
"                               match source port(s)\n"
 
18
" --destination-port [!] port[:port]\n"
 
19
" --dport ...\n"
 
20
"                               match destination port(s)\n",
 
21
IPTABLES_VERSION);
 
22
}
 
23
 
 
24
static const struct option udp_opts[] = {
 
25
        { "source-port", 1, NULL, '1' },
 
26
        { "sport", 1, NULL, '1' }, /* synonym */
 
27
        { "destination-port", 1, NULL, '2' },
 
28
        { "dport", 1, NULL, '2' }, /* synonym */
 
29
        { }
 
30
};
 
31
 
 
32
static void
 
33
parse_udp_ports(const char *portstring, u_int16_t *ports)
 
34
{
 
35
        char *buffer;
 
36
        char *cp;
 
37
 
 
38
        buffer = strdup(portstring);
 
39
        if ((cp = strchr(buffer, ':')) == NULL)
 
40
                ports[0] = ports[1] = parse_port(buffer, "udp");
 
41
        else {
 
42
                *cp = '\0';
 
43
                cp++;
 
44
 
 
45
                ports[0] = buffer[0] ? parse_port(buffer, "udp") : 0;
 
46
                ports[1] = cp[0] ? parse_port(cp, "udp") : 0xFFFF;
 
47
 
 
48
                if (ports[0] > ports[1])
 
49
                        exit_error(PARAMETER_PROBLEM,
 
50
                                   "invalid portrange (min > max)");
 
51
        }
 
52
        free(buffer);
 
53
}
 
54
 
 
55
/* Initialize the match. */
 
56
static void udp_init(struct xt_entry_match *m)
 
57
{
 
58
        struct xt_udp *udpinfo = (struct xt_udp *)m->data;
 
59
 
 
60
        udpinfo->spts[1] = udpinfo->dpts[1] = 0xFFFF;
 
61
}
 
62
 
 
63
#define UDP_SRC_PORTS 0x01
 
64
#define UDP_DST_PORTS 0x02
 
65
 
 
66
/* Function which parses command options; returns true if it
 
67
   ate an option */
 
68
static int
 
69
udp_parse(int c, char **argv, int invert, unsigned int *flags,
 
70
          const void *entry, struct xt_entry_match **match)
 
71
{
 
72
        struct xt_udp *udpinfo = (struct xt_udp *)(*match)->data;
 
73
 
 
74
        switch (c) {
 
75
        case '1':
 
76
                if (*flags & UDP_SRC_PORTS)
 
77
                        exit_error(PARAMETER_PROBLEM,
 
78
                                   "Only one `--source-port' allowed");
 
79
                check_inverse(optarg, &invert, &optind, 0);
 
80
                parse_udp_ports(argv[optind-1], udpinfo->spts);
 
81
                if (invert)
 
82
                        udpinfo->invflags |= XT_UDP_INV_SRCPT;
 
83
                *flags |= UDP_SRC_PORTS;
 
84
                break;
 
85
 
 
86
        case '2':
 
87
                if (*flags & UDP_DST_PORTS)
 
88
                        exit_error(PARAMETER_PROBLEM,
 
89
                                   "Only one `--destination-port' allowed");
 
90
                check_inverse(optarg, &invert, &optind, 0);
 
91
                parse_udp_ports(argv[optind-1], udpinfo->dpts);
 
92
                if (invert)
 
93
                        udpinfo->invflags |= XT_UDP_INV_DSTPT;
 
94
                *flags |= UDP_DST_PORTS;
 
95
                break;
 
96
 
 
97
        default:
 
98
                return 0;
 
99
        }
 
100
 
 
101
        return 1;
 
102
}
 
103
 
 
104
static char *
 
105
port_to_service(int port)
 
106
{
 
107
        struct servent *service;
 
108
 
 
109
        if ((service = getservbyport(htons(port), "udp")))
 
110
                return service->s_name;
 
111
 
 
112
        return NULL;
 
113
}
 
114
 
 
115
static void
 
116
print_port(u_int16_t port, int numeric)
 
117
{
 
118
        char *service;
 
119
 
 
120
        if (numeric || (service = port_to_service(port)) == NULL)
 
121
                printf("%u", port);
 
122
        else
 
123
                printf("%s", service);
 
124
}
 
125
 
 
126
static void
 
127
print_ports(const char *name, u_int16_t min, u_int16_t max,
 
128
            int invert, int numeric)
 
129
{
 
130
        const char *inv = invert ? "!" : "";
 
131
 
 
132
        if (min != 0 || max != 0xFFFF || invert) {
 
133
                printf("%s", name);
 
134
                if (min == max) {
 
135
                        printf(":%s", inv);
 
136
                        print_port(min, numeric);
 
137
                } else {
 
138
                        printf("s:%s", inv);
 
139
                        print_port(min, numeric);
 
140
                        printf(":");
 
141
                        print_port(max, numeric);
 
142
                }
 
143
                printf(" ");
 
144
        }
 
145
}
 
146
 
 
147
/* Prints out the union ipt_matchinfo. */
 
148
static void
 
149
udp_print(const void *ip, const struct xt_entry_match *match, int numeric)
 
150
{
 
151
        const struct xt_udp *udp = (struct xt_udp *)match->data;
 
152
 
 
153
        printf("udp ");
 
154
        print_ports("spt", udp->spts[0], udp->spts[1],
 
155
                    udp->invflags & XT_UDP_INV_SRCPT,
 
156
                    numeric);
 
157
        print_ports("dpt", udp->dpts[0], udp->dpts[1],
 
158
                    udp->invflags & XT_UDP_INV_DSTPT,
 
159
                    numeric);
 
160
        if (udp->invflags & ~XT_UDP_INV_MASK)
 
161
                printf("Unknown invflags: 0x%X ",
 
162
                       udp->invflags & ~XT_UDP_INV_MASK);
 
163
}
 
164
 
 
165
/* Saves the union ipt_matchinfo in parsable form to stdout. */
 
166
static void udp_save(const void *ip, const struct xt_entry_match *match)
 
167
{
 
168
        const struct xt_udp *udpinfo = (struct xt_udp *)match->data;
 
169
 
 
170
        if (udpinfo->spts[0] != 0
 
171
            || udpinfo->spts[1] != 0xFFFF) {
 
172
                if (udpinfo->invflags & XT_UDP_INV_SRCPT)
 
173
                        printf("! ");
 
174
                if (udpinfo->spts[0]
 
175
                    != udpinfo->spts[1])
 
176
                        printf("--sport %u:%u ",
 
177
                               udpinfo->spts[0],
 
178
                               udpinfo->spts[1]);
 
179
                else
 
180
                        printf("--sport %u ",
 
181
                               udpinfo->spts[0]);
 
182
        }
 
183
 
 
184
        if (udpinfo->dpts[0] != 0
 
185
            || udpinfo->dpts[1] != 0xFFFF) {
 
186
                if (udpinfo->invflags & XT_UDP_INV_DSTPT)
 
187
                        printf("! ");
 
188
                if (udpinfo->dpts[0]
 
189
                    != udpinfo->dpts[1])
 
190
                        printf("--dport %u:%u ",
 
191
                               udpinfo->dpts[0],
 
192
                               udpinfo->dpts[1]);
 
193
                else
 
194
                        printf("--dport %u ",
 
195
                               udpinfo->dpts[0]);
 
196
        }
 
197
}
 
198
 
 
199
static struct xtables_match udp_match = {
 
200
        .family         = AF_INET,
 
201
        .name           = "udp",
 
202
        .version        = IPTABLES_VERSION,
 
203
        .size           = XT_ALIGN(sizeof(struct xt_udp)),
 
204
        .userspacesize  = XT_ALIGN(sizeof(struct xt_udp)),
 
205
        .help           = udp_help,
 
206
        .init           = udp_init,
 
207
        .parse          = udp_parse,
 
208
        .print          = udp_print,
 
209
        .save           = udp_save,
 
210
        .extra_opts     = udp_opts,
 
211
};
 
212
 
 
213
static struct xtables_match udp_match6 = {
 
214
        .family         = AF_INET6,
 
215
        .name           = "udp",
 
216
        .version        = IPTABLES_VERSION,
 
217
        .size           = XT_ALIGN(sizeof(struct xt_udp)),
 
218
        .userspacesize  = XT_ALIGN(sizeof(struct xt_udp)),
 
219
        .help           = udp_help,
 
220
        .init           = udp_init,
 
221
        .parse          = udp_parse,
 
222
        .print          = udp_print,
 
223
        .save           = udp_save,
 
224
        .extra_opts     = udp_opts,
 
225
};
 
226
 
 
227
void
 
228
_init(void)
 
229
{
 
230
        xtables_register_match(&udp_match);
 
231
        xtables_register_match(&udp_match6);
 
232
}