added new time match, added new ipv4options match

This commit is contained in:
Harald Welte
2001-03-25 19:25:41 +00:00
parent 18f1aff721
commit 5ea4bcb45a
5 changed files with 532 additions and 1 deletions
+3
View File
@@ -0,0 +1,3 @@
#!/bin/sh
# True if ipv4options is applied.
[ -f $KERNEL_DIR/include/linux/netfilter_ipv4/ipt_ipv4options.h ] && echo ipv4options
+3
View File
@@ -0,0 +1,3 @@
#!/bin/sh
# True if time is applied.
[ -f $KERNEL_DIR/include/linux/netfilter_ipv4/ipt_time.h ] && echo time
+1 -1
View File
@@ -1,6 +1,6 @@
#! /usr/bin/make
PF_EXT_SLIB:=tcp udp icmp mac limit standard REJECT LOG unclean state multiport tos TOS mark MARK owner SNAT DNAT MASQUERADE REDIRECT MIRROR
PF_EXT_SLIB:=tcp udp icmp mac limit standard REJECT LOG unclean state multiport tos TOS mark MARK owner SNAT DNAT MASQUERADE REDIRECT MIRROR SAME
PF6_EXT_SLIB:=tcp udp icmp standard MARK mark
# The following may not be present, but compile them anyway.
+238
View File
@@ -0,0 +1,238 @@
/* Shared library add-on to iptables to add ipv4 options matching support. */
#include <stdio.h>
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
#include <getopt.h>
#include <iptables.h>
#include <linux/netfilter_ipv4/ipt_ipv4options.h>
/* Function which prints out usage message. */
static void
help(void)
{
printf(
"IPV4OPTIONS v%s options:\n"
" --ssrr (match strict source routing flag)\n"
" --lsrr (match loose source routing flag)\n"
" --no-srr (match packets with no source routing)\n\n"
" [!] --rr (match record route flag)\n\n"
" [!] --ts (match timestamp flag)\n\n",
NETFILTER_VERSION);
}
static struct option opts[] = {
{ "ssrr", 0, 0, '1' },
{ "lsrr", 0, 0, '2' },
{ "no-srr", 0, 0, '3'},
{ "rr", 0, 0, '4'},
{ "ts", 0, 0, '5'},
{0}
};
/* Initialize the match. */
static void
init(struct ipt_entry_match *m, unsigned int *nfcache)
{
/* caching not yet implemented */
*nfcache |= NFC_UNKNOWN;
}
/* Function which parses command options; returns true if it
ate an option */
static int
parse(int c, char **argv, int invert, unsigned int *flags,
const struct ipt_entry *entry,
unsigned int *nfcache,
struct ipt_entry_match **match)
{
struct ipt_ipv4options_info *info = (struct ipt_ipv4options_info *)(*match)->data;
switch (c)
{
/* strict-source-routing */
case '1':
if (invert)
exit_error(PARAMETER_PROBLEM,
"ipv4options: unexpected `!' with --ssrr");
if (*flags & IPT_IPV4OPTION_MATCH_SSRR)
exit_error(PARAMETER_PROBLEM,
"Can't specify --ssrr twice");
if (*flags & IPT_IPV4OPTION_MATCH_LSRR)
exit_error(PARAMETER_PROBLEM,
"Can't specify --ssrr with --lsrr");
if (*flags & IPT_IPV4OPTION_DONT_MATCH_SRR)
exit_error(PARAMETER_PROBLEM,
"Can't specify --ssrr with --no-srr");
info->options |= IPT_IPV4OPTION_MATCH_SSRR;
*flags |= IPT_IPV4OPTION_MATCH_SSRR;
break;
/* loose-source-routing */
case '2':
if (invert)
exit_error(PARAMETER_PROBLEM,
"ipv4options: unexpected `!' with --lsrr");
if (*flags & IPT_IPV4OPTION_MATCH_SSRR)
exit_error(PARAMETER_PROBLEM,
"Can't specify --lsrr twice");
if (*flags & IPT_IPV4OPTION_MATCH_LSRR)
exit_error(PARAMETER_PROBLEM,
"Can't specify --lsrr with --ssrr");
if (*flags & IPT_IPV4OPTION_DONT_MATCH_SRR)
exit_error(PARAMETER_PROBLEM,
"Can't specify --lsrr with --no-srr");
info->options |= IPT_IPV4OPTION_MATCH_LSRR;
*flags |= IPT_IPV4OPTION_MATCH_LSRR;
break;
/* no-source-routing */
case '3':
if (invert)
exit_error(PARAMETER_PROBLEM,
"ipv4options: unexpected `!' with --no-srr");
if (*flags & IPT_IPV4OPTION_DONT_MATCH_SRR)
exit_error(PARAMETER_PROBLEM,
"Can't specify --no-srr twice");
if (*flags & IPT_IPV4OPTION_MATCH_SSRR)
exit_error(PARAMETER_PROBLEM,
"Can't specify --no-srr with --ssrr");
if (*flags & IPT_IPV4OPTION_MATCH_LSRR)
exit_error(PARAMETER_PROBLEM,
"Can't specify --no-srr with --lsrr");
info->options |= IPT_IPV4OPTION_DONT_MATCH_SRR;
*flags |= IPT_IPV4OPTION_DONT_MATCH_SRR;
break;
/* record-route */
case '4':
if ((!invert) && (*flags & IPT_IPV4OPTION_MATCH_RR))
exit_error(PARAMETER_PROBLEM,
"Can't specify --rr twice");
if (invert && (*flags & IPT_IPV4OPTION_DONT_MATCH_RR))
exit_error(PARAMETER_PROBLEM,
"Can't specify ! --rr twice");
if ((!invert) && (*flags & IPT_IPV4OPTION_DONT_MATCH_RR))
exit_error(PARAMETER_PROBLEM,
"Can't specify --rr with ! --rr");
if (invert && (*flags & IPT_IPV4OPTION_MATCH_RR))
exit_error(PARAMETER_PROBLEM,
"Can't specify ! --rr with --rr");
if (invert) {
info->options |= IPT_IPV4OPTION_DONT_MATCH_RR;
*flags |= IPT_IPV4OPTION_DONT_MATCH_RR;
}
else {
info->options |= IPT_IPV4OPTION_MATCH_RR;
*flags |= IPT_IPV4OPTION_MATCH_RR;
}
break;
/* timestamp */
case '5':
if ((!invert) && (*flags & IPT_IPV4OPTION_MATCH_TIMESTAMP))
exit_error(PARAMETER_PROBLEM,
"Can't specify --ts twice");
if (invert && (*flags & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP))
exit_error(PARAMETER_PROBLEM,
"Can't specify ! --ts twice");
if ((!invert) && (*flags & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP))
exit_error(PARAMETER_PROBLEM,
"Can't specify --ts with ! --ts");
if (invert && (*flags & IPT_IPV4OPTION_MATCH_TIMESTAMP))
exit_error(PARAMETER_PROBLEM,
"Can't specify ! --ts with --ts");
if (invert) {
info->options |= IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP;
*flags |= IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP;
}
else {
info->options |= IPT_IPV4OPTION_MATCH_TIMESTAMP;
*flags |= IPT_IPV4OPTION_MATCH_TIMESTAMP;
}
break;
default:
return 0;
}
return 1;
}
static void
final_check(unsigned int flags)
{
if (flags == 0)
exit_error(PARAMETER_PROBLEM,
"ipv4options match: you must specify some parameters. See iptables -m ipv4options --help for help.'");
}
/* Prints out the matchinfo. */
static void
print(const struct ipt_ip *ip,
const struct ipt_entry_match *match,
int numeric)
{
struct ipt_ipv4options_info *info = ((struct ipt_ipv4options_info *)match->data);
printf(" IPV4OPTS");
if (info->options & IPT_IPV4OPTION_MATCH_SSRR)
printf(" SSRR");
else if (info->options & IPT_IPV4OPTION_MATCH_LSRR)
printf(" LSRR");
else if (info->options & IPT_IPV4OPTION_DONT_MATCH_SRR)
printf(" !SRR");
if (info->options & IPT_IPV4OPTION_MATCH_RR)
printf(" RR");
else if (info->options & IPT_IPV4OPTION_DONT_MATCH_RR)
printf(" !RR");
if (info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP)
printf(" TS");
else if (info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP)
printf(" !TS");
printf(" ");
}
/* Saves the data in parsable form to stdout. */
static void
save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
{
struct ipt_ipv4options_info *info = ((struct ipt_ipv4options_info *)match->data);
if (info->options & IPT_IPV4OPTION_MATCH_SSRR)
printf(" --ssrr");
else if (info->options & IPT_IPV4OPTION_MATCH_LSRR)
printf(" --lsrr");
else if (info->options & IPT_IPV4OPTION_DONT_MATCH_SRR)
printf(" --no-srr");
if (info->options & IPT_IPV4OPTION_MATCH_RR)
printf(" --rr");
else if (info->options & IPT_IPV4OPTION_DONT_MATCH_RR)
printf(" ! --rr");
if (info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP)
printf(" --ts");
else if (info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP)
printf(" ! --ts");
printf(" ");
}
struct iptables_match ipv4options_struct
= { NULL,
"ipv4options",
NETFILTER_VERSION,
IPT_ALIGN(sizeof(struct ipt_ipv4options_info)),
IPT_ALIGN(sizeof(struct ipt_ipv4options_info)),
&help,
&init,
&parse,
&final_check,
&print,
&save,
opts
};
void _init(void)
{
register_match(&ipv4options_struct);
}
+287
View File
@@ -0,0 +1,287 @@
/* Shared library add-on to iptables to add TIME matching support. */
#include <stdio.h>
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
#include <getopt.h>
#include <iptables.h>
#include <linux/netfilter_ipv4/ipt_time.h>
#include <time.h>
/* Function which prints out usage message. */
static void
help(void)
{
printf(
"TIME v%s options:\n"
" --timestart value --timestop value --days listofdays\n"
" timestart value : HH:MM\n"
" timestop value : HH:MM\n"
" listofdays value: a list of days to apply -> ie. Mon,Tue,Wed,Thu,Fri. Case sensitive\n",
NETFILTER_VERSION);
}
static struct option opts[] = {
{ "timestart", 1, 0, '1' },
{ "timestop", 1, 0, '2' },
{ "days", 1, 0, '3'},
{0}
};
/* Initialize the match. */
static void
init(struct ipt_entry_match *m, unsigned int *nfcache)
{
/* caching not yet implemented */
*nfcache |= NFC_UNKNOWN;
}
/**
* param: part1, a pointer on a string 2 chars maximum long string, that will contain the hours.
* param: part2, a pointer on a string 2 chars maximum long string, that will contain the minutes.
* param: str_2_parse, the string to parse.
* return: 1 if ok, 0 if error.
*/
static int
split_time(char **part1, char **part2, const char *str_2_parse)
{
unsigned short int i,j;
char *rpart1 = *part1;
char *rpart2 = *part2;
/* Check the length of the string */
if (strlen(str_2_parse) > 5)
return 0;
/* parse the first part until the ':' */
for (i=0; i<2; i++)
{
if (str_2_parse[i] != ':') {
rpart1[i] = str_2_parse[i];
}
}
if (str_2_parse[i] != ':')
++i;
/* parse the second part */
j=++i;
for (i=j; i<5; i++)
{
rpart2[i-j] = str_2_parse[i];
}
/* if we are here, format should be ok. */
return 1;
}
static void
parse_time_string(int *hour, int *minute, const char *time)
{
char *hours;
char *minutes;
hours = (char *)malloc(3);
minutes = (char *)malloc(3);
bzero((void *)hours, 3);
bzero((void *)minutes, 3);
if (split_time(&hours, &minutes, time) == 1)
{
*hour = string_to_number(hours, 0, 23);
*minute = string_to_number(minutes, 0, 59);
}
if ((*hour != (-1)) && (*minute != (-1))) {
free(hours);
free(minutes);
return;
}
/* If we are here, there was a problem ..*/
exit_error(PARAMETER_PROBLEM,
"invalid time `%s' specified, should be HH:MM format", time);
}
/* return 1->ok, return 0->error */
static int
parse_day(int *days, int from, int to, const char *string)
{
char *dayread;
char *days_str[7] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
unsigned short int days_of_week[7] = {64, 32, 16, 8, 4, 2, 1};
unsigned int i;
dayread = (char *)malloc(4);
bzero(dayread, 4);
if ((to-from) != 3) {
free(dayread);
return 0;
}
for (i=from; i<to; i++)
dayread[i-from] = string[i];
for (i=0; i<7; i++)
if (strcmp(dayread, days_str[i]) == 0)
{
*days |= days_of_week[i];
free(dayread);
return 1;
}
/* if we are here, we didn't read a valid day */
free(dayread);
return 0;
}
static void
parse_days_string(int *days, const char *daystring)
{
int len;
int i=0;
char *err = "invalid days `%s' specified, should be Sun,Mon,Tue... format";
len = strlen(daystring);
if (len < 3)
exit_error(PARAMETER_PROBLEM, err, daystring);
while(i<len)
{
if (parse_day(days, i, i+3, daystring) == 0)
exit_error(PARAMETER_PROBLEM, err, daystring);
i += 4;
}
}
#define IPT_TIME_START 0x01
#define IPT_TIME_STOP 0x02
#define IPT_TIME_DAYS 0x04
/* Function which parses command options; returns true if it
ate an option */
static int
parse(int c, char **argv, int invert, unsigned int *flags,
const struct ipt_entry *entry,
unsigned int *nfcache,
struct ipt_entry_match **match)
{
struct ipt_time_info *timeinfo = (struct ipt_time_info *)(*match)->data;
int hours, minutes, days;
switch (c)
{
/* timestart */
case '1':
if (invert)
exit_error(PARAMETER_PROBLEM,
"unexpected '!' with --timestart");
if (*flags & IPT_TIME_START)
exit_error(PARAMETER_PROBLEM,
"Can't specify --timestart twice");
parse_time_string(&hours, &minutes, optarg);
timeinfo->hour_start = hours;
timeinfo->minute_start = minutes;
*flags |= IPT_TIME_START;
break;
/* timestop */
case '2':
if (invert)
exit_error(PARAMETER_PROBLEM,
"unexpected '!' with --timestop");
if (*flags & IPT_TIME_STOP)
exit_error(PARAMETER_PROBLEM,
"Can't specify --timestop twice");
parse_time_string(&hours, &minutes, optarg);
timeinfo->hour_stop = hours;
timeinfo->minute_stop = minutes;
*flags |= IPT_TIME_STOP;
break;
/* days */
case '3':
if (invert)
exit_error(PARAMETER_PROBLEM,
"unexpected '!' with --days");
if (*flags & IPT_TIME_DAYS)
exit_error(PARAMETER_PROBLEM,
"Can't specify --days twice");
parse_days_string(&days, optarg);
timeinfo->days_match = days;
*flags |= IPT_TIME_DAYS;
break;
default:
return 0;
}
return 1;
}
/* Final check; must have specified --time-start --time-stop --days. */
static void
final_check(unsigned int flags)
{
if (flags != (IPT_TIME_START | IPT_TIME_STOP | IPT_TIME_DAYS))
exit_error(PARAMETER_PROBLEM,
"TIME match: You must specify `--time-start --time-stop and --days'");
}
static void
print_days(int daynum)
{
char *days[7] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
unsigned short int days_of_week[7] = {64, 32, 16, 8, 4, 2, 1};
unsigned short int i, nbdays=0;
for (i=0; i<7; i++) {
if ((days_of_week[i] & daynum) == days_of_week[i])
{
if (nbdays>0)
printf(",%s", days[i]);
else
printf("%s", days[i]);
++nbdays;
}
}
}
/* Prints out the matchinfo. */
static void
print(const struct ipt_ip *ip,
const struct ipt_entry_match *match,
int numeric)
{
struct ipt_time_info *time = ((struct ipt_time_info *)match->data);
printf(" TIME from %d:%d to %d:%d on ",
time->hour_start, time->minute_start,
time->hour_stop, time->minute_stop);
print_days(time->days_match);
printf(" ");
}
/* Saves the data in parsable form to stdout. */
static void
save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
{
struct ipt_time_info *time = ((struct ipt_time_info *)match->data);
printf(" --timestart %.2d:%.2d --timestop %.2d:%.2d --days ",
time->hour_start, time->minute_start,
time->hour_stop, time->minute_stop);
print_days(time->days_match);
printf(" ");
}
struct iptables_match timestruct
= { NULL,
"time",
NETFILTER_VERSION,
IPT_ALIGN(sizeof(struct ipt_time_info)),
IPT_ALIGN(sizeof(struct ipt_time_info)),
&help,
&init,
&parse,
&final_check,
&print,
&save,
opts
};
void _init(void)
{
register_match(&timestruct);
}