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