libxt_string.c revision 764316a133db8e5e2d1f2a9d941ffae993d7c9d9
13071913784b69423fd25c3db2344e585872920ccEmmanuel Roger/* Shared library add-on to iptables to add string matching support.
23071913784b69423fd25c3db2344e585872920ccEmmanuel Roger *
33071913784b69423fd25c3db2344e585872920ccEmmanuel Roger * Copyright (C) 2000 Emmanuel Roger  <winfield@freegates.be>
4764316a133db8e5e2d1f2a9d941ffae993d7c9d9András Kis-Szabó *
5764316a133db8e5e2d1f2a9d941ffae993d7c9d9András Kis-Szabó * ChangeLog
6764316a133db8e5e2d1f2a9d941ffae993d7c9d9András Kis-Szabó *     27.01.2001: Gianni Tedesco <gianni@ecsc.co.uk>
7764316a133db8e5e2d1f2a9d941ffae993d7c9d9András Kis-Szabó *             Changed --tos to --string in save(). Also
8764316a133db8e5e2d1f2a9d941ffae993d7c9d9András Kis-Szabó *             updated to work with slightly modified
9764316a133db8e5e2d1f2a9d941ffae993d7c9d9András Kis-Szabó *             ipt_string_info.
103071913784b69423fd25c3db2344e585872920ccEmmanuel Roger */
113071913784b69423fd25c3db2344e585872920ccEmmanuel Roger#include <stdio.h>
123071913784b69423fd25c3db2344e585872920ccEmmanuel Roger#include <netdb.h>
133071913784b69423fd25c3db2344e585872920ccEmmanuel Roger#include <string.h>
143071913784b69423fd25c3db2344e585872920ccEmmanuel Roger#include <stdlib.h>
153071913784b69423fd25c3db2344e585872920ccEmmanuel Roger#include <getopt.h>
163071913784b69423fd25c3db2344e585872920ccEmmanuel Roger
173071913784b69423fd25c3db2344e585872920ccEmmanuel Roger#include <iptables.h>
183071913784b69423fd25c3db2344e585872920ccEmmanuel Roger#include <linux/netfilter_ipv4/ipt_string.h>
193071913784b69423fd25c3db2344e585872920ccEmmanuel Roger
203071913784b69423fd25c3db2344e585872920ccEmmanuel Roger/* Function which prints out usage message. */
213071913784b69423fd25c3db2344e585872920ccEmmanuel Rogerstatic void
223071913784b69423fd25c3db2344e585872920ccEmmanuel Rogerhelp(void)
233071913784b69423fd25c3db2344e585872920ccEmmanuel Roger{
243071913784b69423fd25c3db2344e585872920ccEmmanuel Roger	printf(
253071913784b69423fd25c3db2344e585872920ccEmmanuel Roger"STRING match v%s options:\n"
263071913784b69423fd25c3db2344e585872920ccEmmanuel Roger"--string [!] string             Match a string in a packet\n",
273071913784b69423fd25c3db2344e585872920ccEmmanuel RogerNETFILTER_VERSION);
283071913784b69423fd25c3db2344e585872920ccEmmanuel Roger
293071913784b69423fd25c3db2344e585872920ccEmmanuel Roger	fputc('\n', stdout);
303071913784b69423fd25c3db2344e585872920ccEmmanuel Roger}
313071913784b69423fd25c3db2344e585872920ccEmmanuel Roger
323071913784b69423fd25c3db2344e585872920ccEmmanuel Rogerstatic struct option opts[] = {
333071913784b69423fd25c3db2344e585872920ccEmmanuel Roger	{ "string", 1, 0, '1' },
343071913784b69423fd25c3db2344e585872920ccEmmanuel Roger	{0}
353071913784b69423fd25c3db2344e585872920ccEmmanuel Roger};
363071913784b69423fd25c3db2344e585872920ccEmmanuel Roger
373071913784b69423fd25c3db2344e585872920ccEmmanuel Roger/* Initialize the match. */
383071913784b69423fd25c3db2344e585872920ccEmmanuel Rogerstatic void
393071913784b69423fd25c3db2344e585872920ccEmmanuel Rogerinit(struct ipt_entry_match *m, unsigned int *nfcache)
403071913784b69423fd25c3db2344e585872920ccEmmanuel Roger{
413071913784b69423fd25c3db2344e585872920ccEmmanuel Roger	*nfcache |= NFC_UNKNOWN;
423071913784b69423fd25c3db2344e585872920ccEmmanuel Roger}
433071913784b69423fd25c3db2344e585872920ccEmmanuel Roger
443071913784b69423fd25c3db2344e585872920ccEmmanuel Rogerstatic void
453071913784b69423fd25c3db2344e585872920ccEmmanuel Rogerparse_string(const unsigned char *s, struct ipt_string_info *info)
463071913784b69423fd25c3db2344e585872920ccEmmanuel Roger{
47764316a133db8e5e2d1f2a9d941ffae993d7c9d9András Kis-Szabó        if (strlen(s) <= BM_MAX_LEN) strcpy(info->string, s);
483071913784b69423fd25c3db2344e585872920ccEmmanuel Roger	else exit_error(PARAMETER_PROBLEM, "STRING too long `%s'", s);
493071913784b69423fd25c3db2344e585872920ccEmmanuel Roger}
503071913784b69423fd25c3db2344e585872920ccEmmanuel Roger
513071913784b69423fd25c3db2344e585872920ccEmmanuel Roger/* Function which parses command options; returns true if it
523071913784b69423fd25c3db2344e585872920ccEmmanuel Roger   ate an option */
533071913784b69423fd25c3db2344e585872920ccEmmanuel Rogerstatic int
543071913784b69423fd25c3db2344e585872920ccEmmanuel Rogerparse(int c, char **argv, int invert, unsigned int *flags,
553071913784b69423fd25c3db2344e585872920ccEmmanuel Roger      const struct ipt_entry *entry,
563071913784b69423fd25c3db2344e585872920ccEmmanuel Roger      unsigned int *nfcache,
573071913784b69423fd25c3db2344e585872920ccEmmanuel Roger      struct ipt_entry_match **match)
583071913784b69423fd25c3db2344e585872920ccEmmanuel Roger{
593071913784b69423fd25c3db2344e585872920ccEmmanuel Roger	struct ipt_string_info *stringinfo = (struct ipt_string_info *)(*match)->data;
603071913784b69423fd25c3db2344e585872920ccEmmanuel Roger
613071913784b69423fd25c3db2344e585872920ccEmmanuel Roger	switch (c) {
623071913784b69423fd25c3db2344e585872920ccEmmanuel Roger	case '1':
633071913784b69423fd25c3db2344e585872920ccEmmanuel Roger		if (check_inverse(optarg, &invert))
643071913784b69423fd25c3db2344e585872920ccEmmanuel Roger			optind++;
653071913784b69423fd25c3db2344e585872920ccEmmanuel Roger		parse_string(argv[optind-1], stringinfo);
663071913784b69423fd25c3db2344e585872920ccEmmanuel Roger		if (invert)
673071913784b69423fd25c3db2344e585872920ccEmmanuel Roger			stringinfo->invert = 1;
68764316a133db8e5e2d1f2a9d941ffae993d7c9d9András Kis-Szabó                stringinfo->len=strlen((char *)&stringinfo->string);
693071913784b69423fd25c3db2344e585872920ccEmmanuel Roger		*flags = 1;
703071913784b69423fd25c3db2344e585872920ccEmmanuel Roger		break;
713071913784b69423fd25c3db2344e585872920ccEmmanuel Roger
723071913784b69423fd25c3db2344e585872920ccEmmanuel Roger	default:
733071913784b69423fd25c3db2344e585872920ccEmmanuel Roger		return 0;
743071913784b69423fd25c3db2344e585872920ccEmmanuel Roger	}
753071913784b69423fd25c3db2344e585872920ccEmmanuel Roger	return 1;
763071913784b69423fd25c3db2344e585872920ccEmmanuel Roger}
773071913784b69423fd25c3db2344e585872920ccEmmanuel Roger
783071913784b69423fd25c3db2344e585872920ccEmmanuel Rogerstatic void
793071913784b69423fd25c3db2344e585872920ccEmmanuel Rogerprint_string(char string[], int invert, int numeric)
803071913784b69423fd25c3db2344e585872920ccEmmanuel Roger{
813071913784b69423fd25c3db2344e585872920ccEmmanuel Roger
823071913784b69423fd25c3db2344e585872920ccEmmanuel Roger	if (invert)
833071913784b69423fd25c3db2344e585872920ccEmmanuel Roger		fputc('!', stdout);
843071913784b69423fd25c3db2344e585872920ccEmmanuel Roger	printf("%s ",string);
853071913784b69423fd25c3db2344e585872920ccEmmanuel Roger}
863071913784b69423fd25c3db2344e585872920ccEmmanuel Roger
873071913784b69423fd25c3db2344e585872920ccEmmanuel Roger/* Final check; must have specified --string. */
883071913784b69423fd25c3db2344e585872920ccEmmanuel Rogerstatic void
893071913784b69423fd25c3db2344e585872920ccEmmanuel Rogerfinal_check(unsigned int flags)
903071913784b69423fd25c3db2344e585872920ccEmmanuel Roger{
913071913784b69423fd25c3db2344e585872920ccEmmanuel Roger	if (!flags)
923071913784b69423fd25c3db2344e585872920ccEmmanuel Roger		exit_error(PARAMETER_PROBLEM,
933071913784b69423fd25c3db2344e585872920ccEmmanuel Roger			   "STRING match: You must specify `--string'");
943071913784b69423fd25c3db2344e585872920ccEmmanuel Roger}
953071913784b69423fd25c3db2344e585872920ccEmmanuel Roger
963071913784b69423fd25c3db2344e585872920ccEmmanuel Roger/* Prints out the matchinfo. */
973071913784b69423fd25c3db2344e585872920ccEmmanuel Rogerstatic void
983071913784b69423fd25c3db2344e585872920ccEmmanuel Rogerprint(const struct ipt_ip *ip,
993071913784b69423fd25c3db2344e585872920ccEmmanuel Roger      const struct ipt_entry_match *match,
1003071913784b69423fd25c3db2344e585872920ccEmmanuel Roger      int numeric)
1013071913784b69423fd25c3db2344e585872920ccEmmanuel Roger{
1023071913784b69423fd25c3db2344e585872920ccEmmanuel Roger	printf("STRING match ");
1033071913784b69423fd25c3db2344e585872920ccEmmanuel Roger	print_string(((struct ipt_string_info *)match->data)->string,
1043071913784b69423fd25c3db2344e585872920ccEmmanuel Roger		  ((struct ipt_string_info *)match->data)->invert, numeric);
1053071913784b69423fd25c3db2344e585872920ccEmmanuel Roger}
1063071913784b69423fd25c3db2344e585872920ccEmmanuel Roger
1073071913784b69423fd25c3db2344e585872920ccEmmanuel Roger/* Saves the union ipt_matchinfo in parsable form to stdout. */
1083071913784b69423fd25c3db2344e585872920ccEmmanuel Rogerstatic void
1093071913784b69423fd25c3db2344e585872920ccEmmanuel Rogersave(const struct ipt_ip *ip, const struct ipt_entry_match *match)
1103071913784b69423fd25c3db2344e585872920ccEmmanuel Roger{
111764316a133db8e5e2d1f2a9d941ffae993d7c9d9András Kis-Szabó	printf("--string ");
1123071913784b69423fd25c3db2344e585872920ccEmmanuel Roger	print_string(((struct ipt_string_info *)match->data)->string,
1133071913784b69423fd25c3db2344e585872920ccEmmanuel Roger		  ((struct ipt_string_info *)match->data)->invert, 0);
1143071913784b69423fd25c3db2344e585872920ccEmmanuel Roger}
1153071913784b69423fd25c3db2344e585872920ccEmmanuel Roger
1163071913784b69423fd25c3db2344e585872920ccEmmanuel Rogerstruct iptables_match string
1173071913784b69423fd25c3db2344e585872920ccEmmanuel Roger= { NULL,
1183071913784b69423fd25c3db2344e585872920ccEmmanuel Roger    "string",
1193071913784b69423fd25c3db2344e585872920ccEmmanuel Roger    NETFILTER_VERSION,
1203071913784b69423fd25c3db2344e585872920ccEmmanuel Roger    IPT_ALIGN(sizeof(struct ipt_string_info)),
1213071913784b69423fd25c3db2344e585872920ccEmmanuel Roger    IPT_ALIGN(sizeof(struct ipt_string_info)),
1223071913784b69423fd25c3db2344e585872920ccEmmanuel Roger    &help,
1233071913784b69423fd25c3db2344e585872920ccEmmanuel Roger    &init,
1243071913784b69423fd25c3db2344e585872920ccEmmanuel Roger    &parse,
1253071913784b69423fd25c3db2344e585872920ccEmmanuel Roger    &final_check,
1263071913784b69423fd25c3db2344e585872920ccEmmanuel Roger    &print,
1273071913784b69423fd25c3db2344e585872920ccEmmanuel Roger    &save,
1283071913784b69423fd25c3db2344e585872920ccEmmanuel Roger    opts
1293071913784b69423fd25c3db2344e585872920ccEmmanuel Roger};
1303071913784b69423fd25c3db2344e585872920ccEmmanuel Roger
1313071913784b69423fd25c3db2344e585872920ccEmmanuel Rogervoid _init(void)
1323071913784b69423fd25c3db2344e585872920ccEmmanuel Roger{
1333071913784b69423fd25c3db2344e585872920ccEmmanuel Roger	register_match(&string);
1343071913784b69423fd25c3db2344e585872920ccEmmanuel Roger}
135