svn commit: trunk/busybox: include networking

vda at busybox.net vda at busybox.net
Sat Sep 2 16:17:30 UTC 2006


Author: vda
Date: 2006-09-02 09:17:30 -0700 (Sat, 02 Sep 2006)
New Revision: 16029

Log:
ping: implement -I option


Modified:
   trunk/busybox/include/usage.h
   trunk/busybox/networking/ping.c
   trunk/busybox/networking/ping6.c


Changeset:
Modified: trunk/busybox/include/usage.h
===================================================================
--- trunk/busybox/include/usage.h	2006-09-02 16:16:23 UTC (rev 16028)
+++ trunk/busybox/include/usage.h	2006-09-02 16:17:30 UTC (rev 16029)
@@ -2272,6 +2272,7 @@
 	"Options:\n" \
 	"\t-c COUNT\tSend only COUNT pings\n" \
 	"\t-s SIZE\t\tSend SIZE data bytes in packets (default=56)\n" \
+	"\t-I IPADDR\tUse IPADDR as source address\n" \
 	"\t-q\t\tQuiet mode, only displays output at start\n" \
 	"\t\t\tand when finished"
 #endif

Modified: trunk/busybox/networking/ping.c
===================================================================
--- trunk/busybox/networking/ping.c	2006-09-02 16:16:23 UTC (rev 16028)
+++ trunk/busybox/networking/ping.c	2006-09-02 16:17:30 UTC (rev 16029)
@@ -155,6 +155,7 @@
 #else /* ! CONFIG_FEATURE_FANCY_PING */
 /* full(er) version */
 static struct sockaddr_in pingaddr;
+static struct sockaddr_in sourceaddr;
 static int pingsock = -1;
 static int datalen; /* intentionally uninitialized to work around gcc bug */
 
@@ -264,16 +265,15 @@
 
 	gettimeofday(&tv, NULL);
 
-	/* check IP header */
-	iphdr = (struct iphdr *) buf;
-	hlen = iphdr->ihl << 2;
 	/* discard if too short */
 	if (sz < (datalen + ICMP_MINLEN))
 		return;
 
+	/* check IP header */
+	iphdr = (struct iphdr *) buf;
+	hlen = iphdr->ihl << 2;
 	sz -= hlen;
 	icmppkt = (struct icmp *) (buf + hlen);
-
 	if (icmppkt->icmp_id != myid)
 		return;				/* not our ping */
 
@@ -329,12 +329,17 @@
 
 	pingsock = create_icmp_socket();
 
+	if (sourceaddr.sin_addr.s_addr) {
+		if (bind(pingsock, (struct sockaddr*)&sourceaddr, sizeof(sourceaddr)) == -1)
+			bb_error_msg_and_die("could not bind to address");
+	}
+
 	memset(&pingaddr, 0, sizeof(struct sockaddr_in));
 
 	pingaddr.sin_family = AF_INET;
 	hostent = xgethostbyname(host);
 	if (hostent->h_addrtype != AF_INET)
-		bb_error_msg_and_die("unknown address type; only AF_INET is currently supported.");
+		bb_error_msg_and_die("unknown address type; only AF_INET is currently supported");
 
 	memcpy(&pingaddr.sin_addr, hostent->h_addr, sizeof(pingaddr.sin_addr));
 
@@ -348,10 +353,14 @@
 	setsockopt(pingsock, SOL_SOCKET, SO_RCVBUF, (char *) &sockopt,
 			   sizeof(sockopt));
 
-	printf("PING %s (%s): %d data bytes\n",
-		   hostent->h_name,
-		   inet_ntoa(*(struct in_addr *) &pingaddr.sin_addr.s_addr),
-		   datalen);
+	printf("PING %s (%s)",
+			hostent->h_name,
+			inet_ntoa(*(struct in_addr *) &pingaddr.sin_addr.s_addr));
+	if (sourceaddr.sin_addr.s_addr) {
+		printf(" from %s",
+			inet_ntoa(*(struct in_addr *) &sourceaddr.sin_addr.s_addr));
+	}
+	printf(": %d data bytes\n", datalen);
 
 	signal(SIGINT, pingstats);
 
@@ -378,6 +387,27 @@
 	pingstats(0);
 }
 
+/* TODO: consolidate ether-wake.c, dnsd.c, ifupdown.c, nslookup.c
+ * versions of below thing. BTW we have far too many "%u.%u.%u.%u" too...
+*/
+static int parse_nipquad(const char *str, struct sockaddr_in* addr)
+{
+	char dummy;
+	unsigned i1, i2, i3, i4;
+	if (sscanf(str, "%u.%u.%u.%u%c",
+			   &i1, &i2, &i3, &i4, &dummy) == 4
+	&& ( (i1|i2|i3|i4) <= 0xff )
+	) {
+		uint8_t* ptr = (uint8_t*)&addr->sin_addr;
+		ptr[0] = i1;
+		ptr[1] = i2;
+		ptr[2] = i3;
+		ptr[3] = i4;
+		return 0;
+	}
+	return 1; /* error */
+}
+
 int ping_main(int argc, char **argv)
 {
 	char *thisarg;
@@ -386,7 +416,6 @@
 
 	argc--;
 	argv++;
-	options = 0;
 	/* Parse any options */
 	while (argc >= 1 && **argv == '-') {
 		thisarg = *argv;
@@ -407,6 +436,18 @@
 			argv++;
 			datalen = atoi(*argv);
 			break;
+		case 'I':
+			if (--argc <= 0)
+				bb_show_usage();
+			argv++;
+/* ping6 accepts iface too:
+			if_index = if_nametoindex(*argv);
+			if (!if_index) ...
+   make it true for ping too. TODO.
+*/
+			if (parse_nipquad(*argv, &sourceaddr))
+				bb_show_usage();
+			break;
 		default:
 			bb_show_usage();
 		}

Modified: trunk/busybox/networking/ping6.c
===================================================================
--- trunk/busybox/networking/ping6.c	2006-09-02 16:16:23 UTC (rev 16028)
+++ trunk/busybox/networking/ping6.c	2006-09-02 16:17:30 UTC (rev 16029)
@@ -265,7 +265,6 @@
 		return;
 
 	icmppkt = (struct icmp6_hdr *) packet;
-
 	if (icmppkt->icmp6_id != myid)
 		return;				/* not our ping */
 
@@ -423,7 +422,6 @@
 
 	argc--;
 	argv++;
-	options = 0;
 	/* Parse any options */
 	while (argc >= 1 && **argv == '-') {
 		thisarg = *argv;




More information about the busybox-cvs mailing list