From f46b263b4085c9985e1ddaa82d7bbff097401391 Mon Sep 17 00:00:00 2001 From: Bart De Schuymer Date: Thu, 1 May 2003 20:18:00 +0000 Subject: Add arp mac address matching --- extensions/ebt_arp.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 94 insertions(+), 5 deletions(-) (limited to 'extensions/ebt_arp.c') diff --git a/extensions/ebt_arp.c b/extensions/ebt_arp.c index 6298d5e..4df650b 100644 --- a/extensions/ebt_arp.c +++ b/extensions/ebt_arp.c @@ -4,6 +4,7 @@ #include #include "../include/ebtables_u.h" #include "../include/ethernetdb.h" +#include #include #define ARP_OPCODE '1' @@ -11,6 +12,8 @@ #define ARP_PTYPE '3' #define ARP_IP_S '4' #define ARP_IP_D '5' +#define ARP_MAC_S '6' +#define ARP_MAC_D '7' static struct option opts[] = { { "arp-opcode" , required_argument, 0, ARP_OPCODE }, @@ -19,6 +22,8 @@ static struct option opts[] = { "arp-ptype" , required_argument, 0, ARP_PTYPE }, { "arp-ip-src" , required_argument, 0, ARP_IP_S }, { "arp-ip-dst" , required_argument, 0, ARP_IP_D }, + { "arp-mac-src" , required_argument, 0, ARP_MAC_S }, + { "arp-mac-dst" , required_argument, 0, ARP_MAC_D }, { 0 } }; @@ -43,11 +48,13 @@ static void print_help() printf( "arp options:\n" -"--arp-opcode opcode : ARP opcode (integer or string)\n" -"--arp-htype type : ARP hardware type (integer or string)\n" -"--arp-ptype type : ARP protocol type (hexadecimal or string)\n" -"--arp-ip-src [!] address[/mask]: ARP IP source specification\n" -"--arp-ip-dst [!] address[/mask]: ARP IP target specification\n" +"--arp-opcode opcode : ARP opcode (integer or string)\n" +"--arp-htype type : ARP hardware type (integer or string)\n" +"--arp-ptype type : ARP protocol type (hexadecimal or string)\n" +"--arp-ip-src [!] address[/mask]: ARP IP source specification\n" +"--arp-ip-dst [!] address[/mask]: ARP IP target specification\n" +"--arp-mac-src [!] address[/mask]: ARP MAC source specification\n" +"--arp-mac-dst [!] address[/mask]: ARP MAC target specification\n" " opcode strings: \n"); for (i = 0; i < NUMOPCODES; i++) printf("%d = %s\n", i + 1, opcodes[i]); @@ -67,11 +74,16 @@ static void init(struct ebt_entry_match *match) /* defined in ebt_ip.c */ void parse_ip_address(char *address, uint32_t *addr, uint32_t *msk); +/* defined in ebtables.c */ +int getmac_and_mask(char *from, char *to, char *mask); + #define OPT_OPCODE 0x01 #define OPT_HTYPE 0x02 #define OPT_PTYPE 0x04 #define OPT_IP_S 0x08 #define OPT_IP_D 0x10 +#define OPT_MAC_S 0x20 +#define OPT_MAC_D 0x40 static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, unsigned int *flags, struct ebt_entry_match **match) { @@ -80,6 +92,8 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, char *end; uint32_t *addr; uint32_t *mask; + char *maddr; + char *mmask; switch (c) { case ARP_OPCODE: @@ -172,6 +186,32 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, print_error("Missing ARP IP address argument"); parse_ip_address(argv[optind - 1], addr, mask); break; + + case ARP_MAC_S: + case ARP_MAC_D: + if (c == ARP_MAC_S) { + check_option(flags, OPT_MAC_S); + maddr = arpinfo->smaddr; + mmask = arpinfo->smmsk; + arpinfo->bitmask |= EBT_ARP_SRC_MAC; + } else { + check_option(flags, OPT_MAC_D); + maddr = arpinfo->dmaddr; + mmask = arpinfo->dmmsk; + arpinfo->bitmask |= EBT_ARP_DST_MAC; + } + if (check_inverse(optarg)) { + if (c == ARP_MAC_S) + arpinfo->invflags |= EBT_ARP_SRC_MAC; + else + arpinfo->invflags |= EBT_ARP_DST_MAC; + } + if (optind > argc) + print_error("Missing ARP MAC address argument"); + if (getmac_and_mask(argv[optind - 1], maddr, mmask)) + print_error("Problem with ARP MAC address argument"); + break; + default: return 0; } @@ -243,6 +283,43 @@ static void print(const struct ebt_u_entry *entry, (i == 3) ? "" : "."); printf("%s ", mask_to_dotted(arpinfo->dmsk)); } + if (arpinfo->bitmask & EBT_ARP_SRC_MAC) { + int verdict; + printf("--arp-mac-src "); + if (arpinfo->invflags & EBT_ARP_SRC_MAC) + printf("! "); + for (i = 0; i < 6; i++) + printf("%x%s", ((unsigned char *)&arpinfo->smaddr)[i], + (i == 5) ? "" : ":"); + verdict = 0; + for (i = 0; i < 6; i++) + verdict = (arpinfo->smmsk[i] ^ 0xFF); + if (verdict != 0) { + printf("%s", "/"); + for (i = 0; i < 6; i++) + printf("%x%s", ((unsigned char *)&arpinfo->smmsk)[i], + (i == 5) ? "" : ":"); + printf("%s", " "); + } + } + if (arpinfo->bitmask & EBT_ARP_DST_MAC) { + int verdict; + printf("--arp-mac-dst "); + if (arpinfo->invflags & EBT_ARP_DST_MAC) + printf("! "); + for (i = 0; i < 6; i++) + printf("%x%s", ((unsigned char *)&arpinfo->dmaddr)[i], + (i == 5) ? "" : ":"); + verdict = 0; + for (i = 0; i < 6; i++) + verdict = (arpinfo->dmmsk[i] ^ 0xFF); + if (verdict != 0) { + printf("%s", "/"); + for (i = 0; i < 6; i++) + printf("%x%s", ((unsigned char *)&arpinfo->dmmsk)[i], + (i == 5) ? "" : ":"); + } + } } static int compare(const struct ebt_entry_match *m1, @@ -279,6 +356,18 @@ static int compare(const struct ebt_entry_match *m1, if (arpinfo1->dmsk != arpinfo2->dmsk) return 0; } + if (arpinfo1->bitmask & EBT_ARP_SRC_MAC) { + if (arpinfo1->smaddr != arpinfo2->smaddr) + return 0; + if (arpinfo1->smmsk != arpinfo2->smmsk) + return 0; + } + if (arpinfo1->bitmask & EBT_ARP_DST_MAC) { + if (arpinfo1->dmaddr != arpinfo2->dmaddr) + return 0; + if (arpinfo1->dmmsk != arpinfo2->dmmsk) + return 0; + } return 1; } -- cgit v1.2.3