📄 netsimul.c
字号:
ntohs(udp->check)); if (current_expect && strcmp(expect_parse.name, "udp") == 0) { while (parse_get_next(&expect_parse) == 1) { if (strcmp(expect_parse.field, "dstport") == 0) { if (dyn_atoi(expect_parse.value) != ntohs(udp->dest)) { printf("EXPECT: dstport does not " "match\n"); current_expect = 0; break; } } else if (strcmp(expect_parse.field, "srcport") == 0) { if (dyn_atoi(expect_parse.value) != ntohs(udp->source)) { printf("EXPECT: srcport does not " "match\n"); current_expect = 0; break; } } else { printf("Unknown expect field udp::%s\n", expect_parse.field); current_expect = 0; break; } } if (current_expect) { if (parse_init(&expect_parse, expect_parse.next) == 0) { printf("Expected packet received.\n"); current_expect = 0; expect_received = 1; } } } parse_msg(buf + sizeof(struct udphdr), len - sizeof(struct udphdr), &ext); if (current_expect && strcmp(expect_parse.name, "rep") == 0 && ext.rep != NULL) { while (parse_get_next(&expect_parse) == 1) { if (strcmp(expect_parse.field, "home") == 0) { inet_aton(expect_parse.value, &addr); if (addr.s_addr != ext.rep->home_addr.s_addr) { printf("EXPECT: home_addr does not " "match\n"); current_expect = 0; break; } } else if (strcmp(expect_parse.field, "ha") == 0) { inet_aton(expect_parse.value, &addr); if (addr.s_addr != ext.rep->ha_addr.s_addr) { printf("EXPECT: ha_addr does not " "match\n"); current_expect = 0; break; } } else if (strcmp(expect_parse.field, "lifetime") == 0) { if (dyn_atoi(expect_parse.value) != ntohs(ext.rep->lifetime)) { printf("EXPECT: lifetime does not " "match\n"); current_expect = 0; break; } } else if (strcmp(expect_parse.field, "code") == 0) { if (dyn_atoi(expect_parse.value) != ext.rep->code) { printf("EXPECT: code does not " "match\n"); current_expect = 0; break; } } else if (strcmp(expect_parse.field, "matchid") == 0) { struct saved_id *tmp = saved_ids; int num = dyn_atoi(expect_parse.value); while (tmp != NULL) { if (tmp->num == num && (ext.rep->id[0] != tmp->id[0] || ext.rep->id[1] != tmp->id[1])) { printf("EXPECT: id does not " "match\n"); current_expect = 0; break; } tmp = tmp->next; } if (!current_expect) break; } else if (strcmp(expect_parse.field, "id0") == 0) { if (get_id(expect_parse.value) != ext.rep->id[0]) { printf("EXPECT: id0 does not match\n"); current_expect = 0; break; } } else if (strcmp(expect_parse.field, "id1") == 0) { if (get_id(expect_parse.value) != ext.rep->id[1]) { printf("EXPECT: id1 does not match\n"); current_expect = 0; break; } } else { printf("Unknown expect field rep::%s\n", expect_parse.field); current_expect = 0; break; } } if (current_expect) { if (parse_init(&expect_parse, expect_parse.next) == 0) { printf("Expected packet received.\n"); current_expect = 0; expect_received = 1; } } } else if (current_expect && strcmp(expect_parse.name, "req") == 0 && ext.req != NULL) { while (parse_get_next(&expect_parse) == 1) { if (strcmp(expect_parse.field, "home") == 0) { inet_aton(expect_parse.value, &addr); if (addr.s_addr != ext.req->home_addr.s_addr) { printf("EXPECT: home_addr does not " "match\n"); current_expect = 0; break; } } else if (strcmp(expect_parse.field, "ha") == 0) { inet_aton(expect_parse.value, &addr); if (addr.s_addr != ext.req->ha_addr.s_addr) { printf("EXPECT: ha_addr does not " "match\n"); current_expect = 0; break; } } else if (strcmp(expect_parse.field, "coa") == 0) { inet_aton(expect_parse.value, &addr); if (addr.s_addr != ext.req->co_addr.s_addr) { printf("EXPECT: co_addr does not " "match\n"); current_expect = 0; break; } } else if (strcmp(expect_parse.field, "lifetime") == 0) { if (dyn_atoi(expect_parse.value) != ntohs(ext.req->lifetime)) { printf("EXPECT: lifetime does not " "match\n"); current_expect = 0; break; } } else if (strcmp(expect_parse.field, "opts") == 0) { if (dyn_atoi(expect_parse.value) != ext.req->opts) { printf("EXPECT: opts does not " "match\n"); current_expect = 0; break; } } else if (strcmp(expect_parse.field, "matchid") == 0) { struct saved_id *tmp = saved_ids; int num = dyn_atoi(expect_parse.value); while (tmp != NULL) { if (tmp->num == num && (ext.req->id[0] != tmp->id[0] || ext.req->id[1] != tmp->id[1])) { printf("EXPECT: id does not " "match\n"); current_expect = 0; break; } tmp = tmp->next; } if (!current_expect) break; } else { printf("Unknown expect field req::%s\n", expect_parse.field); current_expect = 0; break; } } if (current_expect) { if (parse_init(&expect_parse, expect_parse.next) == 0) { printf("Expected packet received.\n"); current_expect = 0; expect_received = 1; } } } while (current_expect) { if (strcmp(expect_parse.name, "mhauth") == 0) check_auth(ext.start, ext.mh_auth); else if (strcmp(expect_parse.name, "fhauth") == 0) check_auth(ext.start, ext.fh_auth); else if (strcmp(expect_parse.name, "mfauth") == 0) check_auth(ext.start, ext.mf_auth); else if (strcmp(expect_parse.name, "no-encaps") == 0) check_no_ext("encaps", ext.encaps_del); else if (strcmp(expect_parse.name, "no-mhauth") == 0) check_no_ext("mhauth", ext.mh_auth); else if (strcmp(expect_parse.name, "no-fhauth") == 0) check_no_ext("fhauth", ext.fh_auth); else if (strcmp(expect_parse.name, "no-mfauth") == 0) check_no_ext("mfauth", ext.mf_auth); else { printf("EXPECT: unknown extension '%s'\n", expect_parse.name); break; } } if (ext.req != NULL) { prev_id[0] = ext.req->id[0]; prev_id[1] = ext.req->id[1]; } if (ext.rep != NULL) { prev_id[0] = ext.rep->id[0]; prev_id[1] = ext.rep->id[1]; }}void process_gre(char *buf, int len){ printf("\tGRE\n");}void process_ip(char *buf, int len){ struct iphdr *ip; int left; char *next; struct in_addr addr; if (len < sizeof(struct iphdr)) return; ip = (struct iphdr *) buf; printf("\tIP: ttl=%i protocol=%i saddr=%s", ip->ttl, ip->protocol, inet_ntoa(*(struct in_addr *)&ip->saddr)); printf(" daddr=%s\n", inet_ntoa(*(struct in_addr *)&ip->daddr)); if (current_expect && strcmp(expect_parse.name, "ip") == 0) { while (parse_get_next(&expect_parse) == 1) { if (strcmp(expect_parse.field, "dstip") == 0) { inet_aton(expect_parse.value, &addr); if (addr.s_addr != ip->daddr) { printf("EXPECT: dstip does not " "match\n"); current_expect = 0; break; } } else if (strcmp(expect_parse.field, "srcip") == 0) { inet_aton(expect_parse.value, &addr); if (addr.s_addr != ip->saddr) { printf("EXPECT: srcip does not " "match\n"); current_expect = 0; break; } } else if (strcmp(expect_parse.field, "proto") == 0) { if (dyn_atoi(expect_parse.value) != ip->protocol) { printf("EXPECT: proto does not " "match\n"); current_expect = 0; break; } } else if (strcmp(expect_parse.field, "ttl") == 0) { if (dyn_atoi(expect_parse.value) != ip->ttl) { printf("EXPECT: ttl does not " "match\n"); current_expect = 0; break; } } else { printf("Unknown expect field ip::%s\n", expect_parse.field); current_expect = 0; break; } } if (current_expect) { if (parse_init(&expect_parse, expect_parse.next) == 0) { printf("Expected packet received.\n"); current_expect = 0; expect_received = 1; } } } left = len - sizeof(struct iphdr); next = buf + sizeof(struct iphdr); switch (ip->protocol) { case IPPROTO_ICMP: process_icmp(next, left); break; case IPPROTO_UDP: process_udp(next, left); break; case IPPROTO_IPIP: process_ip(next, left); break; case IPPROTO_GRE: process_gre(next, left); break; default: printf("\tUnknown IP protocol.\n"); break; }}struct arphdr_ether { unsigned char ar_sha[ETH_ALEN]; /* Sender hardware address. */ unsigned char ar_sip[4]; /* Sender IP address. */ unsigned char ar_tha[ETH_ALEN]; /* Target hardware address. */ unsigned char ar_tip[4]; /* Target IP address. */};void process_arp(int s, char *buf, int len){ struct ethhdr *eth; struct arphdr *arp; struct arphdr_ether *arp_eth; int arplen; arplen = sizeof(struct ethhdr) + sizeof(struct arphdr) + sizeof(struct arphdr_ether); if (len != arplen) { fprintf(stderr, "process_arp: len=%i != arplen=%i\n", len, arplen); return; } eth = (struct ethhdr *) buf; arp = (struct arphdr *) (eth + 1); arp_eth = (struct arphdr_ether *) (arp + 1); printf("\tARP: ar_hrd=%i ar_pro=%i ar_hln=%i ar_pln=%i ar_op=%i\n", ntohs(arp->ar_hrd), ntohs(arp->ar_pro), arp->ar_hln, arp->ar_pln, ntohs(arp->ar_op)); printf("\tARP(ether): ar_sha=%s ar_sip=%s\n", ether_hwtoa(arp_eth->ar_sha), inet_ntoa(*(struct in_addr *)&arp_eth->ar_sip)); printf("\t\tar_tha=%s ar_tip=%s\n", ether_hwtoa(arp_eth->ar_tha), inet_ntoa(*(struct in_addr *)&arp_eth->ar_tip)); if (ntohs(arp->ar_hrd) != ARPHRD_ETHER || ntohs(arp->ar_pro) != ETH_P_IP || arp->ar_hln != ETH_ALEN || arp->ar_pln != 4) { printf("\tUnknown address type\n"); return; } if (ntohs(arp->ar_op) == ARPOP_REQUEST && arp_eth->ar_tha[0] == 0 && arp_eth->ar_tha[1] == 0 && arp_eth->ar_tha[2] == 0 && arp_eth->ar_tha[3] == 0 && arp_eth->ar_tha[4] == 0 && arp_eth->ar_tha[5] == 0 && memcmp(arp_eth->ar_tip, arp_eth->ar_sip, 4) != 0) { char tmp[4]; arp->ar_op = htons(ARPOP_REPLY); memcpy(eth->h_dest, eth->h_source, 6); ether_atohw("00:12:34:56:78:90", eth->h_source); memcpy(arp_eth->ar_tha, arp_eth->ar_sha, 6); memcpy(tmp, arp_eth->ar_sip, 4); memcpy(arp_eth->ar_sip, arp_eth->ar_tip, 4); memcpy(arp_eth->ar_tip, tmp, 4); ether_atohw("00:12:34:56:78:90", arp_eth->ar_sha); printf("\tReplying to ARP request\n"); write(s, buf, arplen); }}static void check_recv_eth(struct parse_data *parse, const char *dev, struct ethhdr *eth){ while (parse_get_next(parse) == 1) { unsigned char tmphw[ETH_ALEN]; if (strcmp(parse->field, "srchw") == 0) { if (ether_atohw(parse->value, tmphw) < 0) fprintf(stderr, "Invalid srchw='%s'\n", parse->value); if (memcmp(tmphw, eth->h_source, ETH_ALEN) != 0) { printf("EXPECT: srchw does not match\n"); current_expect = 0; break; } } else if (strcmp(parse->field, "dsthw") == 0) { if (ether_atohw(parse->value, tmphw) < 0) fprintf(stderr, "Invalid dsthw='%s'\n", parse->value); if (memcmp(tmphw, eth->h_dest, ETH_ALEN) != 0) { printf("EXPECT: dsthw does not match\n"); current_expect = 0; break; } } else if (strcmp(parse->field, "proto") == 0) { if (htons(dyn_atoi(parse->value)) != eth->h_proto) { printf("EXPECT: proto does not match\n"); current_expect = 0; break; } } else if (strcmp(parse->field, "dev") == 0) { if (strcmp(parse->value, dev) != 0) { printf("EXPECT: dev does not match\n"); current_expect = 0; break; } } else { fprintf(stderr, "Unknown expect option '%s', " "value '%s'\n", parse->field, parse->value); current_expect = 0; break; } } if (current_expect) { if (parse_init(parse, parse->next) == 0) { printf("Expected packet received.\n"); current_expect = 0; expect_received = 1; } }}void process(int fd, const char *dev){ unsigned char buf[2000]; int l, res; struct timeval tv; struct ethhdr *eth; gettimeofday(&tv, NULL); printf("TIME=%i.%06i %s", (int) tv.tv_sec, (int) tv.tv_usec, ctime((time_t *) &tv.tv_sec)); l = read(fd, buf, sizeof(buf)); printf("Received %i bytes from %s:\n", l, dev); if (l < 0) { perror("read"); return; } eth = (struct ethhdr *) buf; printf("\tEthernet: dst=%s ", ether_hwtoa(eth->h_dest)); printf("src=%s proto=%04X\n", ether_hwtoa(eth->h_source), ntohs(eth->h_proto)); current_expect = current_cmd_expect; if (current_expect) { strncpy(expect_buf, current_command, PARSE_BUF_SIZE); res = parse_init(&expect_parse, expect_buf); assert(res == 1 && (strcmp(expect_parse.name, "expect") == 0 || strcmp(expect_parse.name, "reject") == 0)); check_recv_eth(&expect_parse, dev, eth); } switch (ntohs(eth->h_proto)) { case ETH_P_IP: process_ip((char *) (eth + 1), l - sizeof(struct ethhdr)); break; case ETHERTYPE_ARP: process_arp(fd, (char *) eth, l); break; default: printf("\tUnknown Ethernet Protocol ID\n"); break; }}int main(int argc, char *argv[]){ char dev[IFNAMSIZ + 1]; FILE *f; char buf[PARSE_BUF_SIZE]; opt_debug = 1; if (argc < 2) { fprintf(stderr, "netsimul <command file>\n"); exit(-1); } f = fopen(argv[1], "r"); if (f == NULL) { fprintf(stderr, "Could not open command file '%s'\n", argv[1]); exit(-1); } dynamics_strlcpy(dev, "tap0", sizeof(dev)); fd[0] = tun_alloc(dev); if (fd[0] < 0) { fprintf(stderr, "Could not initialize tap0\n"); exit(-1); } dynamics_strlcpy(dev, "tap1", sizeof(dev)); fd[1] = tun_alloc(dev); if (fd[1] < 0) { fprintf(stderr, "Could not initialize tap1\n"); exit(-1); } dynamics_strlcpy(dev, "tap2", sizeof(dev)); fd[2] = tun_alloc(dev); if (fd[2] < 0) { fprintf(stderr, "Could not initialize tap2\n"); exit(-1); } max_fd = fd[1] > fd[0] ? fd[1] : fd[0]; if (fd[2] > max_fd) max_fd = fd[2]; max_fd++; system("/sbin/ifconfig tap0 hw ether 00:00:00:00:00:01 " "192.168.250.1 up"); system("/sbin/ifconfig tap1 hw ether 00:00:00:00:00:02 " "192.168.251.1 up"); system("/sbin/ifconfig tap2 hw ether 00:00:00:00:00:03 " "192.168.252.1 up"); system("/sbin/ip ro add 192.168.150.0/24 dev tap0"); gettimeofday(&start, NULL); printf("Simulation for command file '%s' started at %lu.%06lu\n", argv[1], start.tv_sec, start.tv_usec); while (fgets(buf, sizeof(buf), f)) { char *pos = buf; while (is_space(*pos)) pos++; if (*pos == ';' || *pos == '\0') continue; /* skip comments and empty lines */ handle(pos); } fclose(f); if (expect_error) { printf("FAIL: number of expected packets not received: %i\n", expect_error); } if (reject_error) { printf("FAIL: number of rejected packets received: %i\n", reject_error); } return (expect_error || reject_error);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -