static int test_ping(void) { struct pkt *pkt; struct timeval tv; printf("ping: "); fflush(stdout); ping->pkt_icmp_msg->echo.icmp_id = rand_uint16(ctx.rnd); pkt = pkt_dup(ping); pkt->pkt_ip->ip_id = rand_uint16(ctx.rnd); ip_checksum(pkt->pkt_ip, pkt->pkt_end - pkt->pkt_eth_data); pcap_filter(ctx.pcap, "icmp[0] = 0 and src %s and dst %s", addr_ntoa(&ctx.dst), addr_ntoa(&ctx.src)); send_pkt(pkt); for (tv = read_tv; (pkt = recv_pkt(&tv)) != NULL; tv = read_tv) { if (memcmp(&pkt->pkt_icmp_msg->echo, &ping->pkt_icmp_msg->echo, 8) == 0) break; } printf("%s\n", pkt ? timeval_ntoa(&tv) : "no reply"); return (0); }
static int test_frag(char *overlap, int drop) { struct timeval tv, save_tv = read_tv; struct pkt *pkt; struct icmp_msg_echo *echo; char *frag_argv[4]; if (overlap != NULL) printf("frag-%s: ", overlap); else if (drop) printf("frag-timeout (please wait): "); else printf("frag: "); fflush(stdout); ping->pkt_ip->ip_id = rand_uint16(ctx.rnd); ping->pkt_icmp_msg->echo.icmp_id = rand_uint16(ctx.rnd); pkt = pkt_dup(ping); ip_checksum(pkt->pkt_ip, pkt->pkt_end - pkt->pkt_eth_data); TAILQ_INSERT_TAIL(&ctx.pktq, pkt, pkt_next); frag_argv[0] = "ip_frag"; frag_argv[1] = "8"; frag_argv[2] = overlap; frag_argv[3] = NULL; mod_ip_frag.open(overlap ? 3 : 2, frag_argv, NULL); mod_ip_frag.apply(NULL, &ctx.pktq, NULL); if (drop) { pkt = TAILQ_LAST(&ctx.pktq, pktq); TAILQ_REMOVE(&ctx.pktq, pkt, pkt_next); pkt_free(pkt); save_tv.tv_sec = FRAG_TIMEOUT; } pcap_filter(ctx.pcap, "icmp[0] = %d and src %s and dst %s", drop ? 11 : 0, addr_ntoa(&ctx.dst), addr_ntoa(&ctx.src)); send_pktq(&ctx.pktq); for (tv = save_tv; (pkt = recv_pkt(&tv)) != NULL; tv = save_tv) { if (drop) { echo = (struct icmp_msg_echo *) (pkt->pkt_icmp_msg->timexceed.icmp_ip + IP_HDR_LEN + ICMP_HDR_LEN); } else { echo = &pkt->pkt_icmp_msg->echo; } if (echo->icmp_id == ping->pkt_icmp_msg->echo.icmp_id) break; } printf("%s\n", pkt ? timeval_ntoa(&tv) : "no reply"); return (0); }
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); }
void rrdtool_test(void) { extern char *honeyd_rrdtool_path; struct rrdtool_drv *drv; struct rrdtool_db *db; struct timeval tv, tv_now; char line[1024]; int i, in = 0, out = 0; drv = rrdtool_init(honeyd_rrdtool_path); assert(drv != NULL); db = rrdtool_db_start(drv, "/tmp/myrouter.rrd", 300); assert(db != NULL); rrdtool_db_datasource(db, "input", "COUNTER", 600); rrdtool_db_datasource(db, "output", "COUNTER", 600); rrdtool_db_commit(db); gettimeofday(&tv, NULL); tv_now = tv; for (i = 0; i < 500; i++) { tv.tv_sec += 60; in += (i*5) % 500; out += i % 400 + rand_uint16(honeyd_rand) % 1000; snprintf(line, sizeof(line), "%u:%u", in, out); rrdtool_db_update(db, &tv, line); } unlink("/tmp/honeyd_myrouter.gif"); snprintf(line, sizeof(line), "graph /tmp/honeyd_myrouter.gif --start %ld --end %ld " "--height 300 --width 600 " "DEF:inoctets=/tmp/myrouter.rrd:input:AVERAGE " "DEF:outoctets=/tmp/myrouter.rrd:output:AVERAGE " "CDEF:mout=outoctets,-1,* " "AREA:inoctets#00FF00:\"In traffic\" " "AREA:mout#0000FF:\"Out traffic\"", tv_now.tv_sec, tv.tv_sec); rrdtool_command(drv, line, rrdtool_test_done, NULL); event_dispatch(); if (access("/tmp/honeyd_myrouter.gif", R_OK) == -1) errx(1, "%s: graph creation failed", __func__); rrdtool_free(drv); fprintf(stderr, "\t%s: OK\n", __func__); }
unsigned short random_u16(unsigned int seed) { rand_t *r; int rv; unsigned int rand; r = rand_open(); if (r == NULL) return -1; rv = rand_set(r,&seed,4); if (r == NULL) return -1; rand = rand_uint16(r); r = rand_close(r); return rand; }
int drop_apply(void *d, struct pktq *pktq) { struct drop_data *data = (struct drop_data *)d; struct pkt *pkt; if (data->percent < 100 && (rand_uint16(data->rnd) % 100) > data->percent) return (0); if (data->which == DROP_FIRST) pkt = TAILQ_FIRST(pktq); else if (data->which == DROP_LAST) pkt = TAILQ_LAST(pktq, pktq); else pkt = pktq_random(data->rnd, pktq); TAILQ_REMOVE(pktq, pkt, pkt_next); pkt_free(pkt); return (0); }
static int test_ip_tracert(void) { struct timeval tv; struct hop hops[IP_TTL_DEFAULT]; struct pkt *pkt; struct icmp_msg_echo *echo; int i, hopcnt, max_ttl; printf("ip-tracert: "); fflush(stdout); pcap_filter(ctx.pcap, "icmp[0] = 0 and src %s and dst %s", addr_ntoa(&ctx.dst), addr_ntoa(&ctx.src)); ping->pkt_icmp_msg->echo.icmp_id = rand_uint16(ctx.rnd); pkt = pkt_dup(ping); pkt->pkt_ip->ip_id = rand_uint16(ctx.rnd); ip_checksum(pkt->pkt_ip, pkt->pkt_end - pkt->pkt_eth_data); send_pkt(pkt); tv = read_tv; if ((pkt = recv_pkt(&tv)) == NULL) { printf("no reply\n"); return (0); } /* XXX - guess remote stack's starting TTL */ for (i = 2; pkt->pkt_ip->ip_ttl > i; i <<= 1) ; if ((max_ttl = i - pkt->pkt_ip->ip_ttl + 1) > IP_TTL_DEFAULT) max_ttl = IP_TTL_DEFAULT; printf("%s, %d hops max\n", ip_ntoa(&ping->pkt_ip->ip_dst), max_ttl); pcap_filter(ctx.pcap, "icmp and dst %s", addr_ntoa(&ctx.src)); for (i = 1; i < max_ttl + 1; i++) { pkt = pkt_dup(ping); pkt->pkt_ip->ip_id = rand_uint16(ctx.rnd); pkt->pkt_ip->ip_ttl = i; pkt->pkt_icmp_msg->echo.icmp_seq = htons(i); ip_checksum(pkt->pkt_ip, pkt->pkt_end - pkt->pkt_eth_data); send_pkt(pkt); usleep(42); /* XXX */ } memset(&hops, 0, sizeof(hops)); hopcnt = 0; for (tv = read_tv; (pkt = recv_pkt(&tv)) != NULL; tv = read_tv) { if ((pkt->pkt_icmp->icmp_type == ICMP_TIMEXCEED || pkt->pkt_icmp->icmp_type == ICMP_UNREACH) && pkt->pkt_end - pkt->pkt_eth_data >= (IP_HDR_LEN + ICMP_LEN_MIN) * 2) { echo = (struct icmp_msg_echo *) (pkt->pkt_icmp_msg->timexceed.icmp_ip + IP_HDR_LEN + ICMP_HDR_LEN); } else if (pkt->pkt_icmp->icmp_type == ICMP_ECHOREPLY) { echo = &pkt->pkt_icmp_msg->echo; } else continue; if (echo->icmp_id != ping->pkt_icmp_msg->echo.icmp_id) continue; i = ntohs(echo->icmp_seq); addr_pack(&hops[i].addr, ADDR_TYPE_IP, IP_ADDR_BITS, &pkt->pkt_ip->ip_src, IP_ADDR_LEN); memcpy(&hops[i].icmp, pkt->pkt_icmp, ICMP_HDR_LEN); hops[i].ttl = pkt->pkt_ip->ip_ttl; hopcnt++; if (pkt->pkt_ip->ip_src == ping->pkt_ip->ip_dst) break; } for (i = 1; i < hopcnt + 1; i++) { if (hops[i].addr.addr_type == ADDR_TYPE_IP) { printf("%2d %s (%d)\n", i, addr_ntoa(&hops[i].addr), hops[i].ttl); } else printf("%2d *\n", i); } return (0); }
static int test_ip_opt(void) { struct pkt *pkt; struct timeval tv; struct ip_opt opts[IP_OPT_MAX]; int i, len, max; printf("ip-opt: "); fflush(stdout); memset(&opts, 0, sizeof(opts)); max = 0; opts[max].opt_type = IP_OPT_SEC; opts[max].opt_len = IP_OPT_LEN + 9; max++; opts[max].opt_type = IP_OPT_LSRR; opts[max].opt_len = IP_OPT_LEN + 1 + 4; opts[max].opt_data.rr.ptr = 8; opts[max].opt_data.rr.iplist[0] = ping->pkt_ip->ip_src; max++; opts[max].opt_type = IP_OPT_TS; opts[max].opt_len = IP_OPT_LEN + 1 + 1 + 4; opts[max].opt_data.ts.ptr = 5; opts[max].opt_data.ts.flg = IP_OPT_TS_TSONLY; max++; opts[max].opt_type = IP_OPT_ESEC; opts[max].opt_len = IP_OPT_LEN; max++; opts[max].opt_type = IP_OPT_CIPSO; opts[max].opt_len = IP_OPT_LEN; max++; opts[max].opt_type = IP_OPT_RR; opts[max].opt_len = IP_OPT_LEN + 1 + 4; opts[max].opt_data.rr.ptr = 4; max++; opts[max].opt_type = IP_OPT_SATID; opts[max].opt_len = IP_OPT_LEN + 2; max++; opts[max].opt_type = IP_OPT_SSRR; opts[max].opt_len = IP_OPT_LEN + 1 + 4; opts[max].opt_data.rr.ptr = 8; opts[max].opt_data.rr.iplist[0] = ping->pkt_ip->ip_src; max++; pcap_filter(ctx.pcap, "icmp and src %s and dst %s", addr_ntoa(&ctx.dst), addr_ntoa(&ctx.src)); ping->pkt_icmp_msg->echo.icmp_id = rand_uint16(ctx.rnd); for (i = 0; i < max; i++) { pkt = pkt_dup(ping); pkt->pkt_ip->ip_id = rand_uint16(ctx.rnd); pkt->pkt_icmp_msg->echo.icmp_seq = opts[i].opt_type; len = ip_add_option(pkt->pkt_ip, PKT_BUF_LEN - ETH_HDR_LEN + IP_HDR_LEN, IP_PROTO_IP, &opts[i], opts[i].opt_len); pkt->pkt_end += len; ip_checksum(pkt->pkt_ip, pkt->pkt_end - pkt->pkt_eth_data); send_pkt(pkt); } i = 0; for (tv = read_tv; (pkt = recv_pkt(&tv)) != NULL; tv = read_tv) { if (pkt->pkt_icmp->icmp_type == ICMP_ECHOREPLY && pkt->pkt_icmp_msg->echo.icmp_id == ping->pkt_icmp_msg->echo.icmp_id) { i = IP_OPT_NUMBER(pkt->pkt_icmp_msg->echo.icmp_seq); printf("%s ", optnames[i]); } } printf("%s\n", i ? "" : "none"); return (0); }