1/* Shared library add-on to iptables to add string matching support.
2 *
3 * Copyright (C) 2000 Emmanuel Roger  <winfield@freegates.be>
4 *
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.
10 */
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",
27IPTABLES_VERSION);
28
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{
47        if (strlen(s) <= BM_MAX_NLEN) strcpy(info->string, s);
48	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':
63		check_inverse(optarg, &invert, &optind, 0);
64		parse_string(argv[optind-1], stringinfo);
65		if (invert)
66			stringinfo->invert = 1;
67                stringinfo->len=strlen((char *)&stringinfo->string);
68		*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{
110	printf("--string ");
111	print_string(((struct ipt_string_info *)match->data)->string,
112		  ((struct ipt_string_info *)match->data)->invert, 0);
113}
114
115static
116struct iptables_match string
117= { NULL,
118    "string",
119    IPTABLES_VERSION,
120    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}
135