int gre_encapsulate(ip_t *honeyd_ip, struct addr *src, struct addr *dst, struct ip_hdr *iip, u_int iiplen) { struct ip_hdr *oip = (struct ip_hdr *) pkt; struct gre_hdr *gre = (struct gre_hdr *) (oip + 1); u_char *data = (u_char *) (gre + 1); u_int iplen, sum; iplen = sizeof(struct ip_hdr) + sizeof(struct gre_hdr) + iiplen; if (iplen > sizeof(pkt)) { syslog(LOG_ERR, "%s: packet too long: %d", __func__, iplen); return (-1); } ip_pack_hdr(pkt, 0, iplen, rand_uint16(honeyd_rand), 0, honeyd_ttl, IP_PROTO_GRE, src->addr_ip, dst->addr_ip); memset(gre, 0, sizeof(struct gre_hdr)); gre->gre_flags = htons(GRE_CHECKSUM | GRE_VERSION); gre->gre_proto = htons(GRE_IP4PROTO); /* Copy the payload */ memcpy(data, iip, iiplen); /* Calculate the checksum */ sum = ip_cksum_add(gre, iiplen + sizeof(struct gre_hdr), 0); gre->gre_sum = ip_cksum_carry(sum); ip_checksum(oip, iplen); return (ip_send(honeyd_ip, pkt, iplen) != iplen ? -1 : 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); }