static void test_antispoof_arp_gratuitous(void) { # include "arp_gratuitous.c" const unsigned char *pkts[] = {pkt1}; int pkts_size[] = {42}; uint16_t pkts_nb = 1; struct ether_addr inside_mac; uint32_t inside_ip; pg_scan_ether_addr(&inside_mac, "00:23:df:ff:c9:23"); inside_ip = htobe32(IPv4(192, 168, 22, 56)); test_antispoof_generic(pkts, pkts_size, pkts_nb, inside_mac, inside_ip); }
static void test_antispoof_arp_response(void) { # include "arp_response.c" const unsigned char *pkts[] = {pkt1}; int pkts_size[] = {42}; uint16_t pkts_nb = 1; struct ether_addr inside_mac; uint32_t inside_ip; pg_scan_ether_addr(&inside_mac, "00:18:b9:56:2e:73"); inside_ip = htobe32(IPv4(192, 168, 21, 2)); test_antispoof_generic(pkts, pkts_size, pkts_nb, inside_mac, inside_ip); }
static void test_antispoof_arp_request(void) { # include "arp_request.c" const unsigned char *pkts[] = {pkt1}; int pkts_size[] = {42}; uint16_t pkts_nb = 1; struct ether_addr inside_mac; uint32_t inside_ip; pg_scan_ether_addr(&inside_mac, "00:e0:81:d5:02:91"); inside_ip = htobe32(IPv4(192, 168, 21, 253)); test_antispoof_generic(pkts, pkts_size, pkts_nb, inside_mac, inside_ip); }
static void test_antispoof_rarp(void) { # include "rarp.c" const unsigned char *pkts[] = {pkt1}; int pkts_size[] = {15}; uint16_t pkts_nb = 1; struct ether_addr inside_mac; struct pg_brick *gen_west; struct pg_brick *antispoof; struct pg_brick *col_east; struct pg_error *error = NULL; uint16_t packet_count; uint16_t i; struct rte_mbuf *packet; uint64_t filtered_pkts_mask; pg_scan_ether_addr(&inside_mac, "00:23:df:ff:c9:23"); /* [generator>]--[antispoof]--[collector] */ gen_west = pg_packetsgen_new("gen_west", 1, 1, EAST_SIDE, &packet, 1, &error); g_assert(!error); antispoof = pg_antispoof_new("antispoof", 1, 1, EAST_SIDE, inside_mac, &error); g_assert(!error); col_east = pg_collect_new("col_east", 1, 1, &error); g_assert(!error); pg_brick_link(gen_west, antispoof, &error); g_assert(!error); pg_brick_link(antispoof, col_east, &error); g_assert(!error); /* replay traffic */ for (i = 0; i < pkts_nb; i++) { packet = build_packet(pkts[i], pkts_size[i]); pg_brick_poll(gen_west, &packet_count, &error); g_assert(!error); g_assert(packet_count == 1); pg_brick_west_burst_get(col_east, &filtered_pkts_mask, &error); g_assert(!error); g_assert(pg_mask_count(filtered_pkts_mask) == 0); rte_pktmbuf_free(packet); } pg_brick_destroy(gen_west); pg_brick_destroy(antispoof); pg_brick_destroy(col_east); }
static void test_pg_antispoof_arp_disable(void) { # include "arp_request.c" const unsigned char *pkts[] = {pkt1}; int pkts_size[] = {42}; uint16_t pkts_nb = 1; struct ether_addr inside_mac; uint32_t inside_ip; struct pg_brick *gen_west; struct pg_brick *antispoof; struct pg_brick *col_east; struct pg_error *error = NULL; uint16_t packet_count; uint16_t i; struct rte_mbuf *packet; uint64_t filtered_pkts_mask; struct rte_mbuf **filtered_pkts; pg_scan_ether_addr(&inside_mac, "00:e0:81:d5:02:91"); inside_ip = htobe32(IPv4(0, 0, 0, 42)); /* [generator>]--[antispoof]--[collector] */ gen_west = pg_packetsgen_new("gen_west", 1, 1, EAST_SIDE, &packet, 1, &error); g_assert(!error); antispoof = pg_antispoof_new("antispoof", 1, 1, EAST_SIDE, inside_mac, &error); g_assert(!error); col_east = pg_collect_new("col_east", 1, 1, &error); g_assert(!error); pg_brick_link(gen_west, antispoof, &error); g_assert(!error); pg_brick_link(antispoof, col_east, &error); g_assert(!error); /* enable ARP antispoof with a wrong IP */ pg_antispoof_arp_enable(antispoof, inside_ip); /* replay traffic */ for (i = 0; i < pkts_nb; i++) { packet = build_packet(pkts[i], pkts_size[i]); pg_brick_poll(gen_west, &packet_count, &error); g_assert(!error); g_assert(packet_count == 1); filtered_pkts = pg_brick_west_burst_get(col_east, &filtered_pkts_mask, &error); g_assert(!error); g_assert(pg_mask_count(filtered_pkts_mask) == 0); pg_packets_free(filtered_pkts, filtered_pkts_mask); rte_pktmbuf_free(packet); } /* disable ARP antispoof, should now pass */ pg_antispoof_arp_disable(antispoof); /* replay traffic */ for (i = 0; i < pkts_nb; i++) { packet = build_packet(pkts[i], pkts_size[i]); pg_brick_poll(gen_west, &packet_count, &error); g_assert(!error); g_assert(packet_count == 1); filtered_pkts = pg_brick_west_burst_get(col_east, &filtered_pkts_mask, &error); g_assert(!error); g_assert(pg_mask_count(filtered_pkts_mask) == 1); pg_packets_free(filtered_pkts, filtered_pkts_mask); rte_pktmbuf_free(packet); } pg_brick_destroy(gen_west); pg_brick_destroy(antispoof); pg_brick_destroy(col_east); }
int main(int argc, char **argv) { struct pg_error *error = NULL; int ret; uint64_t args_flags; struct vtep_opts opt = {NULL, NULL, NULL, NULL}; int32_t ip; struct ether_addr eth_addr; struct ether_addr inner_addr; GList *neighbor_addrs = NULL; ret = pg_start(argc, argv, &error); g_assert(ret != -1); CHECK_ERROR(error); if (signal(SIGINT, sig_handler) == SIG_ERR) return -errno; /* accounting program name */ argc -= ret; argv += ret; args_flags = parse_args(argc, argv, &opt); if (args_flags & PRINT_USAGE) print_usage(); if (!!(args_flags & FAIL)) { dprintf(2, "Invalide arguments, use '-h'\n"); ret = -EINVAL; goto exit; } if (!pg_scan_ether_addr(ð_addr, opt.mac) || !is_valid_assigned_ether_addr(ð_addr)) { char buf[40]; ether_format_addr(buf, 40, ð_addr); dprintf(2, "%s is an invalide ethernet adress\n" "sould be an unicast addr and have format XX:XX:XX:XX:XX:XX\n", buf); ret = -EINVAL; goto exit; } if (!pg_scan_ether_addr(&inner_addr, opt.inner_mac) || !is_valid_assigned_ether_addr(&inner_addr)) { char buf[40]; ether_format_addr(buf, 40, &inner_addr); dprintf(2, "%s is an invalide ethernet adress\n" "sould be an unicast addr and have format XX:XX:XX:XX:XX:XX\n", buf); ret = -EINVAL; goto exit; } for (GList *lst = opt.neighbor_macs; lst != NULL; lst = lst->next) { const char *data = lst->data; struct ether_addr *tmp = g_new0(struct ether_addr, 1); if (!pg_scan_ether_addr(tmp, data) || !is_valid_assigned_ether_addr(tmp)) { char buf[40]; ether_format_addr(buf, 40, tmp); dprintf(2, "%s is an invalide ethernet adress\n" "sould be an unicast addr and have format XX:XX:XX:XX:XX:XX\n", buf); ret = -EINVAL; goto exit; } neighbor_addrs = g_list_append(neighbor_addrs, tmp); } ip = inet_addr(opt.ip); if (ip < 0) { dprintf(2, "invalide ip\n" "should have format: XXX.XXX.XXX.XXX\n"); return -EINVAL; } ret = start_loop(ip, ð_addr, &inner_addr, neighbor_addrs); exit: g_list_free(opt.neighbor_macs); g_list_free_full(neighbor_addrs, destroy_ether_addr); pg_stop(); return ret; }
static void firewall_replay(const unsigned char *pkts[], int pkts_nb, int *pkts_size) { struct pg_brick *gen_west, *gen_east; struct pg_brick *fw; struct pg_brick *col_west, *col_east; struct pg_error *error = NULL; uint16_t i, packet_count; struct rte_mbuf *packet; struct ether_hdr *eth; uint64_t filtered_pkts_mask; struct rte_mbuf **filtered_pkts; struct ether_addr tmp_addr; int ret; /* have some collectors and generators on each sides * [collector]--[generator>]--[firewall]--[<generator]--[collector] * 10.0.2.15 173.194.40.111 * 8:0:27:b6:5:16 52:54:0:12:35:2 */ gen_west = pg_packetsgen_new("gen_west", 1, 1, EAST_SIDE, &packet, 1, &error); g_assert(!error); gen_east = pg_packetsgen_new("gen_east", 1, 1, WEST_SIDE, &packet, 1, &error); g_assert(!error); fw = pg_firewall_new("fw", 1, 1, PG_NONE, &error); g_assert(!error); col_west = pg_collect_new("col_west", 1, 1, &error); g_assert(!error); col_east = pg_collect_new("col_east", 1, 1, &error); g_assert(!error); pg_brick_link(col_west, gen_west, &error); g_assert(!error); pg_brick_link(gen_west, fw, &error); g_assert(!error); pg_brick_link(fw, gen_east, &error); g_assert(!error); pg_brick_link(gen_east, col_east, &error); g_assert(!error); /* open all traffic of 10.0.2.15 from the west side of the firewall * returning traffic should be allowed due to STATEFUL option */ ret = pg_firewall_rule_add(fw, "src host 10.0.2.15", WEST_SIDE, 1, &error); g_assert(!error); g_assert(ret == 0); ret = pg_firewall_reload(fw, &error); g_assert(!error); g_assert(ret < 0); /* replay traffic */ for (i = 0; i < pkts_nb; i++) { struct ip *ip; packet = build_packet(pkts[i], pkts_size[i]); eth = rte_pktmbuf_mtod(packet, struct ether_hdr*); ip = (struct ip *)(eth + 1); if (ip->ip_src.s_addr == inet_addr("10.0.2.15")) { pg_brick_poll(gen_west, &packet_count, &error); g_assert(!error); g_assert(packet_count == 1); filtered_pkts = pg_brick_west_burst_get(col_east, &filtered_pkts_mask, &error); g_assert(!error); g_assert(pg_mask_count(filtered_pkts_mask) == 1); /* check eth source address */ eth = rte_pktmbuf_mtod(filtered_pkts[0], struct ether_hdr*); pg_scan_ether_addr(&tmp_addr, "08:00:27:b6:05:16"); g_assert(is_same_ether_addr(ð->s_addr, &tmp_addr)); /* check ip source address */ ip = (struct ip *)(eth + 1); g_assert(ip->ip_src.s_addr == inet_addr("10.0.2.15")); } else if (ip->ip_src.s_addr == inet_addr("173.194.40.111")) {