1 /* Shared library add-on to iptables to add UDP support. */
8 #include <linux/netfilter_ipv4/ip_tables.h>
10 /* Function which prints out usage message. */
16 " --source-port [!] port[:port]\n"
18 " match source port(s)\n"
19 " --destination-port [!] port[:port]\n"
21 " match destination port(s)\n",
25 static struct option opts
[] = {
26 { "source-port", 1, 0, '1' },
27 { "sport", 1, 0, '1' }, /* synonym */
28 { "destination-port", 1, 0, '2' },
29 { "dport", 1, 0, '2' }, /* synonym */
34 parse_udp_ports(const char *portstring
, u_int16_t
*ports
)
39 buffer
= strdup(portstring
);
40 if ((cp
= strchr(buffer
, ':')) == NULL
)
41 ports
[0] = ports
[1] = parse_port(buffer
, "udp");
46 ports
[0] = buffer
[0] ? parse_port(buffer
, "udp") : 0;
47 ports
[1] = cp
[0] ? parse_port(cp
, "udp") : 0xFFFF;
49 if (ports
[0] > ports
[1])
50 exit_error(PARAMETER_PROBLEM
,
51 "invalid portrange (min > max)");
56 /* Initialize the match. */
58 init(struct ipt_entry_match
*m
, unsigned int *nfcache
)
60 struct ipt_udp
*udpinfo
= (struct ipt_udp
*)m
->data
;
62 udpinfo
->spts
[1] = udpinfo
->dpts
[1] = 0xFFFF;
65 #define UDP_SRC_PORTS 0x01
66 #define UDP_DST_PORTS 0x02
68 /* Function which parses command options; returns true if it
71 parse(int c
, char **argv
, int invert
, unsigned int *flags
,
72 const struct ipt_entry
*entry
,
73 unsigned int *nfcache
,
74 struct ipt_entry_match
**match
)
76 struct ipt_udp
*udpinfo
= (struct ipt_udp
*)(*match
)->data
;
80 if (*flags
& UDP_SRC_PORTS
)
81 exit_error(PARAMETER_PROBLEM
,
82 "Only one `--source-port' allowed");
83 check_inverse(optarg
, &invert
, &optind
, 0);
84 parse_udp_ports(argv
[optind
-1], udpinfo
->spts
);
86 udpinfo
->invflags
|= IPT_UDP_INV_SRCPT
;
87 *flags
|= UDP_SRC_PORTS
;
91 if (*flags
& UDP_DST_PORTS
)
92 exit_error(PARAMETER_PROBLEM
,
93 "Only one `--destination-port' allowed");
94 check_inverse(optarg
, &invert
, &optind
, 0);
95 parse_udp_ports(argv
[optind
-1], udpinfo
->dpts
);
97 udpinfo
->invflags
|= IPT_UDP_INV_DSTPT
;
98 *flags
|= UDP_DST_PORTS
;
108 /* Final check; we don't care. */
110 final_check(unsigned int flags
)
115 port_to_service(int port
)
117 struct servent
*service
;
119 if ((service
= getservbyport(htons(port
), "udp")))
120 return service
->s_name
;
126 print_port(u_int16_t port
, int numeric
)
130 if (numeric
|| (service
= port_to_service(port
)) == NULL
)
133 printf("%s", service
);
137 print_ports(const char *name
, u_int16_t min
, u_int16_t max
,
138 int invert
, int numeric
)
140 const char *inv
= invert
? "!" : "";
142 if (min
!= 0 || max
!= 0xFFFF || invert
) {
146 print_port(min
, numeric
);
149 print_port(min
, numeric
);
151 print_port(max
, numeric
);
157 /* Prints out the union ipt_matchinfo. */
159 print(const struct ipt_ip
*ip
,
160 const struct ipt_entry_match
*match
, int numeric
)
162 const struct ipt_udp
*udp
= (struct ipt_udp
*)match
->data
;
165 print_ports("spt", udp
->spts
[0], udp
->spts
[1],
166 udp
->invflags
& IPT_UDP_INV_SRCPT
,
168 print_ports("dpt", udp
->dpts
[0], udp
->dpts
[1],
169 udp
->invflags
& IPT_UDP_INV_DSTPT
,
171 if (udp
->invflags
& ~IPT_UDP_INV_MASK
)
172 printf("Unknown invflags: 0x%X ",
173 udp
->invflags
& ~IPT_UDP_INV_MASK
);
176 /* Saves the union ipt_matchinfo in parsable form to stdout. */
177 static void save(const struct ipt_ip
*ip
, const struct ipt_entry_match
*match
)
179 const struct ipt_udp
*udpinfo
= (struct ipt_udp
*)match
->data
;
181 if (udpinfo
->spts
[0] != 0
182 || udpinfo
->spts
[1] != 0xFFFF) {
183 if (udpinfo
->invflags
& IPT_UDP_INV_SRCPT
)
187 printf("--sport %u:%u ",
191 printf("--sport %u ",
195 if (udpinfo
->dpts
[0] != 0
196 || udpinfo
->dpts
[1] != 0xFFFF) {
197 if (udpinfo
->invflags
& IPT_UDP_INV_DSTPT
)
201 printf("--dport %u:%u ",
205 printf("--dport %u ",
211 struct iptables_match udp
= {
214 .version
= IPTABLES_VERSION
,
215 .size
= IPT_ALIGN(sizeof(struct ipt_udp
)),
216 .userspacesize
= IPT_ALIGN(sizeof(struct ipt_udp
)),
220 .final_check
= &final_check
,
229 register_match(&udp
);