int main(int argc, char **argv) { ip_t *sock; intf_t *intf; struct addr dst; struct ip_hdr *ip; struct udp_hdr *udp; struct intf_entry entry; int len = IP_HDR_LEN + UDP_HDR_LEN; char buf[len]; if (argc < 2 || addr_aton(argv[1], &dst)) { printf("error: please specify a target ip address\n"); return 1; } memset(buf, 0, sizeof(buf)); ip = (struct ip_hdr *) buf; ip->ip_v = 4; ip->ip_hl = 5; ip->ip_tos = 0; ip->ip_off = 0; ip->ip_sum = 0; ip->ip_ttl = IP_TTL_MAX; ip->ip_p = IP_PROTO_UDP; ip->ip_id = htons(0xdead); ip->ip_len = htons(len); udp = (struct udp_hdr *) (buf + IP_HDR_LEN); udp->uh_sum = 0; udp->uh_sport = htons(0); udp->uh_dport = htons(5353); udp->uh_ulen = htons(UDP_HDR_LEN); intf = intf_open(); intf_get_dst(intf, &entry, &dst); intf_close(intf); ip->ip_src = entry.intf_addr.addr_ip; ip->ip_dst = dst.addr_ip; ip_checksum(buf, len); sock = ip_open(); if (!sock) { printf("error: root privileges needed for raw socket\n"); return 1; } ip_send(sock, buf, len); ip_close(sock); return 0; }
int intf_main(int argc, char *argv[]) { struct intf_entry *entry; struct addr *ap, addr; char *cmd, buf[1024]; if (argc < 2) usage(); cmd = argv[1]; entry = (struct intf_entry *)buf; memset(entry, 0, sizeof(*entry)); entry->intf_len = sizeof(buf); if ((intf = intf_open()) == NULL) err(1, "intf_open"); if (strcmp(cmd, "show") == 0) { if (intf_loop(intf, print_intf, NULL) < 0) err(1, "intf_loop"); } else if (strcmp(cmd, "get") == 0) { if (argc < 3) usage(); strlcpy(entry->intf_name, argv[2], sizeof(entry->intf_name)); if (intf_get(intf, entry) < 0) err(1, "intf_get"); print_intf(entry, NULL); } else if (strcmp(cmd, "src") == 0) { if (argc < 3 || addr_aton(argv[2], &addr) < 0) usage(); if (intf_get_src(intf, entry, &addr) < 0) err(1, "intf_get_src"); print_intf(entry, NULL); } else if (strcmp(cmd, "dst") == 0) { if (argc < 3 || addr_aton(argv[2], &addr) < 0) usage(); if (intf_get_dst(intf, entry, &addr) < 0) err(1, "intf_get_dst"); print_intf(entry, NULL); } else if (strcmp(cmd, "set") == 0) { if (argc < 4) usage(); strlcpy(entry->intf_name, argv[2], sizeof(entry->intf_name)); for (argv += 3, argc -= 3; argc > 1; argv += 2, argc -= 2) { if (strcmp(argv[0], "alias") == 0) { ap = &entry->intf_alias_addrs [entry->intf_alias_num++]; } else if (strcmp(argv[0], "dst") == 0) { ap = &entry->intf_dst_addr; } else if (strcmp(argv[0], "inet") == 0) { ap = &entry->intf_addr; } else if (strcmp(argv[0], "link") == 0) { ap = &entry->intf_link_addr; } else break; if (addr_pton(argv[1], ap) < 0) err(1, "invalid address: %s", argv[1]); } for ( ; argc > 0; argv++, argc--) { if (strcmp(argv[0], "up") == 0) entry->intf_flags |= INTF_FLAG_UP; else if (strcmp(argv[0], "down") == 0) entry->intf_flags &= ~INTF_FLAG_UP; else if (strcmp(argv[0], "arp") == 0) entry->intf_flags &= ~INTF_FLAG_NOARP; else if (strcmp(argv[0], "noarp") == 0) entry->intf_flags |= INTF_FLAG_NOARP; else usage(); } if (intf_set(intf, entry) < 0) err(1, "intf_set"); } else usage(); intf_close(intf); exit(0); }
int main(int argc, char *argv[]) { struct intf_entry ifent; intf_t *intf; int i, tests; char *cmd; if (argc < 3) usage(); for (tests = 0, i = 1; i < argc - 1; i++) { cmd = argv[i]; if (strcmp(cmd, "all") == 0) tests = ~0; else if (strcmp(cmd, "ping") == 0) tests |= TEST_PING; else if (strcmp(cmd, "ip-opt") == 0) tests |= TEST_IP_OPT; else if (strcmp(cmd, "ip-tracert") == 0) tests |= TEST_IP_TRACERT; else if (strcmp(cmd, "frag") == 0) tests |= TEST_FRAG; else if (strcmp(cmd, "frag-new") == 0) tests |= TEST_FRAG_NEW; else if (strcmp(cmd, "frag-old") == 0) tests |= TEST_FRAG_OLD; else if (strcmp(cmd, "frag-timeout") == 0) tests |= TEST_FRAG_TIMEOUT; else usage(); } if (addr_aton(argv[i], &ctx.dst) < 0) err(1, "invalid host %s", argv[i]); if ((intf = intf_open()) == NULL) err(1, "couldn't open interface handle"); ifent.intf_len = sizeof(ifent); if (intf_get_dst(intf, &ifent, &ctx.dst) < 0) err(1, "couldn't find interface for %s", addr_ntoa(&ctx.dst)); memcpy(&ctx.src, &ifent.intf_addr, sizeof(ctx.src)); ctx.src.addr_bits = IP_ADDR_BITS; intf_close(intf); if ((ctx.ip = ip_open()) == NULL) err(1, "couldn't open raw IP interface"); if ((ctx.pcap = pcap_open(ifent.intf_name)) == NULL) err(1, "couldn't open %s for sniffing", ifent.intf_name); if ((ctx.dloff = pcap_dloff(ctx.pcap)) < 0) err(1, "couldn't determine link layer offset"); ctx.rnd = rand_open(); pkt_init(16); TAILQ_INIT(&ctx.pktq); ping = pkt_new(); ip_pack_hdr(ping->pkt_ip, 0, IP_HDR_LEN + 8 + 24, 666, 0, IP_TTL_DEFAULT, IP_PROTO_ICMP, ctx.src.addr_ip, ctx.dst.addr_ip); icmp_pack_hdr_echo(ping->pkt_icmp, ICMP_ECHO, ICMP_CODE_NONE, 666, 1, "AAAAAAAABBBBBBBBCCCCCCCC", 24); ping->pkt_end = ping->pkt_eth_data + IP_HDR_LEN + 8 + 24; pkt_decorate(ping); if ((tests & TEST_PING) != 0) test_ping(); if ((tests & TEST_IP_OPT) != 0) test_ip_opt(); if ((tests & TEST_IP_TRACERT) != 0) test_ip_tracert(); if ((tests & TEST_FRAG) != 0) test_frag(NULL, 0); if ((tests & TEST_FRAG_NEW) != 0) test_frag("new", 0); if ((tests & TEST_FRAG_OLD) != 0) test_frag("old", 0); if ((tests & TEST_FRAG_TIMEOUT) != 0) test_frag(NULL, 1); rand_close(ctx.rnd); pcap_close(ctx.pcap); ip_close(ctx.ip); exit(0); }
static void fragroute_init(const char *dst, const char *outfile) { struct arp_entry arpent; struct intf_entry ifent; struct route_entry rtent; #ifdef WIN32 WSADATA wsdata; if (WSAStartup(MAKEWORD(2, 2), &wsdata) != 0) err(1, "couldn't initialize Winsock"); SetConsoleCtrlHandler(fragroute_signal, TRUE); #else signal(SIGINT, fragroute_signal); signal(SIGTERM, fragroute_signal); #endif if (addr_aton(dst, &ctx.dst) < 0) err(1, "destination address invalid"); if (ctx.dst.addr_bits != IP_ADDR_BITS) errx(1, "only /32 destinations supported at this time"); pkt_init(128); event_init(); // event_sigcb = fragroute_close; if ((ctx.arp = arp_open()) == NULL || (ctx.intf = intf_open()) == NULL || (ctx.route = route_open()) == NULL) err(1, "couldn't open kernel networking interfaces"); /* Find outgoing interface, addresses, and MTU. */ ifent.intf_len = sizeof(ifent); if (intf_get_dst(ctx.intf, &ifent, &ctx.dst) < 0) err(1, "couldn't determine outgoing interface"); memcpy(&ctx.src, &ifent.intf_addr, sizeof(ctx.src)); ctx.src.addr_bits = IP_ADDR_BITS; memcpy(&ctx.smac, &ifent.intf_link_addr, sizeof(ctx.smac)); ctx.mtu = ifent.intf_mtu; /* Open outgoing interface for sending. */ if ((ctx.eth = eth_open(ifent.intf_name)) == NULL) err(1, "couldn't open %s for sending", ifent.intf_name); /* Find destination MAC address. */ memcpy(&arpent.arp_pa, &ctx.dst, sizeof(arpent.arp_pa)); if (arp_get(ctx.arp, &arpent) < 0) { memcpy(&rtent.route_dst, &ctx.dst, sizeof(rtent.route_dst)); if (route_get(ctx.route, &rtent) < 0) err(1, "no route to %s", addr_ntoa(&rtent.route_dst)); memcpy(&arpent.arp_pa, &rtent.route_gw, sizeof(arpent.arp_pa)); if (arp_get(ctx.arp, &arpent) < 0) err(1, "no ARP entry for %s", addr_ntoa(&arpent.arp_pa)); } memcpy(&ctx.dmac, &arpent.arp_ha, sizeof(ctx.dmac)); /* Setup our tunnel. */ if ((ctx.tun = tun_open(&ctx.src, &ctx.dst, ctx.mtu)) == NULL) err(1, "couldn't initialize tunnel interface"); ctx.dfile = NULL; if (outfile && ((ctx.dfile = pcap_dump_open(ctx.tun->pcap, outfile)) == NULL)) err(1, "couldn't open pcap dump file"); tun_register(ctx.tun, fragroute_process, &ctx); }