void icmpIpIn(icmpip_hdr* packet) { // check ICMP type switch(packet->icmp.type) { case ICMP_TYPE_ECHOREQUEST: // echo request icmpEchoRequest(packet); break; default: break; } }
/** * @ingroup shell * * Shell command (ping). * @param nargs number of arguments in args array * @param args array of arguments * @return OK for success, SYSERR for syntax error */ shellcmd xsh_ping(int nargs, char *args[]) { int i = 0; int interval = 1000, count = 10, recv = 0, echoq = 0; ulong rtt = 0, min = 0, max = 0, total = 0; ulong startsec = 0, startms = 0; struct netaddr target; struct packet *pkt = NULL; char str[50]; /* Output help, if '--help' argument was supplied */ if (nargs == 2 && strncmp(args[1], "--help", 7) == 0) { printf("Usage: ping <IP>\n\n"); printf("Description:\n"); printf("\tSend ICMP echo requests to network hosts\n"); printf("Options:\n"); printf("\t<IP>\t\tIP address\n"); printf("\t-c count\tstop after sending count packets\n"); printf ("\t-i interval\tsleep interval milliseconds between pings\n"); printf("\t--help\t\tdisplay this help and exit\n"); return OK; } /* Check for correct number of arguments */ if (nargs < 2) { fprintf(stderr, "ping: too few arguments\n"); fprintf(stderr, "Try 'ping --help' for more information\n"); return SHELL_ERROR; } i = 1; while (i < nargs) { if (0 == strncmp(args[i], "-c", 3)) { i++; if (i < nargs) { count = atoi(args[i]); } else { fprintf(stderr, "ping: -c requires integer argument\n"); return SHELL_ERROR; } } else if (0 == strncmp(args[i], "-i", 3)) { i++; if (i < nargs) { interval = atoi(args[i]); } else { fprintf(stderr, "ping: -i requires integer argument\n"); return SHELL_ERROR; } } else if (SYSERR == dot2ipv4(args[i], &target)) { fprintf(stderr, "ping: %s is not a valid IPv4 address.\n", args[i]); return SHELL_ERROR; } i++; } netaddrsprintf(str, &target); if (0 == strncmp(str, "ERROR", 6)) { fprintf(stderr, "ping: destination IP address required.\n"); return SHELL_ERROR; } printf("PING %s\n", str); echoq = echoQueueAlloc(); if (SYSERR == echoq) { printf("...No free echo queues!\n"); return SHELL_ERROR; } startsec = clktime; startms = clkticks; for (i = 0; i < count; i++) { // Send ping packet if (SYSERR == icmpEchoRequest(&target, gettid(), i)) { printf("...Failed to reach %s\n", str); return SHELL_ERROR; } sleep(interval); if (NOMSG != recvclr()) { // pick reply packets off of the queue pkt = echoQueueGet(echoq); while ((NULL != (ulong)pkt) && (SYSERR != (ulong)pkt)) { rtt = echoTripTime(pkt); total += rtt; if ((rtt < min) || (0 == min)) { min = rtt; } if (rtt > max) { max = rtt; } echoPrintPkt(pkt, rtt); netFreebuf(pkt); recv++; pkt = echoQueueGet(echoq); } } } echoQueueDealloc(echoq); netaddrsprintf(str, &target); printf("--- %s ping statistics ---\n", str); printf("%d packets transmitted, %d received,", count, recv); printf(" %d%% packet loss,", (count - recv) * 100 / count); printf(" time %dms\n", (clktime - startsec) * 1000 + ((clkticks - startms) * 1000) / CLKTICKS_PER_SEC); printf("rtt min/avg/max = %d.%03d/", min / 1000, min % 1000); if (0 != recv) { printf("%d.%03d/", (total / recv) / 1000, (total / recv) % 1000); } else { printf("-/"); } printf("%d.%03d ms\n", max / 1000, max % 1000); return SHELL_OK; }