Commit dab1e98e authored by Arturo Borrero Gonzalez's avatar Arturo Borrero Gonzalez
Browse files

New upstream version 1.8.1

parent f1f129da
ip6tables-translate -t filter -A INPUT -m icmp6 --icmpv6-type 1 -j LOG
nft add rule ip6 filter INPUT icmpv6 type destination-unreachable counter log
ip6tables-translate -t filter -A INPUT -m icmp6 --icmpv6-type neighbour-advertisement -j LOG
nft add rule ip6 filter INPUT icmpv6 type nd-neighbor-advert counter log
ip6tables-translate -t filter -A INPUT -m icmp6 ! --icmpv6-type packet-too-big -j LOG
nft add rule ip6 filter INPUT icmpv6 type != packet-too-big counter log
ip6tables-translate -A INPUT -p mh --mh-type 1 -j ACCEPT
nft add rule ip6 filter INPUT meta l4proto 135 mh type 1 counter accept
ip6tables-translate -A INPUT -p mh --mh-type 1:3 -j ACCEPT
nft add rule ip6 filter INPUT meta l4proto 135 mh type 1-3 counter accept
ip6tables-translate -A INPUT -m rt --rt-type 0 -j DROP
nft add rule ip6 filter INPUT rt type 0 counter drop
ip6tables-translate -A INPUT -m rt ! --rt-len 22 -j DROP
nft add rule ip6 filter INPUT rt hdrlength != 22 counter drop
ip6tables-translate -A INPUT -m rt --rt-segsleft 26 -j ACCEPT
nft add rule ip6 filter INPUT rt seg-left 26 counter accept
ip6tables-translate -A INPUT -m rt --rt-type 0 --rt-len 22 -j DROP
nft add rule ip6 filter INPUT rt type 0 rt hdrlength 22 counter drop
ip6tables-translate -A INPUT -m rt --rt-type 0 --rt-len 22 ! --rt-segsleft 26 -j ACCEPT
nft add rule ip6 filter INPUT rt type 0 rt seg-left != 26 rt hdrlength 22 counter accept
/* Shared library to add Segment Routing Header (SRH) matching support.
*
* Author:
* Ahmed Abdelsalam <amsalam20@gmail.com>
*/
#include <stdio.h>
#include <xtables.h>
#include <linux/netfilter_ipv6/ip6t_srh.h>
#include <string.h>
/* srh command-line options */
enum {
O_SRH_NEXTHDR,
O_SRH_LEN_EQ,
O_SRH_LEN_GT,
O_SRH_LEN_LT,
O_SRH_SEGS_EQ,
O_SRH_SEGS_GT,
O_SRH_SEGS_LT,
O_SRH_LAST_EQ,
O_SRH_LAST_GT,
O_SRH_LAST_LT,
O_SRH_TAG,
O_SRH_PSID,
O_SRH_NSID,
O_SRH_LSID,
};
static void srh_help(void)
{
printf(
"srh match options:\n"
"[!] --srh-next-hdr next-hdr Next Header value of SRH\n"
"[!] --srh-hdr-len-eq hdr_len Hdr Ext Len value of SRH\n"
"[!] --srh-hdr-len-gt hdr_len Hdr Ext Len value of SRH\n"
"[!] --srh-hdr-len-lt hdr_len Hdr Ext Len value of SRH\n"
"[!] --srh-segs-left-eq segs_left Segments Left value of SRH\n"
"[!] --srh-segs-left-gt segs_left Segments Left value of SRH\n"
"[!] --srh-segs-left-lt segs_left Segments Left value of SRH\n"
"[!] --srh-last-entry-eq last_entry Last Entry value of SRH\n"
"[!] --srh-last-entry-gt last_entry Last Entry value of SRH\n"
"[!] --srh-last-entry-lt last_entry Last Entry value of SRH\n"
"[!] --srh-tag tag Tag value of SRH\n"
"[!] --srh-psid addr[/mask] SRH previous SID\n"
"[!] --srh-nsid addr[/mask] SRH next SID\n"
"[!] --srh-lsid addr[/mask] SRH Last SID\n");
}
#define s struct ip6t_srh
static const struct xt_option_entry srh_opts[] = {
{ .name = "srh-next-hdr", .id = O_SRH_NEXTHDR, .type = XTTYPE_UINT8,
.flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, next_hdr)},
{ .name = "srh-hdr-len-eq", .id = O_SRH_LEN_EQ, .type = XTTYPE_UINT8,
.flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, hdr_len)},
{ .name = "srh-hdr-len-gt", .id = O_SRH_LEN_GT, .type = XTTYPE_UINT8,
.flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, hdr_len)},
{ .name = "srh-hdr-len-lt", .id = O_SRH_LEN_LT, .type = XTTYPE_UINT8,
.flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, hdr_len)},
{ .name = "srh-segs-left-eq", .id = O_SRH_SEGS_EQ, .type = XTTYPE_UINT8,
.flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, segs_left)},
{ .name = "srh-segs-left-gt", .id = O_SRH_SEGS_GT, .type = XTTYPE_UINT8,
.flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, segs_left)},
{ .name = "srh-segs-left-lt", .id = O_SRH_SEGS_LT, .type = XTTYPE_UINT8,
.flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, segs_left)},
{ .name = "srh-last-entry-eq", .id = O_SRH_LAST_EQ, .type = XTTYPE_UINT8,
.flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, last_entry)},
{ .name = "srh-last-entry-gt", .id = O_SRH_LAST_GT, .type = XTTYPE_UINT8,
.flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, last_entry)},
{ .name = "srh-last-entry-lt", .id = O_SRH_LAST_LT, .type = XTTYPE_UINT8,
.flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, last_entry)},
{ .name = "srh-tag", .id = O_SRH_TAG, .type = XTTYPE_UINT16,
.flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, tag)},
{ }
};
#undef s
#define s struct ip6t_srh1
static const struct xt_option_entry srh1_opts[] = {
{ .name = "srh-next-hdr", .id = O_SRH_NEXTHDR, .type = XTTYPE_UINT8,
.flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, next_hdr)},
{ .name = "srh-hdr-len-eq", .id = O_SRH_LEN_EQ, .type = XTTYPE_UINT8,
.flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, hdr_len)},
{ .name = "srh-hdr-len-gt", .id = O_SRH_LEN_GT, .type = XTTYPE_UINT8,
.flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, hdr_len)},
{ .name = "srh-hdr-len-lt", .id = O_SRH_LEN_LT, .type = XTTYPE_UINT8,
.flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, hdr_len)},
{ .name = "srh-segs-left-eq", .id = O_SRH_SEGS_EQ, .type = XTTYPE_UINT8,
.flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, segs_left)},
{ .name = "srh-segs-left-gt", .id = O_SRH_SEGS_GT, .type = XTTYPE_UINT8,
.flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, segs_left)},
{ .name = "srh-segs-left-lt", .id = O_SRH_SEGS_LT, .type = XTTYPE_UINT8,
.flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, segs_left)},
{ .name = "srh-last-entry-eq", .id = O_SRH_LAST_EQ, .type = XTTYPE_UINT8,
.flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, last_entry)},
{ .name = "srh-last-entry-gt", .id = O_SRH_LAST_GT, .type = XTTYPE_UINT8,
.flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, last_entry)},
{ .name = "srh-last-entry-lt", .id = O_SRH_LAST_LT, .type = XTTYPE_UINT8,
.flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, last_entry)},
{ .name = "srh-tag", .id = O_SRH_TAG, .type = XTTYPE_UINT16,
.flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, tag)},
{ .name = "srh-psid", .id = O_SRH_PSID, .type = XTTYPE_HOSTMASK,
.flags = XTOPT_INVERT},
{ .name = "srh-nsid", .id = O_SRH_NSID, .type = XTTYPE_HOSTMASK,
.flags = XTOPT_INVERT},
{ .name = "srh-lsid", .id = O_SRH_LSID, .type = XTTYPE_HOSTMASK,
.flags = XTOPT_INVERT},
{ }
};
#undef s
static void srh_init(struct xt_entry_match *m)
{
struct ip6t_srh *srhinfo = (void *)m->data;
srhinfo->mt_flags = 0;
srhinfo->mt_invflags = 0;
}
static void srh1_init(struct xt_entry_match *m)
{
struct ip6t_srh1 *srhinfo = (void *)m->data;
srhinfo->mt_flags = 0;
srhinfo->mt_invflags = 0;
memset(srhinfo->psid_addr.s6_addr, 0, sizeof(srhinfo->psid_addr.s6_addr));
memset(srhinfo->nsid_addr.s6_addr, 0, sizeof(srhinfo->nsid_addr.s6_addr));
memset(srhinfo->lsid_addr.s6_addr, 0, sizeof(srhinfo->lsid_addr.s6_addr));
memset(srhinfo->psid_msk.s6_addr, 0, sizeof(srhinfo->psid_msk.s6_addr));
memset(srhinfo->nsid_msk.s6_addr, 0, sizeof(srhinfo->nsid_msk.s6_addr));
memset(srhinfo->lsid_msk.s6_addr, 0, sizeof(srhinfo->lsid_msk.s6_addr));
}
static void srh_parse(struct xt_option_call *cb)
{
struct ip6t_srh *srhinfo = cb->data;
xtables_option_parse(cb);
switch (cb->entry->id) {
case O_SRH_NEXTHDR:
srhinfo->mt_flags |= IP6T_SRH_NEXTHDR;
if (cb->invert)
srhinfo->mt_invflags |= IP6T_SRH_INV_NEXTHDR;
break;
case O_SRH_LEN_EQ:
srhinfo->mt_flags |= IP6T_SRH_LEN_EQ;
if (cb->invert)
srhinfo->mt_invflags |= IP6T_SRH_INV_LEN_EQ;
break;
case O_SRH_LEN_GT:
srhinfo->mt_flags |= IP6T_SRH_LEN_GT;
if (cb->invert)
srhinfo->mt_invflags |= IP6T_SRH_INV_LEN_GT;
break;
case O_SRH_LEN_LT:
srhinfo->mt_flags |= IP6T_SRH_LEN_LT;
if (cb->invert)
srhinfo->mt_invflags |= IP6T_SRH_INV_LEN_LT;
break;
case O_SRH_SEGS_EQ:
srhinfo->mt_flags |= IP6T_SRH_SEGS_EQ;
if (cb->invert)
srhinfo->mt_invflags |= IP6T_SRH_INV_SEGS_EQ;
break;
case O_SRH_SEGS_GT:
srhinfo->mt_flags |= IP6T_SRH_SEGS_GT;
if (cb->invert)
srhinfo->mt_invflags |= IP6T_SRH_INV_SEGS_GT;
break;
case O_SRH_SEGS_LT:
srhinfo->mt_flags |= IP6T_SRH_SEGS_LT;
if (cb->invert)
srhinfo->mt_invflags |= IP6T_SRH_INV_SEGS_LT;
break;
case O_SRH_LAST_EQ:
srhinfo->mt_flags |= IP6T_SRH_LAST_EQ;
if (cb->invert)
srhinfo->mt_invflags |= IP6T_SRH_INV_LAST_EQ;
break;
case O_SRH_LAST_GT:
srhinfo->mt_flags |= IP6T_SRH_LAST_GT;
if (cb->invert)
srhinfo->mt_invflags |= IP6T_SRH_INV_LAST_GT;
break;
case O_SRH_LAST_LT:
srhinfo->mt_flags |= IP6T_SRH_LAST_LT;
if (cb->invert)
srhinfo->mt_invflags |= IP6T_SRH_INV_LAST_LT;
break;
case O_SRH_TAG:
srhinfo->mt_flags |= IP6T_SRH_TAG;
if (cb->invert)
srhinfo->mt_invflags |= IP6T_SRH_INV_TAG;
break;
}
}
static void srh1_parse(struct xt_option_call *cb)
{
struct ip6t_srh1 *srhinfo = cb->data;
xtables_option_parse(cb);
switch (cb->entry->id) {
case O_SRH_NEXTHDR:
srhinfo->mt_flags |= IP6T_SRH_NEXTHDR;
if (cb->invert)
srhinfo->mt_invflags |= IP6T_SRH_INV_NEXTHDR;
break;
case O_SRH_LEN_EQ:
srhinfo->mt_flags |= IP6T_SRH_LEN_EQ;
if (cb->invert)
srhinfo->mt_invflags |= IP6T_SRH_INV_LEN_EQ;
break;
case O_SRH_LEN_GT:
srhinfo->mt_flags |= IP6T_SRH_LEN_GT;
if (cb->invert)
srhinfo->mt_invflags |= IP6T_SRH_INV_LEN_GT;
break;
case O_SRH_LEN_LT:
srhinfo->mt_flags |= IP6T_SRH_LEN_LT;
if (cb->invert)
srhinfo->mt_invflags |= IP6T_SRH_INV_LEN_LT;
break;
case O_SRH_SEGS_EQ:
srhinfo->mt_flags |= IP6T_SRH_SEGS_EQ;
if (cb->invert)
srhinfo->mt_invflags |= IP6T_SRH_INV_SEGS_EQ;
break;
case O_SRH_SEGS_GT:
srhinfo->mt_flags |= IP6T_SRH_SEGS_GT;
if (cb->invert)
srhinfo->mt_invflags |= IP6T_SRH_INV_SEGS_GT;
break;
case O_SRH_SEGS_LT:
srhinfo->mt_flags |= IP6T_SRH_SEGS_LT;
if (cb->invert)
srhinfo->mt_invflags |= IP6T_SRH_INV_SEGS_LT;
break;
case O_SRH_LAST_EQ:
srhinfo->mt_flags |= IP6T_SRH_LAST_EQ;
if (cb->invert)
srhinfo->mt_invflags |= IP6T_SRH_INV_LAST_EQ;
break;
case O_SRH_LAST_GT:
srhinfo->mt_flags |= IP6T_SRH_LAST_GT;
if (cb->invert)
srhinfo->mt_invflags |= IP6T_SRH_INV_LAST_GT;
break;
case O_SRH_LAST_LT:
srhinfo->mt_flags |= IP6T_SRH_LAST_LT;
if (cb->invert)
srhinfo->mt_invflags |= IP6T_SRH_INV_LAST_LT;
break;
case O_SRH_TAG:
srhinfo->mt_flags |= IP6T_SRH_TAG;
if (cb->invert)
srhinfo->mt_invflags |= IP6T_SRH_INV_TAG;
break;
case O_SRH_PSID:
srhinfo->mt_flags |= IP6T_SRH_PSID;
srhinfo->psid_addr = cb->val.haddr.in6;
srhinfo->psid_msk = cb->val.hmask.in6;
if (cb->invert)
srhinfo->mt_invflags |= IP6T_SRH_INV_PSID;
break;
case O_SRH_NSID:
srhinfo->mt_flags |= IP6T_SRH_NSID;
srhinfo->nsid_addr = cb->val.haddr.in6;
srhinfo->nsid_msk = cb->val.hmask.in6;
if (cb->invert)
srhinfo->mt_invflags |= IP6T_SRH_INV_NSID;
break;
case O_SRH_LSID:
srhinfo->mt_flags |= IP6T_SRH_LSID;
srhinfo->lsid_addr = cb->val.haddr.in6;
srhinfo->lsid_msk = cb->val.hmask.in6;
if (cb->invert)
srhinfo->mt_invflags |= IP6T_SRH_INV_LSID;
break;
}
}
static void srh_print(const void *ip, const struct xt_entry_match *match,
int numeric)
{
const struct ip6t_srh *srhinfo = (struct ip6t_srh *)match->data;
printf(" srh");
if (srhinfo->mt_flags & IP6T_SRH_NEXTHDR)
printf(" next-hdr:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_NEXTHDR ? "!" : "",
srhinfo->next_hdr);
if (srhinfo->mt_flags & IP6T_SRH_LEN_EQ)
printf(" hdr-len-eq:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_LEN_EQ ? "!" : "",
srhinfo->hdr_len);
if (srhinfo->mt_flags & IP6T_SRH_LEN_GT)
printf(" hdr-len-gt:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_LEN_GT ? "!" : "",
srhinfo->hdr_len);
if (srhinfo->mt_flags & IP6T_SRH_LEN_LT)
printf(" hdr-len-lt:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_LEN_LT ? "!" : "",
srhinfo->hdr_len);
if (srhinfo->mt_flags & IP6T_SRH_SEGS_EQ)
printf(" segs-left-eq:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_SEGS_EQ ? "!" : "",
srhinfo->segs_left);
if (srhinfo->mt_flags & IP6T_SRH_SEGS_GT)
printf(" segs-left-gt:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_SEGS_GT ? "!" : "",
srhinfo->segs_left);
if (srhinfo->mt_flags & IP6T_SRH_SEGS_LT)
printf(" segs-left-lt:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_SEGS_LT ? "!" : "",
srhinfo->segs_left);
if (srhinfo->mt_flags & IP6T_SRH_LAST_EQ)
printf(" last-entry-eq:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_LAST_EQ ? "!" : "",
srhinfo->last_entry);
if (srhinfo->mt_flags & IP6T_SRH_LAST_GT)
printf(" last-entry-gt:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_LAST_GT ? "!" : "",
srhinfo->last_entry);
if (srhinfo->mt_flags & IP6T_SRH_LAST_LT)
printf(" last-entry-lt:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_LAST_LT ? "!" : "",
srhinfo->last_entry);
if (srhinfo->mt_flags & IP6T_SRH_TAG)
printf(" tag:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_TAG ? "!" : "",
srhinfo->tag);
}
static void srh1_print(const void *ip, const struct xt_entry_match *match, int numeric)
{
const struct ip6t_srh1 *srhinfo = (struct ip6t_srh1 *)match->data;
printf(" srh");
if (srhinfo->mt_flags & IP6T_SRH_NEXTHDR)
printf(" next-hdr:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_NEXTHDR ? "!" : "",
srhinfo->next_hdr);
if (srhinfo->mt_flags & IP6T_SRH_LEN_EQ)
printf(" hdr-len-eq:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_LEN_EQ ? "!" : "",
srhinfo->hdr_len);
if (srhinfo->mt_flags & IP6T_SRH_LEN_GT)
printf(" hdr-len-gt:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_LEN_GT ? "!" : "",
srhinfo->hdr_len);
if (srhinfo->mt_flags & IP6T_SRH_LEN_LT)
printf(" hdr-len-lt:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_LEN_LT ? "!" : "",
srhinfo->hdr_len);
if (srhinfo->mt_flags & IP6T_SRH_SEGS_EQ)
printf(" segs-left-eq:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_SEGS_EQ ? "!" : "",
srhinfo->segs_left);
if (srhinfo->mt_flags & IP6T_SRH_SEGS_GT)
printf(" segs-left-gt:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_SEGS_GT ? "!" : "",
srhinfo->segs_left);
if (srhinfo->mt_flags & IP6T_SRH_SEGS_LT)
printf(" segs-left-lt:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_SEGS_LT ? "!" : "",
srhinfo->segs_left);
if (srhinfo->mt_flags & IP6T_SRH_LAST_EQ)
printf(" last-entry-eq:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_LAST_EQ ? "!" : "",
srhinfo->last_entry);
if (srhinfo->mt_flags & IP6T_SRH_LAST_GT)
printf(" last-entry-gt:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_LAST_GT ? "!" : "",
srhinfo->last_entry);
if (srhinfo->mt_flags & IP6T_SRH_LAST_LT)
printf(" last-entry-lt:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_LAST_LT ? "!" : "",
srhinfo->last_entry);
if (srhinfo->mt_flags & IP6T_SRH_TAG)
printf(" tag:%s%d", srhinfo->mt_invflags & IP6T_SRH_INV_TAG ? "!" : "",
srhinfo->tag);
if (srhinfo->mt_flags & IP6T_SRH_PSID)
printf(" psid %s %s/%u", srhinfo->mt_invflags & IP6T_SRH_INV_PSID ? "!" : "",
xtables_ip6addr_to_numeric(&srhinfo->psid_addr),
xtables_ip6mask_to_cidr(&srhinfo->psid_msk));
if (srhinfo->mt_flags & IP6T_SRH_NSID)
printf(" nsid %s %s/%u", srhinfo->mt_invflags & IP6T_SRH_INV_NSID ? "!" : "",
xtables_ip6addr_to_numeric(&srhinfo->nsid_addr),
xtables_ip6mask_to_cidr(&srhinfo->nsid_msk));
if (srhinfo->mt_flags & IP6T_SRH_LSID)
printf(" lsid %s %s/%u", srhinfo->mt_invflags & IP6T_SRH_INV_LSID ? "!" : "",
xtables_ip6addr_to_numeric(&srhinfo->lsid_addr),
xtables_ip6mask_to_cidr(&srhinfo->lsid_msk));
}
static void srh_save(const void *ip, const struct xt_entry_match *match)
{
const struct ip6t_srh *srhinfo = (struct ip6t_srh *)match->data;
if (srhinfo->mt_flags & IP6T_SRH_NEXTHDR)
printf("%s --srh-next-hdr %u", (srhinfo->mt_invflags & IP6T_SRH_INV_NEXTHDR) ? " !" : "",
srhinfo->next_hdr);
if (srhinfo->mt_flags & IP6T_SRH_LEN_EQ)
printf("%s --srh-hdr-len-eq %u", (srhinfo->mt_invflags & IP6T_SRH_INV_LEN_EQ) ? " !" : "",
srhinfo->hdr_len);
if (srhinfo->mt_flags & IP6T_SRH_LEN_GT)
printf("%s --srh-hdr-len-gt %u", (srhinfo->mt_invflags & IP6T_SRH_INV_LEN_GT) ? " !" : "",
srhinfo->hdr_len);
if (srhinfo->mt_flags & IP6T_SRH_LEN_LT)
printf("%s --srh-hdr-len-lt %u", (srhinfo->mt_invflags & IP6T_SRH_INV_LEN_LT) ? " !" : "",
srhinfo->hdr_len);
if (srhinfo->mt_flags & IP6T_SRH_SEGS_EQ)
printf("%s --srh-segs-left-eq %u", (srhinfo->mt_invflags & IP6T_SRH_INV_SEGS_EQ) ? " !" : "",
srhinfo->segs_left);
if (srhinfo->mt_flags & IP6T_SRH_SEGS_GT)
printf("%s --srh-segs-left-gt %u", (srhinfo->mt_invflags & IP6T_SRH_INV_SEGS_GT) ? " !" : "",
srhinfo->segs_left);
if (srhinfo->mt_flags & IP6T_SRH_SEGS_LT)
printf("%s --srh-segs-left-lt %u", (srhinfo->mt_invflags & IP6T_SRH_INV_SEGS_LT) ? " !" : "",
srhinfo->segs_left);
if (srhinfo->mt_flags & IP6T_SRH_LAST_EQ)
printf("%s --srh-last-entry-eq %u", (srhinfo->mt_invflags & IP6T_SRH_INV_LAST_EQ) ? " !" : "",
srhinfo->last_entry);
if (srhinfo->mt_flags & IP6T_SRH_LAST_GT)
printf("%s --srh-last-entry-gt %u", (srhinfo->mt_invflags & IP6T_SRH_INV_LAST_GT) ? " !" : "",
srhinfo->last_entry);
if (srhinfo->mt_flags & IP6T_SRH_LAST_LT)
printf("%s --srh-last-entry-lt %u", (srhinfo->mt_invflags & IP6T_SRH_INV_LAST_LT) ? " !" : "",
srhinfo->last_entry);
if (srhinfo->mt_flags & IP6T_SRH_TAG)
printf("%s --srh-tag %u", (srhinfo->mt_invflags & IP6T_SRH_INV_TAG) ? " !" : "",
srhinfo->tag);
}
static void srh1_save(const void *ip, const struct xt_entry_match *match)
{
const struct ip6t_srh1 *srhinfo = (struct ip6t_srh1 *)match->data;
if (srhinfo->mt_flags & IP6T_SRH_NEXTHDR)
printf("%s --srh-next-hdr %u", (srhinfo->mt_invflags & IP6T_SRH_INV_NEXTHDR) ? " !" : "",
srhinfo->next_hdr);
if (srhinfo->mt_flags & IP6T_SRH_LEN_EQ)
printf("%s --srh-hdr-len-eq %u", (srhinfo->mt_invflags & IP6T_SRH_INV_LEN_EQ) ? " !" : "",
srhinfo->hdr_len);
if (srhinfo->mt_flags & IP6T_SRH_LEN_GT)
printf("%s --srh-hdr-len-gt %u", (srhinfo->mt_invflags & IP6T_SRH_INV_LEN_GT) ? " !" : "",
srhinfo->hdr_len);
if (srhinfo->mt_flags & IP6T_SRH_LEN_LT)
printf("%s --srh-hdr-len-lt %u", (srhinfo->mt_invflags & IP6T_SRH_INV_LEN_LT) ? " !" : "",
srhinfo->hdr_len);
if (srhinfo->mt_flags & IP6T_SRH_SEGS_EQ)
printf("%s --srh-segs-left-eq %u", (srhinfo->mt_invflags & IP6T_SRH_INV_SEGS_EQ) ? " !" : "",
srhinfo->segs_left);
if (srhinfo->mt_flags & IP6T_SRH_SEGS_GT)
printf("%s --srh-segs-left-gt %u", (srhinfo->mt_invflags & IP6T_SRH_INV_SEGS_GT) ? " !" : "",
srhinfo->segs_left);
if (srhinfo->mt_flags & IP6T_SRH_SEGS_LT)
printf("%s --srh-segs-left-lt %u", (srhinfo->mt_invflags & IP6T_SRH_INV_SEGS_LT) ? " !" : "",
srhinfo->segs_left);
if (srhinfo->mt_flags & IP6T_SRH_LAST_EQ)
printf("%s --srh-last-entry-eq %u", (srhinfo->mt_invflags & IP6T_SRH_INV_LAST_EQ) ? " !" : "",
srhinfo->last_entry);
if (srhinfo->mt_flags & IP6T_SRH_LAST_GT)
printf("%s --srh-last-entry-gt %u", (srhinfo->mt_invflags & IP6T_SRH_INV_LAST_GT) ? " !" : "",
srhinfo->last_entry);
if (srhinfo->mt_flags & IP6T_SRH_LAST_LT)
printf("%s --srh-last-entry-lt %u", (srhinfo->mt_invflags & IP6T_SRH_INV_LAST_LT) ? " !" : "",
srhinfo->last_entry);
if (srhinfo->mt_flags & IP6T_SRH_TAG)
printf("%s --srh-tag %u", (srhinfo->mt_invflags & IP6T_SRH_INV_TAG) ? " !" : "",
srhinfo->tag);
if (srhinfo->mt_flags & IP6T_SRH_PSID)
printf("%s --srh-psid %s/%u", srhinfo->mt_invflags & IP6T_SRH_INV_PSID ? " !" : "",
xtables_ip6addr_to_numeric(&srhinfo->psid_addr),
xtables_ip6mask_to_cidr(&srhinfo->psid_msk));
if (srhinfo->mt_flags & IP6T_SRH_NSID)
printf("%s --srh-nsid %s/%u", srhinfo->mt_invflags & IP6T_SRH_INV_NSID ? " !" : "",
xtables_ip6addr_to_numeric(&srhinfo->nsid_addr),
xtables_ip6mask_to_cidr(&srhinfo->nsid_msk));
if (srhinfo->mt_flags & IP6T_SRH_LSID)
printf("%s --srh-lsid %s/%u", srhinfo->mt_invflags & IP6T_SRH_INV_LSID ? " !" : "",
xtables_ip6addr_to_numeric(&srhinfo->lsid_addr),
xtables_ip6mask_to_cidr(&srhinfo->lsid_msk));
}
static struct xtables_match srh_mt6_reg[] = {
{
.name = "srh",
.version = XTABLES_VERSION,
.revision = 0,
.family = NFPROTO_IPV6,
.size = XT_ALIGN(sizeof(struct ip6t_srh)),
.userspacesize = XT_ALIGN(sizeof(struct ip6t_srh)),
.help = srh_help,
.init = srh_init,
.print = srh_print,
.save = srh_save,
.x6_parse = srh_parse,
.x6_options = srh_opts,
},
{
.name = "srh",
.version = XTABLES_VERSION,
.revision = 1,
.family = NFPROTO_IPV6,
.size = XT_ALIGN(sizeof(struct ip6t_srh1)),
.userspacesize = XT_ALIGN(sizeof(struct ip6t_srh1)),
.help = srh_help,
.init = srh1_init,
.print = srh1_print,
.save = srh1_save,
.x6_parse = srh1_parse,
.x6_options = srh1_opts,
}
};
void
_init(void)
{
xtables_register_matches(srh_mt6_reg, ARRAY_SIZE(srh_mt6_reg));
}
......@@ -35,6 +35,15 @@ static void DNAT_help(void)
"[--random] [--persistent]\n");
}
static void DNAT_help_v2(void)
{
printf(
"DNAT target options:\n"
" --to-destination [<ipaddr>[-<ipaddr>]][:port[-port[/port]]]\n"
" Address to map destination to.\n"
"[--random] [--persistent]\n");
}
static const struct xt_option_entry DNAT_opts[] = {
{.name = "to-destination", .id = O_TO_DEST, .type = XTTYPE_STRING,
.flags = XTOPT_MAND | XTOPT_MULTI},
......@@ -287,22 +296,260 @@ static int DNAT_xlate(struct xt_xlate *xl,
return 1;
}
static struct xtables_target dnat_tg_reg = {
static void
parse_to_v2(const char *orig_arg, int portok, struct nf_nat_range2 *range)
{
char *arg, *colon, *dash, *error;
const struct in_addr *ip;
arg = strdup(orig_arg);
if (arg == NULL)
xtables_error(RESOURCE_PROBLEM, "strdup");
colon = strchr(arg, ':');
if (colon) {
int port;
if (!portok)
xtables_error(PARAMETER_PROBLEM,
"Need TCP, UDP, SCTP or DCCP with port specification");
range->flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
port = atoi(colon+1);
if (port <= 0 || port > 65535)
xtables_error(PARAMETER_PROBLEM,
"Port `%s' not valid\n", colon+1);
error = strchr(colon+1, ':');
if (error)
xtables_error(PARAMETER_PROBLEM,
"Invalid port:port syntax - use dash\n");
dash = strchr(colon, '-');
if (!dash) {
range->min_proto.tcp.port
= range->max_proto.tcp.port
= htons(port);
} else {
int maxport;
char *slash;
maxport = atoi(dash + 1);
if (maxport <= 0 || maxport > 65535)
xtables_error(PARAMETER_PROBLEM,
"Port `%s' not valid\n", dash+1);
if (maxport < port)
/* People are stupid. */
xtables_error(PARAMETER_PROBLEM,
"Port range `%s' funky\n", colon+1);
range->min_proto.tcp.port = htons(port);
range->max_proto.tcp.port = htons(maxport);
slash = strchr(dash, '/');
if (slash) {
int baseport;
baseport = atoi(slash + 1);
if (baseport <= 0 || baseport > 65535)
xtables_error(PARAMETER_PROBLEM,
"Port `%s' not valid\n", slash+1);
range->flags |= NF_NAT_RANGE_PROTO_OFFSET;
range->base_proto.tcp.port = htons(baseport);
}
}
/* Starts with a colon? No IP info...*/
if (colon == arg) {
free(arg);
return;
}
*colon = '\0';
}
range->flags |= NF_NAT_RANGE_MAP_IPS;
dash = strchr(arg, '-');
if (colon && dash && dash > colon)
dash = NULL;
if (dash)
*dash = '\0';
ip = xtables_numeric_to_ipaddr(arg);
if (!ip)
xtables_error(PARAMETER_PROBLEM, "Bad IP address \"%s\"\n",
arg);
range->min_addr.in = *ip;
if (dash) {
ip = xtables_numeric_to_ipaddr(dash+1);
if (!ip)
xtables_error(PARAMETER_PROBLEM, "Bad IP address \"%s\"\n",
dash+1);
range->max_addr.in = *ip;
} else
range->max_addr = range->min_addr;
free(arg);
return;
}
static void DNAT_parse_v2(struct xt_option_call *cb)
{
const struct ipt_entry *entry = cb->xt_entry;
struct nf_nat_range2 *range = cb->data;
int portok;
if (entry->ip.proto == IPPROTO_TCP
|| entry->ip.proto == IPPROTO_UDP
|| entry->ip.proto == IPPROTO_SCTP
|| entry->ip.proto == IPPROTO_DCCP
|| entry->ip.proto == IPPROTO_ICMP)
portok = 1;
else
portok = 0;
xtables_option_parse(cb);
switch (cb->entry->id) {
case O_TO_DEST:
if (cb->xflags & F_X_TO_DEST) {
xtables_error(PARAMETER_PROBLEM,
"DNAT: Multiple --to-destination not supported");
}
parse_to_v2(cb->arg, portok, range);
cb->xflags |= F_X_TO_DEST;
break;
case O_PERSISTENT:
range->flags |= NF_NAT_RANGE_PERSISTENT;
break;
}
}
static void DNAT_fcheck_v2(struct xt_fcheck_call *cb)
{
static const unsigned int f = F_TO_DEST | F_RANDOM;
struct nf_nat_range2 *range = cb->data;
if ((cb->xflags & f) == f)
range->flags |= NF_NAT_RANGE_PROTO_RANDOM;
}
static void print_range_v2(const struct nf_nat_range2 *range)
{
if (range->flags & NF_NAT_RANGE_MAP_IPS) {
printf("%s", xtables_ipaddr_to_numeric(&range->min_addr.in));
if (memcmp(&range->min_addr, &range->max_addr,
sizeof(range->min_addr)))
printf("-%s", xtables_ipaddr_to_numeric(&range->max_addr.in));
}
if (range->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
printf(":");
printf("%hu", ntohs(range->min_proto.tcp.port));
if (range->max_proto.tcp.port != range->min_proto.tcp.port)
printf("-%hu", ntohs(range->max_proto.tcp.port));
if (range->flags & NF_NAT_RANGE_PROTO_OFFSET)
printf("/%hu", ntohs(range->base_proto.tcp.port));
}
}
static void DNAT_print_v2(const void *ip, const struct xt_entry_target *target,
int numeric)
{
const struct nf_nat_range2 *range = (const void *)target->data;
printf(" to:");
print_range_v2(range);
if (range->flags & NF_NAT_RANGE_PROTO_RANDOM)
printf(" random");
if (range->flags & NF_NAT_RANGE_PERSISTENT)
printf(" persistent");
}
static void DNAT_save_v2(const void *ip, const struct xt_entry_target *target)
{
const struct nf_nat_range2 *range = (const void *)target->data;
printf(" --to-destination ");
print_range_v2(range);
if (range->flags & NF_NAT_RANGE_PROTO_RANDOM)
printf(" --random");
if (range->flags & NF_NAT_RANGE_PERSISTENT)
printf(" --persistent");
}
static void print_range_xlate_v2(const struct nf_nat_range2 *range,
struct xt_xlate *xl)
{
if (range->flags & NF_NAT_RANGE_MAP_IPS) {
xt_xlate_add(xl, "%s", xtables_ipaddr_to_numeric(&range->min_addr.in));
if (memcmp(&range->min_addr, &range->max_addr,
sizeof(range->min_addr))) {
xt_xlate_add(xl, "-%s", xtables_ipaddr_to_numeric(&range->max_addr.in));
}
}
if (range->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
xt_xlate_add(xl, ":%hu", ntohs(range->min_proto.tcp.port));
if (range->max_proto.tcp.port != range->min_proto.tcp.port)
xt_xlate_add(xl, "-%hu", ntohs(range->max_proto.tcp.port));
if (range->flags & NF_NAT_RANGE_PROTO_OFFSET)
xt_xlate_add(xl, ";%hu", ntohs(range->base_proto.tcp.port));
}
}
static int DNAT_xlate_v2(struct xt_xlate *xl,
const struct xt_xlate_tg_params *params)
{
const struct nf_nat_range2 *range = (const void *)params->target->data;
bool sep_need = false;
const char *sep = " ";
xt_xlate_add(xl, "dnat to ");
print_range_xlate_v2(range, xl);
if (range->flags & NF_NAT_RANGE_PROTO_RANDOM) {
xt_xlate_add(xl, " random");
sep_need = true;
}
if (range->flags & NF_NAT_RANGE_PERSISTENT) {
if (sep_need)
sep = ",";
xt_xlate_add(xl, "%spersistent", sep);
}
return 1;
}
static struct xtables_target dnat_tg_reg[] = {
{
.name = "DNAT",
.version = XTABLES_VERSION,
.family = NFPROTO_IPV4,
.revision = 0,
.size = XT_ALIGN(sizeof(struct nf_nat_ipv4_multi_range_compat)),
.userspacesize = XT_ALIGN(sizeof(struct nf_nat_ipv4_multi_range_compat)),
.help = DNAT_help,
.x6_parse = DNAT_parse,
.x6_fcheck = DNAT_fcheck,
.print = DNAT_print,
.save = DNAT_save,
.x6_parse = DNAT_parse,
.x6_fcheck = DNAT_fcheck,
.x6_options = DNAT_opts,
.xlate = DNAT_xlate,
},
{
.name = "DNAT",
.version = XTABLES_VERSION,
.family = NFPROTO_IPV4,
.revision = 2,
.size = XT_ALIGN(sizeof(struct nf_nat_range2)),
.userspacesize = XT_ALIGN(sizeof(struct nf_nat_range2)),
.help = DNAT_help_v2,
.print = DNAT_print_v2,
.save = DNAT_save_v2,
.x6_parse = DNAT_parse_v2,
.x6_fcheck = DNAT_fcheck_v2,
.x6_options = DNAT_opts,
.xlate = DNAT_xlate_v2,
},
};
void _init(void)
{
xtables_register_target(&dnat_tg_reg);
xtables_register_targets(dnat_tg_reg, ARRAY_SIZE(dnat_tg_reg));
}
iptables-translate -t nat -A prerouting -p tcp -o eth0 -j DNAT --to-destination 1.2.3.4
nft add rule ip nat prerouting oifname "eth0" ip protocol tcp counter dnat to 1.2.3.4
iptables-translate -t nat -A prerouting -p tcp -d 15.45.23.67 --dport 80 -j DNAT --to-destination 192.168.1.1-192.168.1.10
nft add rule ip nat prerouting ip daddr 15.45.23.67 tcp dport 80 counter dnat to 192.168.1.1-192.168.1.10
iptables-translate -t nat -A prerouting -p tcp -o eth0 -j DNAT --to-destination 1.2.3.4:1-1023
nft add rule ip nat prerouting oifname "eth0" ip protocol tcp counter dnat to 1.2.3.4:1-1023
iptables-translate -t nat -A prerouting -p tcp -o eth0 -j DNAT --to-destination 1.2.3.4 --random
nft add rule ip nat prerouting oifname "eth0" ip protocol tcp counter dnat to 1.2.3.4 random
iptables-translate -t nat -A prerouting -p tcp -o eth0 -j DNAT --to-destination 1.2.3.4 --random --persistent
nft add rule ip nat prerouting oifname "eth0" ip protocol tcp counter dnat to 1.2.3.4 random,persistent
iptables-translate -A FORWARD -p tcp -j LOG --log-level error
nft add rule ip filter FORWARD ip protocol tcp counter log level err
iptables-translate -A FORWARD -p tcp -j LOG --log-prefix "Random prefix"
nft add rule ip filter FORWARD ip protocol tcp counter log prefix \"Random prefix\"
......@@ -11,6 +11,7 @@
enum {
O_TO_PORTS = 0,
O_RANDOM,
O_RANDOM_FULLY,
};
static void MASQUERADE_help(void)
......@@ -20,12 +21,15 @@ static void MASQUERADE_help(void)
" --to-ports <port>[-<port>]\n"
" Port (range) to map to.\n"
" --random\n"
" Randomize source port.\n");
" Randomize source port.\n"
" --random-fully\n"
" Fully randomize source port.\n");
}
static const struct xt_option_entry MASQUERADE_opts[] = {
{.name = "to-ports", .id = O_TO_PORTS, .type = XTTYPE_STRING},
{.name = "random", .id = O_RANDOM, .type = XTTYPE_NONE},
{.name = "random-fully", .id = O_RANDOM_FULLY, .type = XTTYPE_NONE},
XTOPT_TABLEEND,
};
......@@ -97,6 +101,9 @@ static void MASQUERADE_parse(struct xt_option_call *cb)
case O_RANDOM:
mr->range[0].flags |= NF_NAT_RANGE_PROTO_RANDOM;
break;
case O_RANDOM_FULLY:
mr->range[0].flags |= NF_NAT_RANGE_PROTO_RANDOM_FULLY;
break;
}
}
......@@ -116,6 +123,9 @@ MASQUERADE_print(const void *ip, const struct xt_entry_target *target,
if (r->flags & NF_NAT_RANGE_PROTO_RANDOM)
printf(" random");
if (r->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY)
printf(" random-fully");
}
static void
......@@ -132,6 +142,9 @@ MASQUERADE_save(const void *ip, const struct xt_entry_target *target)
if (r->flags & NF_NAT_RANGE_PROTO_RANDOM)
printf(" --random");
if (r->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY)
printf(" --random-fully");
}
static int MASQUERADE_xlate(struct xt_xlate *xl,
......
iptables-translate -t nat -A POSTROUTING -j MASQUERADE
nft add rule ip nat POSTROUTING counter masquerade
iptables-translate -t nat -A POSTROUTING -p tcp -j MASQUERADE --to-ports 10
nft add rule ip nat POSTROUTING ip protocol tcp counter masquerade to :10
iptables-translate -t nat -A POSTROUTING -p tcp -j MASQUERADE --to-ports 10-20 --random
nft add rule ip nat POSTROUTING ip protocol tcp counter masquerade to :10-20 random
iptables-translate -t nat -A prerouting -p tcp --dport 80 -j REDIRECT --to-ports 8080
nft add rule ip nat prerouting tcp dport 80 counter redirect to :8080
iptables-translate -t nat -A prerouting -p tcp --dport 80 -j REDIRECT --to-ports 8080 --random
nft add rule ip nat prerouting tcp dport 80 counter redirect to :8080 random
......@@ -20,13 +20,8 @@
struct reject_names {
const char *name;
const char *alias;
enum ipt_reject_with with;
const char *desc;
};
struct reject_names_xlate {
const char *name;
enum ipt_reject_with with;
const char *xlate;
};
enum {
......@@ -34,26 +29,53 @@ enum {
};
static const struct reject_names reject_table[] = {
{"icmp-net-unreachable", "net-unreach",
IPT_ICMP_NET_UNREACHABLE, "ICMP network unreachable"},
{"icmp-host-unreachable", "host-unreach",
IPT_ICMP_HOST_UNREACHABLE, "ICMP host unreachable"},
{"icmp-proto-unreachable", "proto-unreach",
IPT_ICMP_PROT_UNREACHABLE, "ICMP protocol unreachable"},
{"icmp-port-unreachable", "port-unreach",
IPT_ICMP_PORT_UNREACHABLE, "ICMP port unreachable (default)"},
[IPT_ICMP_NET_UNREACHABLE] = {
"icmp-net-unreachable", "net-unreach",
"ICMP network unreachable",
"net-unreachable",
},
[IPT_ICMP_HOST_UNREACHABLE] = {
"icmp-host-unreachable", "host-unreach",
"ICMP host unreachable",
"host-unreachable",
},
[IPT_ICMP_PROT_UNREACHABLE] = {
"icmp-proto-unreachable", "proto-unreach",
"ICMP protocol unreachable",
"prot-unreachable",
},
[IPT_ICMP_PORT_UNREACHABLE] = {
"icmp-port-unreachable", "port-unreach",
"ICMP port unreachable (default)",
"port-unreachable",
},
#if 0
{"echo-reply", "echoreply",
IPT_ICMP_ECHOREPLY, "for ICMP echo only: faked ICMP echo reply"},
[IPT_ICMP_ECHOREPLY] = {
"echo-reply", "echoreply",
"for ICMP echo only: faked ICMP echo reply",
"echo-reply",
},
#endif
{"icmp-net-prohibited", "net-prohib",
IPT_ICMP_NET_PROHIBITED, "ICMP network prohibited"},
{"icmp-host-prohibited", "host-prohib",
IPT_ICMP_HOST_PROHIBITED, "ICMP host prohibited"},
{"tcp-reset", "tcp-rst",
IPT_TCP_RESET, "TCP RST packet"},
{"icmp-admin-prohibited", "admin-prohib",
IPT_ICMP_ADMIN_PROHIBITED, "ICMP administratively prohibited (*)"}
[IPT_ICMP_NET_PROHIBITED] = {
"icmp-net-prohibited", "net-prohib",
"ICMP network prohibited",
"net-prohibited",
},
[IPT_ICMP_HOST_PROHIBITED] = {
"icmp-host-prohibited", "host-prohib",
"ICMP host prohibited",
"host-prohibited",
},
[IPT_TCP_RESET] = {
"tcp-reset", "tcp-rst",
"TCP RST packet",
"tcp reset",
},
[IPT_ICMP_ADMIN_PROHIBITED] = {
"icmp-admin-prohibited", "admin-prohib",
"ICMP administratively prohibited (*)",
"admin-prohibited",
},
};
static void
......@@ -64,6 +86,8 @@ print_reject_types(void)
printf("Valid reject types:\n");
for (i = 0; i < ARRAY_SIZE(reject_table); ++i) {
if (!reject_table[i].name)
continue;
printf(" %-25s\t%s\n", reject_table[i].name, reject_table[i].desc);
printf(" %-25s\talias\n", reject_table[i].alias);
}
......@@ -102,14 +126,17 @@ static void REJECT_parse(struct xt_option_call *cb)
unsigned int i;
xtables_option_parse(cb);
for (i = 0; i < ARRAY_SIZE(reject_table); ++i)
for (i = 0; i < ARRAY_SIZE(reject_table); ++i) {
if (!reject_table[i].name)
continue;
if (strncasecmp(reject_table[i].name,
cb->arg, strlen(cb->arg)) == 0 ||
strncasecmp(reject_table[i].alias,
cb->arg, strlen(cb->arg)) == 0) {
reject->with = reject_table[i].with;
reject->with = i;
return;
}
}
/* This due to be dropped late in 2.4 pre-release cycle --RR */
if (strncasecmp("echo-reply", cb->arg, strlen(cb->arg)) == 0 ||
strncasecmp("echoreply", cb->arg, strlen(cb->arg)) == 0)
......@@ -124,61 +151,32 @@ static void REJECT_print(const void *ip, const struct xt_entry_target *target,
{
const struct ipt_reject_info *reject
= (const struct ipt_reject_info *)target->data;
unsigned int i;
for (i = 0; i < ARRAY_SIZE(reject_table); ++i)
if (reject_table[i].with == reject->with)
break;
printf(" reject-with %s", reject_table[i].name);
printf(" reject-with %s", reject_table[reject->with].name);
}
static void REJECT_save(const void *ip, const struct xt_entry_target *target)
{
const struct ipt_reject_info *reject =
(const struct ipt_reject_info *)target->data;
unsigned int i;
for (i = 0; i < ARRAY_SIZE(reject_table); ++i)
if (reject_table[i].with == reject->with)
break;
printf(" --reject-with %s", reject_table[i].name);
printf(" --reject-with %s", reject_table[reject->with].name);
}
static const struct reject_names_xlate reject_table_xlate[] = {
{"net-unreachable", IPT_ICMP_NET_UNREACHABLE},
{"host-unreachable", IPT_ICMP_HOST_UNREACHABLE},
{"prot-unreachable", IPT_ICMP_PROT_UNREACHABLE},
{"port-unreachable", IPT_ICMP_PORT_UNREACHABLE},
#if 0
{"echo-reply", IPT_ICMP_ECHOREPLY},
#endif
{"net-prohibited", IPT_ICMP_NET_PROHIBITED},
{"host-prohibited", IPT_ICMP_HOST_PROHIBITED},
{"tcp reset", IPT_TCP_RESET},
{"admin-prohibited", IPT_ICMP_ADMIN_PROHIBITED}
};
static int REJECT_xlate(struct xt_xlate *xl,
const struct xt_xlate_tg_params *params)
{
const struct ipt_reject_info *reject =
(const struct ipt_reject_info *)params->target->data;
unsigned int i;
for (i = 0; i < ARRAY_SIZE(reject_table_xlate); ++i) {
if (reject_table_xlate[i].with == reject->with)
break;
}
if (reject->with == IPT_ICMP_PORT_UNREACHABLE)
xt_xlate_add(xl, "reject");
else if (reject->with == IPT_TCP_RESET)
xt_xlate_add(xl, "reject with %s",
reject_table_xlate[i].name);
reject_table[reject->with].xlate);
else
xt_xlate_add(xl, "reject with icmp type %s",
reject_table_xlate[i].name);
reject_table[reject->with].xlate);
return 1;
}
......
iptables-translate -A FORWARD -p TCP --dport 22 -j REJECT
nft add rule ip filter FORWARD tcp dport 22 counter reject
iptables-translate -A FORWARD -p TCP --dport 22 -j REJECT --reject-with icmp-net-unreachable
nft add rule ip filter FORWARD tcp dport 22 counter reject with icmp type net-unreachable
iptables-translate -A FORWARD -p TCP --dport 22 -j REJECT --reject-with tcp-reset
nft add rule ip filter FORWARD tcp dport 22 counter reject with tcp reset
iptables-translate -t nat -A postrouting -o eth0 -j SNAT --to 1.2.3.4
nft add rule ip nat postrouting oifname "eth0" counter snat to 1.2.3.4
iptables-translate -t nat -A postrouting -o eth0 -j SNAT --to 1.2.3.4-1.2.3.6
nft add rule ip nat postrouting oifname "eth0" counter snat to 1.2.3.4-1.2.3.6
iptables-translate -t nat -A postrouting -p tcp -o eth0 -j SNAT --to 1.2.3.4:1-1023
nft add rule ip nat postrouting oifname "eth0" ip protocol tcp counter snat to 1.2.3.4:1-1023
iptables-translate -t nat -A postrouting -o eth0 -j SNAT --to 1.2.3.4 --random
nft add rule ip nat postrouting oifname "eth0" counter snat to 1.2.3.4 random
iptables-translate -t nat -A postrouting -o eth0 -j SNAT --to 1.2.3.4 --random --persistent
nft add rule ip nat postrouting oifname "eth0" counter snat to 1.2.3.4 random,persistent
iptables-translate -A INPUT -p 51 -m ah --ahspi 500 -j DROP
nft add rule ip filter INPUT ah spi 500 counter drop
iptables-translate -A INPUT -p 51 -m ah --ahspi 500:600 -j DROP
nft add rule ip filter INPUT ah spi 500-600 counter drop
iptables-translate -A INPUT -p 51 -m ah ! --ahspi 50 -j DROP
nft add rule ip filter INPUT ah spi != 50 counter drop
......@@ -5,6 +5,8 @@
#include <limits.h> /* INT_MAX in ip6_tables.h */
#include <linux/netfilter_ipv4/ip_tables.h>
#include "libxt_icmp.h"
/* special hack for icmp-type 'any':
* Up to kernel <=2.4.20 the problem was:
* '-p icmp ' matches all icmp packets
......@@ -17,13 +19,7 @@ enum {
O_ICMP_TYPE = 0,
};
struct icmp_names {
const char *name;
uint8_t type;
uint8_t code_min, code_max;
};
static const struct icmp_names icmp_codes[] = {
static const struct xt_icmp_names icmp_codes[] = {
{ "any", 0xFF, 0, 0xFF },
{ "echo-reply", 0, 0, 0xFF },
/* Alias */ { "pong", 0, 0, 0xFF },
......@@ -78,34 +74,14 @@ static const struct icmp_names icmp_codes[] = {
{ "address-mask-reply", 18, 0, 0xFF }
};
static void
print_icmptypes(void)
{
unsigned int i;
printf("Valid ICMP Types:");
for (i = 0; i < ARRAY_SIZE(icmp_codes); ++i) {
if (i && icmp_codes[i].type == icmp_codes[i-1].type) {
if (icmp_codes[i].code_min == icmp_codes[i-1].code_min
&& (icmp_codes[i].code_max
== icmp_codes[i-1].code_max))
printf(" (%s)", icmp_codes[i].name);
else
printf("\n %s", icmp_codes[i].name);
}
else
printf("\n%s", icmp_codes[i].name);
}
printf("\n");
}
static void icmp_help(void)
{
printf(
"icmp match options:\n"
"[!] --icmp-type typename match icmp type\n"
"[!] --icmp-type type[/code] (or numeric type or type/code)\n");
print_icmptypes();
printf("Valid ICMP Types:");
xt_print_icmp_types(icmp_codes, ARRAY_SIZE(icmp_codes));
}
static const struct xt_option_entry icmp_opts[] = {
......
iptables-translate -t filter -A INPUT -m icmp --icmp-type echo-reply -j ACCEPT
nft add rule ip filter INPUT icmp type echo-reply counter accept
iptables-translate -t filter -A INPUT -m icmp --icmp-type 3 -j ACCEPT
nft add rule ip filter INPUT icmp type destination-unreachable counter accept
iptables-translate -t filter -A INPUT -m icmp ! --icmp-type 3 -j ACCEPT
nft add rule ip filter INPUT icmp type != destination-unreachable counter accept
......@@ -28,61 +28,23 @@ static const struct xt_option_entry realm_opts[] = {
XTOPT_TABLEEND,
};
/* array of realms from /etc/iproute2/rt_realms */
static const char f_realms[] = "/etc/iproute2/rt_realms";
/* array of realms from f_realms[] */
static struct xtables_lmap *realms;
static void realm_init(struct xt_entry_match *m)
{
const char file[] = "/etc/iproute2/rt_realms";
realms = xtables_lmap_init(file);
if (realms == NULL && errno != ENOENT)
fprintf(stderr, "Warning: %s: %s\n", file, strerror(errno));
}
static void realm_parse(struct xt_option_call *cb)
{
struct xt_realm_info *realminfo = cb->data;
int id;
char *end;
struct xt_realm_info *ri = cb->data;
unsigned int id, mask;
xtables_option_parse(cb);
realminfo->id = strtoul(cb->arg, &end, 0);
if (end != cb->arg && (*end == '/' || *end == '\0')) {
if (*end == '/')
realminfo->mask = strtoul(end+1, &end, 0);
else
realminfo->mask = 0xffffffff;
if (*end != '\0' || end == cb->arg)
xtables_error(PARAMETER_PROBLEM,
"Bad realm value \"%s\"", cb->arg);
} else {
id = xtables_lmap_name2id(realms, cb->arg);
if (id == -1)
xtables_error(PARAMETER_PROBLEM,
"Realm \"%s\" not found", cb->arg);
realminfo->id = id;
realminfo->mask = 0xffffffff;
}
if (cb->invert)
realminfo->invert = 1;
}
xtables_parse_val_mask(cb, &id, &mask, realms);
static void
print_realm(unsigned long id, unsigned long mask, int numeric)
{
const char *name = NULL;
ri->id = id;
ri->mask = mask;
if (mask != 0xffffffff)
printf(" 0x%lx/0x%lx", id, mask);
else {
if (numeric == 0)
name = xtables_lmap_id2name(realms, id);
if (name)
printf(" %s", name);
else
printf(" 0x%lx", id);
}
if (cb->invert)
ri->invert = 1;
}
static void realm_print(const void *ip, const struct xt_entry_match *match,
......@@ -94,7 +56,7 @@ static void realm_print(const void *ip, const struct xt_entry_match *match,
printf(" !");
printf(" realm");
print_realm(ri->id, ri->mask, numeric);
xtables_print_val_mask(ri->id, ri->mask, numeric ? NULL : realms);
}
static void realm_save(const void *ip, const struct xt_entry_match *match)
......@@ -105,7 +67,7 @@ static void realm_save(const void *ip, const struct xt_entry_match *match)
printf(" !");
printf(" --realm");
print_realm(ri->id, ri->mask, 0);
xtables_print_val_mask(ri->id, ri->mask, realms);
}
static void
......@@ -151,7 +113,6 @@ static struct xtables_match realm_mt_reg = {
.size = XT_ALIGN(sizeof(struct xt_realm_info)),
.userspacesize = XT_ALIGN(sizeof(struct xt_realm_info)),
.help = realm_help,
.init = realm_init,
.print = realm_print,
.save = realm_save,
.x6_parse = realm_parse,
......@@ -161,5 +122,10 @@ static struct xtables_match realm_mt_reg = {
void _init(void)
{
realms = xtables_lmap_init(f_realms);
if (realms == NULL && errno != ENOENT)
fprintf(stderr, "Warning: %s: %s\n", f_realms,
strerror(errno));
xtables_register_match(&realm_mt_reg);
}
iptables-translate -A PREROUTING -m realm --realm 4
nft add rule ip filter PREROUTING rtclassid 0x4 counter
iptables-translate -A PREROUTING -m realm --realm 5/5
nft add rule ip filter PREROUTING rtclassid and 0x5 == 0x5 counter
iptables-translate -A PREROUTING -m realm ! --realm 50
nft add rule ip filter PREROUTING rtclassid != 0x32 counter
iptables-translate -A INPUT -m realm --realm 1/0xf
nft add rule ip filter INPUT rtclassid and 0xf == 0x1 counter
iptables-translate -A INPUT -m ttl --ttl-eq 3 -j ACCEPT
nft add rule ip filter INPUT ip ttl 3 counter accept
iptables-translate -A INPUT -m ttl --ttl-gt 5 -j ACCEPT
nft add rule ip filter INPUT ip ttl gt 5 counter accept
......@@ -82,6 +82,16 @@ static void audit_save(const void *ip, const struct xt_entry_target *target)
}
}
static int audit_xlate(struct xt_xlate *xl,
const struct xt_xlate_tg_params *params)
{
/* audit type is merely sanity checked by xt_AUDIT.ko,
* so nftables doesn't even support it */
xt_xlate_add(xl, "log level audit");
return 1;
}
static struct xtables_target audit_tg_reg = {
.name = "AUDIT",
.version = XTABLES_VERSION,
......@@ -93,6 +103,7 @@ static struct xtables_target audit_tg_reg = {
.save = audit_save,
.x6_parse = audit_parse,
.x6_options = audit_opts,
.xlate = audit_xlate,
};
void _init(void)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment