pingのデフォルト送信先
ネットワークの導通を確認する場合には、まずはデフォルトゲートウェイにpingを打ってみると思います。それならば、引数をつけずにpingを実行したら、デフォルトゲートウェイ宛てにpingを送信してくれてもよさそうなものです。ということで、NetBSD-2.0.2のping.c(1.75)に対するpatchを作ってみました。kmemまわりを使ってデフォルトゲートウェイを求める処理が面倒なので、popen(3)を使って手を抜いています(^^;;
diff -ruN ping.orig/ping.c ping/ping.c --- ping.orig/ping.c 2005-10-09 21:53:05.000000000 +0900 +++ ping/ping.c 2005-10-23 06:06:56.000000000 +0900 @@ -241,6 +241,7 @@ static void gethost(const char *, const char *, struct sockaddr_in *, char *, int); static void usage(void); +static int get_default_gw_addr(char *, size_t); int @@ -260,7 +261,8 @@ char *policy_out = NULL; #endif #endif - + char *addrp; + char addr[128]; setprogname(argv[0]); @@ -426,15 +428,23 @@ } if (hostind == 0) { - if (optind != argc-1) - usage(); - else + if (optind != argc-1) { + if (get_default_gw_addr(addr, sizeof addr) != 0) + usage(); + addrp = addr; + } else { hostind = optind; + addrp = argv[hostind]; + } + } else if (hostind >= argc - 1) { + if (get_default_gw_addr(addr, sizeof addr) != 0) + usage(); + addrp = addr; + } else { + addrp = argv[hostind]; } - else if (hostind >= argc - 1) - usage(); - gethost("", argv[hostind], &whereto, hostname, sizeof(hostname)); + gethost("", addrp, &whereto, hostname, sizeof(hostname)); if (IN_MULTICAST(ntohl(whereto.sin_addr.s_addr))) pingflags |= F_MCAST; if (!(pingflags & F_SOURCE_ROUTE)) @@ -1850,3 +1860,27 @@ getprogname()); exit(1); } + +static int +get_default_gw_addr(char *addr, size_t len) +{ + char buf[128]; + size_t n; + + FILE *p = popen("/usr/bin/netstat -rn " + "| /usr/bin/grep default " + "| /usr/bin/awk '{print $2}'", + "r"); + + if (fgets(buf, sizeof buf, p) == NULL) + return -1; + pclose(p); + + if ((n = strlen(buf)) == 0) + return -2; + + buf[n - 1] = '\0'; + strlcpy(addr, buf, len); + + return 0; +}