/* ping host , char *cmdstr*/ int run_ping6(int argc, char **argv) { pcs *pc = &vpc[pcid]; struct in6_addr ipaddr; struct packet *m = NULL; int i; char *p; char proto_seq[16]; int count = 5; printf("\n"); i = 2; for (i = 2; i < argc; i++) { if (!strcmp(argv[i], "-c")) { if ((i + 1) < argc && digitstring(argv[i + 1])) count = atoi(argv[i + 1]); break; } } if (vinet_pton6(AF_INET6, argv[1], &ipaddr) != 1) { printf("Invalid address: %s\n", argv[1]); return 0; } memcpy(pc->mscb.dip6.addr8, ipaddr.s6_addr, 16); if (pc->mscb.dip6.addr16[0] != IPV6_ADDR_INT16_ULL) memcpy(pc->mscb.sip6.addr8, pc->ip6.ip.addr8, 16); else memcpy(pc->mscb.sip6.addr8, pc->link6.ip.addr8, 16); /* ping self, discard options */ if (IP6EQ(&pc->mscb.sip6, &pc->mscb.dip6)) { i = 1; while (i < 6) { printf("%s icmp_seq=%d ttl=%d time=0.001 ms\n", argv[1], i++, pc->mscb.ttl); delay_ms(1); } return 1; } /* find destination */ p = (char*)nbDiscovery(pc, &pc->mscb.dip6); if (p == NULL) { printf("host (%s) not reachable\n", argv[1]); return 0; } memcpy(pc->mscb.dmac, p, 6); if (pc->mscb.proto == IPPROTO_ICMP) { pc->mscb.proto = IPPROTO_ICMPV6; strcpy(proto_seq, "icmp6_seq"); } else if (pc->mscb.proto == IPPROTO_TCP) { strcpy(proto_seq, "tcp6_seq"); } else if (pc->mscb.proto == IPPROTO_UDP) { strcpy(proto_seq, "udp6_seq"); } if (pc->mscb.proto == IPPROTO_TCP && pc->mscb.flags == 0) { i = 0; while ((i++ < count || count == -1) && !ctrl_c) { struct timeval ts0, ts; u_int usec; int k; int dsize = pc->mscb.dsize; int traveltime = 1; if (i > 1) delay_ms(pc->mscb.waittime); /* clear the input queue */ while ((m = deq(&pc->iq)) != NULL); /* connect the remote */ gettimeofday(&(ts), (void*)0); k = tcp_open(IPV6_VERSION); /* restore data size */ pc->mscb.dsize = dsize; gettimeofday(&(ts0), (void*)0); usec = (ts0.tv_sec - ts.tv_sec) * 1000000 + ts0.tv_usec - ts.tv_usec; if (k == 0) { printf("Connect %d@%s timeout\n", pc->mscb.dport, argv[1]); continue; } else if (k == 2) { char buf[INET6_ADDRSTRLEN + 1]; memset(buf, 0, sizeof(buf)); vinet_ntop6(AF_INET6, &pc->mscb.rdip6, buf, INET6_ADDRSTRLEN + 1); printf("*%s %s=%d ttl=%d time=%.3f ms", buf, proto_seq, i++, pc->mscb.rttl, usec / 1000.0); printf(" (ICMP type:%d, code:%d, %s)\n", pc->mscb.icmptype, pc->mscb.icmpcode, icmpTypeCode2String(6, pc->mscb.icmptype, pc->mscb.icmpcode)); continue; } else if (k == 3) { printf("Connect %d@%s RST returned\n", pc->mscb.dport, argv[1]); continue; } printf("Connect %d@%s seq=%d ttl=%d time=%.3f ms\n", pc->mscb.dport, argv[1], i, pc->mscb.rttl, usec / 1000.0); traveltime = 0.6 * usec / 1000; /* send data */ delay_ms(traveltime); gettimeofday(&(ts), (void*)0); k = tcp_send(IPV6_VERSION); if (k == 0) { printf("SendData %d@%s timeout\n", pc->mscb.dport, argv[1]); continue; } gettimeofday(&(ts0), (void*)0); usec = (ts0.tv_sec - ts.tv_sec) * 1000000 + ts0.tv_usec - ts.tv_usec; printf("SendData %d@%s seq=%d ttl=%d time=%.3f ms\n", pc->mscb.dport, argv[1], i, pc->mscb.rttl, usec / 1000.0); /* close */ if (k != 2) delay_ms(traveltime); gettimeofday(&(ts), (void*)0); k = tcp_close(IPV6_VERSION); if (k == 0) { printf("Close %d@%s timeout\n", pc->mscb.dport, argv[1]); continue; } gettimeofday(&(ts0), (void*)0); usec = (ts0.tv_sec - ts.tv_sec) * 1000000 + ts0.tv_usec - ts.tv_usec; printf("Close %d@%s seq=%d ttl=%d time=%.3f ms\n", pc->mscb.dport, argv[1], i, pc->mscb.rttl, usec / 1000.0); } } else { i = 1; while ((i <= count || count == -1) && !ctrl_c) { struct packet *p; struct timeval tv; u_int usec; int respok = 0; pc->mscb.sn = i; pc->mscb.timeout = time_tick; m = packet6(&pc->mscb); if (m == NULL) { printf("out of memory\n"); return false; } gettimeofday(&(tv), (void*)0); enq(&pc->oq, m); while (!timeout(tv, pc->mscb.waittime) && !ctrl_c) { delay_ms(1); respok = 0; while ((p = deq(&pc->iq)) != NULL && !respok && !timeout(tv, pc->mscb.waittime) && !ctrl_c) { pc->mscb.icmptype = pc->mscb.icmpcode = 0; respok = response6(p, &pc->mscb); usec = (p->ts.tv_sec - tv.tv_sec) * 1000000 + p->ts.tv_usec - tv.tv_usec; del_pkt(p); if (respok == 0) continue; tv.tv_sec = 0; if ((pc->mscb.proto == IPPROTO_ICMPV6 && pc->mscb.icmptype == ICMP6_ECHO_REPLY) || (pc->mscb.proto == IPPROTO_UDP && respok == IPPROTO_UDP)|| (pc->mscb.proto == IPPROTO_TCP && respok == IPPROTO_TCP)) { printf("%s %s=%d ttl=%d time=%.3f ms\n", argv[1], proto_seq, i++, pc->mscb.rttl, usec / 1000.0); break; } if (respok == IPPROTO_ICMPV6) { char buf[INET6_ADDRSTRLEN + 1]; memset(buf, 0, sizeof(buf)); vinet_ntop6(AF_INET6, &pc->mscb.rdip6, buf, INET6_ADDRSTRLEN + 1); printf("*%s %s=%d ttl=%d time=%.3f ms", buf, proto_seq, i++, pc->mscb.rttl, usec / 1000.0); printf(" (ICMP type:%d, code:%d, %s)\n", pc->mscb.icmptype, pc->mscb.icmpcode, icmpTypeCode2String(6, pc->mscb.icmptype, pc->mscb.icmpcode)); break; } } } if (!respok && !ctrl_c) printf("%s %s=%d timeout\n", argv[1], proto_seq, i++); } } return 1; }
static void dmp_ip6(void *dat) { ip6hdr *iph = (ip6hdr *)dat; icmp6hdr *icmp = (icmp6hdr *)(iph + 1); udphdr *uh = (udphdr *)(iph + 1); tcphdr *th = (tcphdr *)(iph + 1); u_char *data; char *p; printf("IPv6, flowid: %x, length: %d, ttl: %d\n", ntohl(iph->ip6_flow & IPV6_FLOWLABEL_MASK), ntohs(iph->ip6_plen), iph->ip6_hlim); p = ip6tostr(iph->src.addr8); printf("Address: %s -> ", p); p = ip6tostr(iph->dst.addr8); printf("%s\n", p); if (iph->ip6_nxt == IPPROTO_ICMPV6) { printf("Proto: icmp, "); printf("type: %d, ", icmp->type); printf("code: %d", icmp->code); if (icmp->type == ICMP6_PACKET_TOO_BIG) printf(", mtu: %d", ntohl(icmp->icmp6_mtu)); printf("\n"); printf("Desc: %s\n", icmpTypeCode2String(6, icmp->type, icmp->code)); } else if (iph->ip6_nxt == IPPROTO_UDP) { printf("Proto: udp, len: %d, sum: %4.4x\n", ntohs(uh->len), ntohs(uh->cksum)); printf("Port: %d -> %d\n", ntohs(uh->sport), ntohs(uh->dport)); if (ntohs(uh->sport) == ntohs(uh->dport) && ntohs(uh->sport) == 521 && iph->dst.addr32[0] == IPV6_ADDR_INT32_MLL && iph->dst.addr32[1] == 0 && iph->dst.addr32[2] == 0 && iph->dst.addr32[3] == 0x09000000) { data = (u_char *)(uh + 1); printf("Desc: RIP%d %s message\n", *(data + 1), (*data == 1) ? "request" : "response"); } } else if (iph->ip6_nxt == IPPROTO_TCP) { printf("Proto: tcp, sum: %4.4x, ack: %8.8x, seq: %8.8x, ", ntohs(th->th_sum), ntohl(th->th_ack), ntohl(th->th_seq)); printf("flags: "); if (th->th_flags & TH_FIN) printf("F"); if (th->th_flags & TH_SYN) printf("S"); if (th->th_flags & TH_RST) printf("R"); if (th->th_flags & TH_PUSH) printf("P"); if (th->th_flags & TH_ACK) printf("A"); if (th->th_flags & TH_URG) printf("U"); if (th->th_flags & TH_ECE) printf("E"); if (th->th_flags & TH_CWR) printf("C"); printf("\n"); printf("Port: %d -> %d\n", ntohs(th->th_sport), ntohs(th->th_dport)); } }
int run_tracert6(int argc, char **argv) { int i, j; struct packet *m; pcs *pc = &vpc[pcid]; u_char *dmac; int ok = 0; struct in6_addr ipaddr; ip6 ip; int pktnum = 3; int count = 99; printf("\n"); if (argc < 2) { printf("incompleted command.\n"); return 0; } i = 2; for (i = 2; i < argc; i++) { if (!strcmp(argv[i], "-c")) { if ((i + 1) < argc && digitstring(argv[i + 1])) count = atoi(argv[i + 1]); break; } } if (count == 99 && digitstring(argv[argc - 1])) count = atoi(argv[argc - 1]); if (optind < argc && digitstring(argv[optind])) count = atoi(argv[optind]); if (count < 1 || count > 64) count = 64; if (vinet_pton6(AF_INET6, argv[1], &ipaddr) != 1) { printf("Invalid address: %s\n", argv[1]); return 0; } memcpy(pc->mscb.dip6.addr8, ipaddr.s6_addr, 16); if (pc->mscb.dip6.addr16[0] != IPV6_ADDR_INT16_ULL) memcpy(pc->mscb.sip6.addr8, pc->ip6.ip.addr8, 16); else memcpy(pc->mscb.sip6.addr8, pc->link6.ip.addr8, 16); dmac = nbDiscovery(pc, &ip); if (dmac == NULL) { printf("host (%s) not reachable\n", argv[1]); return 0; } memcpy(pc->mscb.dmac, dmac, 6); printf("trace to %s, %d hops max\n", argv[1], count); /* send the udp packets */ i = 1; while (i <= count && !ctrl_c) { struct packet *p; struct timeval tv; u_int usec; int k; printf("%2d ", i); for (j = 0; j < pktnum && !ctrl_c; j++) { pc->mscb.ttl = i; m = packet6(&pc->mscb); if (m == NULL) { printf("out of memory\n"); return 0; } gettimeofday(&(tv), (void*)0); enq(&pc->oq, m); k = 0; while (!timeout(tv, pc->mscb.waittime) && !ctrl_c) { delay_ms(1); ok = 0; while ((p = deq(&pc->iq)) != NULL && !ok && !timeout(tv, pc->mscb.waittime) && !ctrl_c) { ok = response6(p, &pc->mscb); usec = (p->ts.tv_sec - tv.tv_sec) * 1000000 + p->ts.tv_usec - tv.tv_usec; del_pkt(p); if (pc->mscb.icmptype == ICMP6_TIME_EXCEEDED || IP6EQ(&(pc->mscb.dip6), &(pc->mscb.rdip6))) { if (j == 0) { char buf[128]; memcpy(ipaddr.s6_addr, pc->mscb.rdip6.addr8, 16); memset(buf, 0, 128); vinet_ntop6(AF_INET6, &ipaddr, buf, INET6_ADDRSTRLEN + 1); printf("%s ", buf); } printf(" %.3f ms", usec / 1000.0);fflush(stdout); tv.tv_sec = 0; break; } else if (pc->mscb.icmptype == ICMP6_DST_UNREACH || pc->mscb.icmptype == ICMP6_DST_UNREACH_NOPORT) { if (j == 0) { char buf[128]; memcpy(ipaddr.s6_addr, pc->mscb.rdip6.addr8, 16); memset(buf, 0, 128); vinet_ntop6(AF_INET6, &ipaddr, buf, INET6_ADDRSTRLEN + 1); printf("*%s %.3f ms (ICMP type:%d, code:%d, %s)\n", buf, usec / 1000.0, pc->mscb.icmptype, pc->mscb.icmpcode, icmpTypeCode2String(6, pc->mscb.icmptype, pc->mscb.icmpcode)); } tv.tv_sec = 0; return 1; } } k++; } if (!ok && !ctrl_c) printf(" *"); } printf("\n"); i++; if (pc->mscb.icmptype == ICMP6_DST_UNREACH) break; } return 1; }
static void dmp_ip(void *dat) { iphdr *iph = (iphdr *)dat; icmphdr *icmp = (icmphdr *)(iph + 1); udphdr *uh = (udphdr *)(iph + 1); tcphdr *th = (tcphdr *)(iph + 1); u_char *data; struct in_addr in; printf("IPv%d, id: %x, length: %d, ttl: %d, sum: %4.4x", iph->ver, ntohs(iph->id), ntohs(iph->len), iph->ttl, ntohs(iph->cksum)); if ((ntohs(iph->frag) & IP_DF) == IP_DF) printf(", DF"); if (ntohs(iph->frag) & (IP_MF | IP_OFFMASK)) printf(", MF/%d", (ntohs(iph->frag) << 3) & 0xffff); in.s_addr = iph->sip; printf("\nAddress: %s -> ", inet_ntoa(in)); in.s_addr = iph->dip; printf("%s\n", inet_ntoa(in)); if ((ntohs(iph->frag) << 3) & 0xffff) return; if (iph->proto == IPPROTO_ICMP) { printf("Proto: icmp, "); printf("type: %d, ", icmp->type); printf("code: %d\n", icmp->code); printf("Desc: %s\n", icmpTypeCode2String(iph->ver, icmp->type, icmp->code)); } else if (iph->proto == IPPROTO_UDP) { printf("Proto: udp, len: %d, sum: %4.4x\n", ntohs(uh->len), ntohs(uh->cksum)); printf("Port: %d -> %d\n", ntohs(uh->sport), ntohs(uh->dport)); if (ntohs(uh->sport) == 53 || ntohs(uh->dport) == 53) return dmp_dns(dat); if (ntohs(uh->sport) == ntohs(uh->dport) && ntohs(uh->sport) == 520 && iph->dip == 0x90000e0) { data = (u_char *)(uh + 1); printf("Desc: RIP%d %s message\n", *(data + 1), (*data == 1) ? "request" : "response"); } } else if (iph->proto == IPPROTO_TCP) { printf("Proto: tcp, sum: %4.4x, ack: %8.8x, seq: %8.8x, ", ntohs(th->th_sum), ntohl(th->th_ack), ntohl(th->th_seq)); printf("flags: "); if (th->th_flags & TH_FIN) printf("F"); if (th->th_flags & TH_SYN) printf("S"); if (th->th_flags & TH_RST) printf("R"); if (th->th_flags & TH_PUSH) printf("P"); if (th->th_flags & TH_ACK) printf("A"); if (th->th_flags & TH_URG) printf("U"); if (th->th_flags & TH_ECE) printf("E"); if (th->th_flags & TH_CWR) printf("C"); printf("\n"); printf("Port: %d -> %d\n", ntohs(th->th_sport), ntohs(th->th_dport)); } }