blob: 51e5828e81432837a0e74c1adcc85b9c927940de [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",
27NETFILTER_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{
András Kis-Szabó764316a2001-02-26 17:31:20 +000047 if (strlen(s) <= BM_MAX_LEN) 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':
63 if (check_inverse(optarg, &invert))
64 optind++;
65 parse_string(argv[optind-1], stringinfo);
66 if (invert)
67 stringinfo->invert = 1;
András Kis-Szabó764316a2001-02-26 17:31:20 +000068 stringinfo->len=strlen((char *)&stringinfo->string);
Emmanuel Roger30719132000-10-04 15:19:31 +000069 *flags = 1;
70 break;
71
72 default:
73 return 0;
74 }
75 return 1;
76}
77
78static void
79print_string(char string[], int invert, int numeric)
80{
81
82 if (invert)
83 fputc('!', stdout);
84 printf("%s ",string);
85}
86
87/* Final check; must have specified --string. */
88static void
89final_check(unsigned int flags)
90{
91 if (!flags)
92 exit_error(PARAMETER_PROBLEM,
93 "STRING match: You must specify `--string'");
94}
95
96/* Prints out the matchinfo. */
97static void
98print(const struct ipt_ip *ip,
99 const struct ipt_entry_match *match,
100 int numeric)
101{
102 printf("STRING match ");
103 print_string(((struct ipt_string_info *)match->data)->string,
104 ((struct ipt_string_info *)match->data)->invert, numeric);
105}
106
107/* Saves the union ipt_matchinfo in parsable form to stdout. */
108static void
109save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
110{
András Kis-Szabó764316a2001-02-26 17:31:20 +0000111 printf("--string ");
Emmanuel Roger30719132000-10-04 15:19:31 +0000112 print_string(((struct ipt_string_info *)match->data)->string,
113 ((struct ipt_string_info *)match->data)->invert, 0);
114}
115
116struct iptables_match string
117= { NULL,
118 "string",
119 NETFILTER_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}