Home | History | Annotate | Download | only in sockets
      1 /* -*- linux-c -*- */
      2 /*
      3  *
      4  *
      5  *   Copyright (c) International Business Machines  Corp., 2000
      6  *
      7  *   This program is free software;  you can redistribute it and/or modify
      8  *   it under the terms of the GNU General Public License as published by
      9  *   the Free Software Foundation; either version 2 of the License, or
     10  *   (at your option) any later version.
     11  *
     12  *   This program is distributed in the hope that it will be useful,
     13  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
     14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
     15  *   the GNU General Public License for more details.
     16  *
     17  *   You should have received a copy of the GNU General Public License
     18  *   along with this program;  if not, write to the Free Software
     19  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
     20  *
     21  *
     22  */
     23 /*
     24  * ltpClient.c
     25  *
     26  * LTP Network Socket Test Client
     27  *
     28  *
     29  */
     30 
     31 #include <sys/types.h>
     32 #include <sys/socket.h>
     33 #include <netinet/in.h>
     34 #include <netinet/ip_icmp.h>
     35 #include <arpa/inet.h>
     36 #include <netdb.h>
     37 #include <stdio.h>
     38 #include <stdlib.h>
     39 #include <resolv.h>
     40 #include <fcntl.h>
     41 #include <errno.h>
     42 #include <unistd.h>
     43 #include <string.h>
     44 #include <sys/time.h>
     45 
     46 #define LOCAL_UDP_SERVER_PORT   10000
     47 #define LOCAL_TCP_SERVER_PORT   10001
     48 #define LOCAL_MCAST_SERVER_PORT 10002
     49 #define MAX_MSG_LEN             256
     50 #define TIMETOLIVE              10
     51 #define PACKETSIZE	            64
     52 #define NET_ERROR               -1
     53 #define PACKET_LEN              1024	/* 1K should be plenty */
     54 #define TRUE                    1
     55 #define FALSE                   0
     56 
     57 struct protoent *protocol = NULL;
     58 
     59 struct packet {
     60 	struct icmphdr hdr;
     61 	char msg[PACKETSIZE - sizeof(struct icmphdr)];
     62 };
     63 
     64 /*
     65 *   Function Prototypes
     66 */
     67 int ltp_run_ping_tests(char *hostName);
     68 int ltp_run_traceroute_tests(char *hostName);
     69 void ping_network(struct sockaddr_in *rawAddr, int pid);
     70 void output_to_display(void *netPacket, int bytes, int pid);
     71 unsigned short checksum(void *netPacket, int len);
     72 int network_listener(char *hostname, int pid);
     73 void ltp_traceroute(struct sockaddr_in *rawTraceAddr, char *hostName, int pid);
     74 
     75 /*******************************************************************
     76 *  Function: Main
     77 *
     78 *  Main will run the tests in this order.
     79 *       UDP, TCP and Multicast will be run first, if multicast is enabled.
     80 *       If multicast is not enabled, the UDP/TCP tests will continue.
     81 *       Once those tests complete, the ping and then traceroute tests will run.
     82 *
     83 ********************************************************************/
     84 int main(int argc, char *argv[])
     85 {
     86 
     87 	int udpSocketHandle, tcpSocketHandle, mcastSocketHandle, rc, i;
     88 
     89 	struct sockaddr_in udpClientAddr,
     90 	    udpRemoteServerAddr,
     91 	    tcpClientAddr,
     92 	    tcpRemoteServerAddr, mcastClientAddr, mcastRemoteServerAddr;
     93 
     94 	struct hostent *hostEntry;
     95 
     96 	char hostName[MAX_MSG_LEN],
     97 	    progName[MAX_MSG_LEN], traceName[MAX_MSG_LEN], multiCast = TRUE;
     98 
     99 	unsigned char ttl = 1;
    100 
    101 	mcastSocketHandle = -1;
    102 
    103 	/* check command line args */
    104 	if (argc < 4) {
    105 		printf
    106 		    ("usage :<server-hostname> <trace-hostName> <data1> ... <dataN> \n");
    107 		exit(1);
    108 	}
    109 
    110 	strncpy(progName, argv[0], MAX_MSG_LEN);
    111 	strncpy(hostName, argv[1], MAX_MSG_LEN);
    112 	strncpy(traceName, argv[2], MAX_MSG_LEN);
    113 
    114 	/* get server IP address (no check if input is IP address or DNS name */
    115 	hostEntry = gethostbyname(hostName);
    116 
    117 	if (hostEntry == NULL) {
    118 		printf("%s: unknown host passed'%s' \n", progName, hostName);
    119 		exit(1);
    120 	}
    121 
    122 	printf("%s: sending data to '%s' (IP : %s) \n", progName,
    123 	       hostEntry->h_name,
    124 	       inet_ntoa(*(struct in_addr *)hostEntry->h_addr_list[0]));
    125 
    126 	/* Setup UDP data packets */
    127 
    128 	udpRemoteServerAddr.sin_family = hostEntry->h_addrtype;
    129 	memcpy((char *)&udpRemoteServerAddr.sin_addr.s_addr,
    130 	       hostEntry->h_addr_list[0], hostEntry->h_length);
    131 	udpRemoteServerAddr.sin_port = htons(LOCAL_UDP_SERVER_PORT);
    132 
    133 	/* Setup TCP data packets */
    134 
    135 	tcpRemoteServerAddr.sin_family = hostEntry->h_addrtype;
    136 	memcpy((char *)&tcpRemoteServerAddr.sin_addr.s_addr,
    137 	       hostEntry->h_addr_list[0], hostEntry->h_length);
    138 	tcpRemoteServerAddr.sin_port = htons(LOCAL_TCP_SERVER_PORT);
    139 
    140 	/* Setup multiCast data packets */
    141 
    142 	mcastRemoteServerAddr.sin_family = hostEntry->h_addrtype;
    143 	memcpy((char *)&mcastRemoteServerAddr.sin_addr.s_addr,
    144 	       hostEntry->h_addr_list[0], hostEntry->h_length);
    145 	mcastRemoteServerAddr.sin_port = htons(LOCAL_MCAST_SERVER_PORT);
    146 
    147 	/* socket creation */
    148 	udpSocketHandle = socket(AF_INET, SOCK_DGRAM, 0);
    149 	tcpSocketHandle = socket(AF_INET, SOCK_STREAM, 0);
    150 
    151 	if (udpSocketHandle < 0) {
    152 		printf("%s: Error: cannot open UDP socket \n", progName);
    153 	}
    154 
    155 	if (tcpSocketHandle < 0) {
    156 		printf("%s: Error: cannot open TCP socket \n", progName);
    157 	}
    158 
    159 	/* bind any UDP port */
    160 	udpClientAddr.sin_family = AF_INET;
    161 	udpClientAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    162 	udpClientAddr.sin_port = htons(0);
    163 
    164 	/* bind any TCP port */
    165 	tcpClientAddr.sin_family = AF_INET;
    166 	tcpClientAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    167 	tcpClientAddr.sin_port = htons(0);
    168 
    169 	if (udpSocketHandle > 0) {
    170 		rc = bind(udpSocketHandle, (struct sockaddr *)&udpClientAddr,
    171 			  sizeof(udpClientAddr));
    172 
    173 		if (rc < 0) {
    174 			printf("%s: Error: cannot bind UDP port\n", progName);
    175 		}
    176 	}
    177 
    178 	if (tcpSocketHandle > 0) {
    179 		rc = bind(tcpSocketHandle, (struct sockaddr *)&tcpClientAddr,
    180 			  sizeof(tcpClientAddr));
    181 
    182 		if (rc < 0) {
    183 			printf("%s: Error: cannot bind TCP port\n", progName);
    184 		} else {
    185 			/* connect to server */
    186 			rc = connect(tcpSocketHandle,
    187 				     (struct sockaddr *)&tcpRemoteServerAddr,
    188 				     sizeof(tcpRemoteServerAddr));
    189 
    190 			if (rc < 0) {
    191 				printf
    192 				    ("Error: cannot connect tp TCP Server \n");
    193 			}
    194 		}
    195 	}
    196 
    197 	/* check given address is multicast */
    198 	if (!IN_MULTICAST(ntohl(mcastRemoteServerAddr.sin_addr.s_addr))) {
    199 		printf
    200 		    ("%s : Hostname [%s] passed [%s] is not a multicast server\n",
    201 		     progName, hostName,
    202 		     inet_ntoa(mcastRemoteServerAddr.sin_addr));
    203 		printf("The multiCast Server will not be started \n");
    204 		multiCast = FALSE;
    205 	} else {
    206 		/* create socket */
    207 		mcastSocketHandle = socket(AF_INET, SOCK_DGRAM, 0);
    208 		if (mcastSocketHandle < 0) {
    209 			printf("Error: %s : cannot open mulitCast socket\n",
    210 			       progName);
    211 			multiCast = FALSE;
    212 		}
    213 
    214 		/* bind any port number */
    215 		mcastClientAddr.sin_family = AF_INET;
    216 		mcastClientAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    217 		mcastClientAddr.sin_port = htons(0);
    218 
    219 		if (bind
    220 		    (mcastSocketHandle, (struct sockaddr *)&mcastClientAddr,
    221 		     sizeof(mcastClientAddr)) < 0) {
    222 			printf("Error: binding multiCast socket");
    223 			multiCast = FALSE;
    224 		}
    225 
    226 		if (setsockopt
    227 		    (mcastSocketHandle, IPPROTO_IP, IP_MULTICAST_TTL, &ttl,
    228 		     sizeof(ttl)) < 0) {
    229 			printf("Error: %s : cannot set ttl = %d \n", progName,
    230 			       ttl);
    231 			multiCast = FALSE;
    232 		}
    233 
    234 		printf("%s : sending data on multicast group '%s' (%s)\n",
    235 		       progName, hostEntry->h_name,
    236 		       inet_ntoa(*(struct in_addr *)hostEntry->h_addr_list[0]));
    237 
    238 	}
    239 
    240 	/* Skip over the program and hostnames and just send data */
    241 	for (i = 3; i < argc; i++) {
    242 
    243 		if (udpSocketHandle > 0) {
    244 			rc = sendto(udpSocketHandle, argv[i],
    245 				    strlen(argv[i]) + 1, 0,
    246 				    (struct sockaddr *)&udpRemoteServerAddr,
    247 				    sizeof(udpRemoteServerAddr));
    248 
    249 			if (rc < 0) {
    250 				printf("%s: cannot send UDP data %d \n",
    251 				       progName, i - 1);
    252 				close(udpSocketHandle);
    253 			} else {
    254 				printf("%s: UDP data%u sent (%s)\n", progName,
    255 				       i - 1, argv[i]);
    256 			}
    257 		} else {
    258 			printf("%s UDP Socket not open for send \n", hostName);
    259 		}
    260 
    261 		if (tcpSocketHandle > 0) {
    262 			rc = send(tcpSocketHandle, argv[i], strlen(argv[i]) + 1,
    263 				  0);
    264 
    265 			if (rc < 0) {
    266 				printf("cannot send TCP data ");
    267 				close(tcpSocketHandle);
    268 
    269 			} else {
    270 				printf("%s: TCP data%u sent (%s)\n", progName,
    271 				       i - 1, argv[i]);
    272 			}
    273 		} else {
    274 			printf("%s TCP Socket not open for send \n", hostName);
    275 		}
    276 
    277 		if (multiCast) {
    278 			rc = sendto(mcastSocketHandle, argv[i],
    279 				    strlen(argv[i]) + 1, 0,
    280 				    (struct sockaddr *)&mcastRemoteServerAddr,
    281 				    sizeof(mcastRemoteServerAddr));
    282 
    283 			if (rc < 0) {
    284 				printf("%s : cannot send multiCast data %d\n",
    285 				       progName, i - 1);
    286 				close(mcastSocketHandle);
    287 				multiCast = FALSE;
    288 			}
    289 		}
    290 	}
    291 
    292 	sleep(5);
    293 
    294 	ltp_run_traceroute_tests(traceName);
    295 
    296 	ltp_run_ping_tests(hostName);
    297 
    298 	return 0;
    299 
    300 }
    301 
    302 /*****************************************************************************
    303 * Function: ltp_run_traceroute_tests - host look up and start traceroute processes
    304 *
    305 ******************************************************************************/
    306 int ltp_run_traceroute_tests(char *hostName)
    307 {
    308 
    309 	struct hostent *hostEntry;
    310 	struct sockaddr_in rawTraceAddr;
    311 	int pid = -1;
    312 
    313 	pid = getpid();
    314 
    315 	protocol = getprotobyname("ICMP");
    316 	hostEntry = gethostbyname(hostName);
    317 
    318 	memset(&rawTraceAddr, 0, sizeof(rawTraceAddr));
    319 
    320 	rawTraceAddr.sin_family = hostEntry->h_addrtype;
    321 	rawTraceAddr.sin_port = 0;
    322 	rawTraceAddr.sin_addr.s_addr = *(long *)hostEntry->h_addr;
    323 
    324 	ltp_traceroute(&rawTraceAddr, hostName, pid);
    325 
    326 	return 0;
    327 }
    328 
    329 /**********************************************************************
    330 * Function: ltp_run_ping_tests - host look up and start ping processes
    331 *
    332 ***********************************************************************/
    333 int ltp_run_ping_tests(char *hostName)
    334 {
    335 
    336 	struct hostent *hostEntry;
    337 	struct sockaddr_in rawAddr;
    338 	int pid = -1;
    339 
    340 	pid = getpid();
    341 
    342 	protocol = getprotobyname("ICMP");
    343 	hostEntry = gethostbyname(hostName);
    344 
    345 	memset(&rawAddr, 0, sizeof(rawAddr));
    346 
    347 	rawAddr.sin_family = hostEntry->h_addrtype;
    348 	rawAddr.sin_port = 0;
    349 	rawAddr.sin_addr.s_addr = *(long *)hostEntry->h_addr;
    350 
    351 	if (fork() == 0) {
    352 		network_listener(hostName, pid);
    353 	} else {
    354 		ping_network(&rawAddr, pid);
    355 
    356 	}
    357 
    358 	return 0;
    359 }
    360 
    361 /******************************************************************************
    362 * Function: network_listener - separate process to listen for and collect messages
    363 *
    364 *******************************************************************************/
    365 int network_listener(char *hostName, int pid)
    366 {
    367 
    368 	int rawSocket, count, value = TIMETOLIVE;
    369 	struct sockaddr_in rawAddr;
    370 	unsigned char packet[PACKET_LEN];
    371 
    372 	rawSocket = socket(PF_INET, SOCK_RAW, protocol->p_proto);
    373 	count = 0;
    374 
    375 	if (rawSocket < 0) {
    376 		printf("%s: Error: cannot open RAW socket \n", hostName);
    377 		return (NET_ERROR);
    378 	}
    379 
    380 	while (1) {		/* loop forever */
    381 
    382 		int bytes;
    383 		socklen_t len = sizeof(rawAddr);
    384 
    385 		memset(packet, 0, sizeof(packet));
    386 
    387 		bytes =
    388 		    recvfrom(rawSocket, packet, sizeof(packet), 0,
    389 			     (struct sockaddr *)&rawAddr, &len);
    390 
    391 		if (bytes > 0)
    392 			output_to_display(packet, bytes, pid);
    393 		else {
    394 			printf("%s : cannot receive data\n", hostName);
    395 			break;
    396 		}
    397 		count++;
    398 
    399 		if (value == count) {
    400 			printf("Exiting the network_listener...\n");
    401 		}
    402 	}
    403 
    404 	close(rawSocket);
    405 	return (0);
    406 }
    407 
    408 /****************************************************************
    409 * Function: checksum - standard 1s complement checksum
    410 *
    411 *****************************************************************/
    412 unsigned short checksum(void *netPacket, int len)
    413 {
    414 
    415 	unsigned short *packetPtr = netPacket, result;
    416 
    417 	unsigned int sum = 0;
    418 
    419 	for (sum = 0; len > 1; len -= 2) {
    420 		sum += *packetPtr++;
    421 	}
    422 
    423 	if (len == 1) {
    424 		sum += *(unsigned char *)packetPtr;
    425 	}
    426 
    427 	sum = (sum >> 16) + (sum & 0xFFFF);
    428 	sum += (sum >> 16);
    429 
    430 	result = ~sum;
    431 
    432 	return result;
    433 }
    434 
    435 /*****************************************************************
    436 * Function: output_to_display - Output to display info. from the
    437 *                               listener
    438 ******************************************************************/
    439 void output_to_display(void *netPacket, int bytes, int pid)
    440 {
    441 
    442 	int i;
    443 	struct iphdr *ip = netPacket;
    444 	struct icmphdr *icmpPtr = netPacket + ip->ihl * 4;
    445 	struct in_addr tmp_addr;
    446 
    447 	printf
    448 	    ("\n************** -- Ping Tests - **********************************************\n");
    449 
    450 	for (i = 0; i < bytes; i++) {
    451 		if (!(i & 15)) {
    452 			printf("\n[%d]:  ", i);
    453 		}
    454 
    455 		printf("[%d] ", ((unsigned char *)netPacket)[i]);
    456 	}
    457 
    458 	printf("\n");
    459 
    460 	tmp_addr.s_addr = ip->saddr;
    461 
    462 	printf("IPv%d: hdr-size=%d pkt-size=%d protocol=%d TTL=%d src=%s ",
    463 	       ip->version, ip->ihl * 4, ntohs(ip->tot_len), ip->protocol,
    464 	       ip->ttl, inet_ntoa(tmp_addr));
    465 
    466 	tmp_addr.s_addr = ip->daddr;
    467 	printf("dst=%s\n", inet_ntoa(tmp_addr));
    468 
    469 	if (icmpPtr->un.echo.id == pid) {
    470 
    471 		printf("ICMP: type[%d/%d] checksum[%d] id[%d] seq[%d]\n\n",
    472 		       icmpPtr->type, icmpPtr->code, ntohs(icmpPtr->checksum),
    473 		       icmpPtr->un.echo.id, icmpPtr->un.echo.sequence);
    474 
    475 	}
    476 }
    477 
    478 /***********************************************************************
    479 * Function: ping_network - Build a message and send it.
    480 *
    481 *
    482 ***********************************************************************/
    483 void ping_network(struct sockaddr_in *rawAddr, int pid)
    484 {
    485 
    486 	const int value = TIMETOLIVE;
    487 	int i, rawSocket, count = 1;
    488 
    489 	struct packet rawPacket;
    490 
    491 	struct sockaddr_in r_addr;
    492 
    493 	rawSocket = socket(PF_INET, SOCK_RAW, protocol->p_proto);
    494 
    495 	if (rawSocket < 0) {
    496 		printf("Error: cannot open RAW socket %d\n", rawSocket);
    497 		return;
    498 	}
    499 
    500 	if (setsockopt(rawSocket, SOL_IP, IP_TTL, &value, sizeof(value)) != 0) {
    501 		printf("ERROR: Setting TimeToLive option");
    502 	} else {
    503 		printf
    504 		    ("The test will run for [%d] iterations -- Ctrl-C to interupt \n",
    505 		     value);
    506 		sleep(3);
    507 	}
    508 
    509 	if (fcntl(rawSocket, F_SETFL, O_NONBLOCK) != 0) {
    510 		printf("ERROR: Failed request nonblocking I/O");
    511 	}
    512 
    513 	while (1) {
    514 
    515 		socklen_t msgLength = sizeof(r_addr);
    516 
    517 		printf("Message ID #:%d \n", count);
    518 
    519 		if (recvfrom
    520 		    (rawSocket, &rawPacket, sizeof(rawPacket), 0,
    521 		     (struct sockaddr *)&r_addr, &msgLength) > 0) {
    522 			printf("*** -- Message Received -- ***\n");
    523 		}
    524 
    525 		memset(&rawPacket, 0, sizeof(rawPacket));
    526 
    527 		rawPacket.hdr.type = ICMP_ECHO;
    528 		rawPacket.hdr.un.echo.id = pid;
    529 
    530 		for (i = 0; i < sizeof(rawPacket.msg) - 1; i++) {
    531 			rawPacket.msg[i] = i + '0';
    532 		}
    533 
    534 		rawPacket.msg[i] = 0;
    535 		rawPacket.hdr.un.echo.sequence = count++;
    536 		rawPacket.hdr.checksum =
    537 		    checksum(&rawPacket, sizeof(rawPacket));
    538 
    539 		if (sendto
    540 		    (rawSocket, &rawPacket, sizeof(rawPacket), 0,
    541 		     (struct sockaddr *)rawAddr, sizeof(*rawAddr)) <= 0)
    542 			printf("ERROR: sendto failed !!");
    543 
    544 		sleep(1);
    545 
    546 		if (value == count) {
    547 			printf("Exiting ping test...\n");
    548 			break;
    549 		}
    550 	}
    551 
    552 	close(rawSocket);
    553 }
    554 
    555 /**********************************************************************
    556 *  Function: ltp_traceroute
    557 *                      try to reach the destination
    558 *                      while outputting hops along the route
    559 ***********************************************************************/
    560 void ltp_traceroute(struct sockaddr_in *rawTraceAddr, char *hostName, int pid)
    561 {
    562 
    563 	const int flag = TRUE;
    564 	int TimeToLive = 0;
    565 	int i, rawTraceSocket, count = 1;
    566 	socklen_t length;
    567 	struct packet rawTracePacket;
    568 	unsigned char tracePacket[PACKET_LEN];
    569 	struct sockaddr_in rawReceiveAddr;
    570 	struct hostent *hostEntry2;
    571 	struct in_addr tmp_addr;
    572 
    573 	printf
    574 	    ("\n************** -- Trace Route Tests - **********************************************\n");
    575 
    576 	rawTraceSocket = socket(PF_INET, SOCK_RAW, protocol->p_proto);
    577 
    578 	if (rawTraceSocket < 0) {
    579 		printf("Error: cannot open RAW socket %d\n", rawTraceSocket);
    580 		return;
    581 	}
    582 
    583 	if (setsockopt(rawTraceSocket, SOL_IP, SO_ERROR, &flag, sizeof(flag)) !=
    584 	    0)
    585 		printf("ERROR: Setting socket options");
    586 
    587 	do {
    588 		struct iphdr *ip;
    589 		length = sizeof(rawReceiveAddr);
    590 
    591 		TimeToLive++;
    592 		if (setsockopt
    593 		    (rawTraceSocket, SOL_IP, IP_TTL, &TimeToLive,
    594 		     sizeof(TimeToLive)) != 0) {
    595 			printf("ERROR: Setting TimeToLive option");
    596 		}
    597 
    598 		memset(&rawTracePacket, 0, sizeof(rawTracePacket));
    599 
    600 		rawTracePacket.hdr.type = ICMP_ECHO;
    601 		rawTracePacket.hdr.un.echo.id = pid;
    602 
    603 		for (i = 0; i < sizeof(rawTracePacket.msg) - 1; i++) {
    604 			rawTracePacket.msg[i] = i + '0';
    605 		}
    606 
    607 		rawTracePacket.msg[i] = 0;
    608 		rawTracePacket.hdr.un.echo.sequence = count++;
    609 		rawTracePacket.hdr.checksum =
    610 		    checksum(&rawTracePacket, sizeof(rawTracePacket));
    611 
    612 		if (sendto
    613 		    (rawTraceSocket, &rawTracePacket, sizeof(rawTracePacket), 0,
    614 		     (struct sockaddr *)rawTraceAddr,
    615 		     sizeof(*rawTraceAddr)) <= 0) {
    616 			printf("ERROR: sendto failed !!");
    617 		}
    618 		sleep(1);
    619 
    620 		if (recvfrom
    621 		    (rawTraceSocket, tracePacket, sizeof(tracePacket),
    622 		     MSG_DONTWAIT, (struct sockaddr *)&rawReceiveAddr,
    623 		     &length) > 0) {
    624 			ip = (void *)tracePacket;
    625 
    626 			tmp_addr.s_addr = ip->saddr;
    627 			printf("Host IP:#%d: %s \n", count - 1,
    628 			       inet_ntoa(tmp_addr));
    629 
    630 			hostEntry2 =
    631 			    gethostbyaddr((void *)&rawReceiveAddr, length,
    632 					  rawReceiveAddr.sin_family);
    633 
    634 			if (hostEntry2 != NULL)
    635 				printf("(%s)\n", hostEntry2->h_name);
    636 			else
    637 				perror("Name: ");
    638 		} else {
    639 			printf("%s : data send complete...\n", hostName);
    640 			break;
    641 		}
    642 
    643 	}
    644 	while (rawReceiveAddr.sin_addr.s_addr != rawTraceAddr->sin_addr.s_addr);
    645 
    646 	printf
    647 	    ("\n************** -- End Trace Route Tests - ******************************************\n");
    648 
    649 	close(rawTraceSocket);
    650 }
    651