blob: 20613fdcb2ea7bd3b218bd9b81f5ce8c5253668d [file] [log] [blame]
Emmanuel Roger30719132000-10-04 15:19:31 +00001/* Shared library add-on to iptables to add string matching support.
2 *
3 * Copyright (C) 2000 Emmanuel Roger <winfield@freegates.be>
András Kis-Szabó764316a2001-02-26 17:31:20 +00004 *
5 * ChangeLog
6 * 27.01.2001: Gianni Tedesco <gianni@ecsc.co.uk>
7 * Changed --tos to --string in save(). Also
8 * updated to work with slightly modified
9 * ipt_string_info.
Emmanuel Roger30719132000-10-04 15:19:31 +000010 */
11#include <stdio.h>
12#include <netdb.h>
13#include <string.h>
14#include <stdlib.h>
15#include <getopt.h>
16
17#include <iptables.h>
18#include <linux/netfilter_ipv4/ipt_string.h>
19
20/* Function which prints out usage message. */
21static void
22help(void)
23{
24 printf(
25"STRING match v%s options:\n"
26"--string [!] string Match a string in a packet\n",
Harald Welte80fe35d2002-05-29 13:08:15 +000027IPTABLES_VERSION);
Emmanuel Roger30719132000-10-04 15:19:31 +000028
29 fputc('\n', stdout);
30}
31
32static struct option opts[] = {
33 { "string", 1, 0, '1' },
34 {0}
35};
36
37/* Initialize the match. */
38static void
39init(struct ipt_entry_match *m, unsigned int *nfcache)
40{
41 *nfcache |= NFC_UNKNOWN;
42}
43
44static void
45parse_string(const unsigned char *s, struct ipt_string_info *info)
46{
Harald Welte06d0b252001-05-21 18:20:56 +000047 if (strlen(s) <= BM_MAX_NLEN) strcpy(info->string, s);
Emmanuel Roger30719132000-10-04 15:19:31 +000048 else exit_error(PARAMETER_PROBLEM, "STRING too long `%s'", s);
49}
50
51/* Function which parses command options; returns true if it
52 ate an option */
53static int
54parse(int c, char **argv, int invert, unsigned int *flags,
55 const struct ipt_entry *entry,
56 unsigned int *nfcache,
57 struct ipt_entry_match **match)
58{
59 struct ipt_string_info *stringinfo = (struct ipt_string_info *)(*match)->data;
60
61 switch (c) {
62 case '1':
Harald Welteb77f1da2002-03-14 11:35:58 +000063 check_inverse(optarg, &invert, &optind, 0);
Emmanuel Roger30719132000-10-04 15:19:31 +000064 parse_string(argv[optind-1], stringinfo);
65 if (invert)
66 stringinfo->invert = 1;
András Kis-Szabó764316a2001-02-26 17:31:20 +000067 stringinfo->len=strlen((char *)&stringinfo->string);
Emmanuel Roger30719132000-10-04 15:19:31 +000068 *flags = 1;
69 break;
70
71 default:
72 return 0;
73 }
74 return 1;
75}
76
77static void
78print_string(char string[], int invert, int numeric)
79{
80
81 if (invert)
82 fputc('!', stdout);
83 printf("%s ",string);
84}
85
86/* Final check; must have specified --string. */
87static void
88final_check(unsigned int flags)
89{
90 if (!flags)
91 exit_error(PARAMETER_PROBLEM,
92 "STRING match: You must specify `--string'");
93}
94
95/* Prints out the matchinfo. */
96static void
97print(const struct ipt_ip *ip,
98 const struct ipt_entry_match *match,
99 int numeric)
100{
101 printf("STRING match ");
102 print_string(((struct ipt_string_info *)match->data)->string,
103 ((struct ipt_string_info *)match->data)->invert, numeric);
104}
105
106/* Saves the union ipt_matchinfo in parsable form to stdout. */
107static void
108save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
109{
András Kis-Szabó764316a2001-02-26 17:31:20 +0000110 printf("--string ");
Emmanuel Roger30719132000-10-04 15:19:31 +0000111 print_string(((struct ipt_string_info *)match->data)->string,
112 ((struct ipt_string_info *)match->data)->invert, 0);
113}
114
Harald Welte3efb6ea2001-08-06 18:50:21 +0000115static
Emmanuel Roger30719132000-10-04 15:19:31 +0000116struct iptables_match string
117= { NULL,
118 "string",
Harald Welte80fe35d2002-05-29 13:08:15 +0000119 IPTABLES_VERSION,
Emmanuel Roger30719132000-10-04 15:19:31 +0000120 IPT_ALIGN(sizeof(struct ipt_string_info)),
121 IPT_ALIGN(sizeof(struct ipt_string_info)),
122 &help,
123 &init,
124 &parse,
125 &final_check,
126 &print,
127 &save,
128 opts
129};
130
131void _init(void)
132{
133 register_match(&string);
134}