blob: b85971c5620a99fde39697dd4ff326881009aad5 [file] [log] [blame]
robbiewedaaedb2002-01-16 21:31:11 +00001/*
2#
3#
Garrett Cooper2c282152010-12-16 00:55:50 -08004# Task Subprogram
robbiewedaaedb2002-01-16 21:31:11 +00005#
6# SUBPROGRAM NAME: PINGPONG6.C
7#
8# REQUIRED PARAMETERS:
9# Calling Procedure: pingpong6 HOST SIZE PACKETS
10# HOST - Current host
Garrett Cooper2c282152010-12-16 00:55:50 -080011# SIZE - Size of each packet
robbiewedaaedb2002-01-16 21:31:11 +000012# PACKETS - the number of packets across the network
13#
14# SETUP REQUIRED:
15# o This task must be run as root.
16# o TCP/IP must be configured before executing this task.
17#
18# DESCRIPTION:
19# Purpose:To generate lan traffic with ICMP6 echo packet
20# Command: None
21# Subcommand:None
22# Design:
23# Create raw socket
24# spawn child process to send echo ICMP6 packet
25# the child process build echo packet and send to network
26# repeat n times
27# the parent goes on to receive the reply
28# when finish print # of packets sent & # pf packets received
29#
30#
31#===========================================================================
32*/
33
34#define PS2
35#include <stdio.h>
36#include <errno.h>
vapier32cc0ac2006-06-22 04:28:32 +000037#include <string.h>
robbiewedaaedb2002-01-16 21:31:11 +000038#include <sys/time.h>
39#include <sys/types.h>
40
41#include <sys/param.h>
42#include <sys/socket.h>
43#include <sys/file.h>
44#include <sys/signal.h>
yaberauneya106e74f2009-10-17 06:56:58 +000045#include <stdlib.h>
yaberauneya03ce9342009-10-10 23:30:05 +000046#include <unistd.h>
robbiewedaaedb2002-01-16 21:31:11 +000047
48#include <netinet/in_systm.h>
49#include <netinet/in.h>
50#include <netinet/ip6.h>
51#include <netinet/icmp6.h>
52#include <netdb.h>
53
54#define MAXPACKET 4096 /* max packet size */
55#ifndef MAXHOSTNAMELEN
56#define MAXHOSTNAMELEN 64
57#endif
58
59int pfd[2];
60int fdstr[10];
61int verbose;
62int count;
63u_char packet[MAXPACKET];
64int options;
robbiewedaaedb2002-01-16 21:31:11 +000065int s; /* Socket file descriptor */
66struct addrinfo *hp; /* Pointer to host info */
67struct addrinfo hints;
robbiewedaaedb2002-01-16 21:31:11 +000068
69struct sockaddr_in6 whereto;/* Who to pingpong */
70int datalen; /* How much data */
71
robbiewedaaedb2002-01-16 21:31:11 +000072char *hostname;
73char hnamebuf[MAXHOSTNAMELEN];
74
75int npackets=1;
76int ntransmitted = 0; /* sequence # for outbound packets = #sent */
77int ident;
78
79int nreceived = 0; /* # of packets we got back */
80int timing = 0;
Garrett Cooper2c282152010-12-16 00:55:50 -080081void finish(int);
robbiewedaaedb2002-01-16 21:31:11 +000082int nwrite;
83/*
84 * M A I N
85 */
yaberauneya106e74f2009-10-17 06:56:58 +000086int
robbiewedaaedb2002-01-16 21:31:11 +000087main(argc, argv)
88char *argv[];
89{
90 struct sockaddr_in6 from;
91 char **av = argv;
92 int nrcv;
93 int on = 1;
94 int rc = 0;
95 struct protoent *proto;
96 int gai;
97
98 printf ("Starting pingpong - to send / receive packets from host \n");
99
100 /* Get Host net address */
101 printf ("Get host net address for sending packets \n");
102 memset(&hints, 0, sizeof(hints));
103 hints.ai_family = PF_INET6;
104
subrata_modaka2f85d32008-10-29 05:09:47 +0000105 if ((gai=getaddrinfo(av[1], NULL, &hints, &hp))!=0) {
robbiewdd2c02a2002-09-05 15:48:16 +0000106 fprintf(stderr, "Unknown subject address %s: %s\n",av[1], gai_strerror(gai));
subrata_modaka2f85d32008-10-29 05:09:47 +0000107 exit(1);
108 }
109 if (!hp->ai_addr || hp->ai_addr->sa_family != AF_INET6) {
robbiewdd2c02a2002-09-05 15:48:16 +0000110 fprintf(stderr, "getaddrinfo failed");
subrata_modaka2f85d32008-10-29 05:09:47 +0000111 exit(1);
112 }
robbiewedaaedb2002-01-16 21:31:11 +0000113 strcpy(hnamebuf, av[1]);
114 hostname = hnamebuf;
vapier32cc0ac2006-06-22 04:28:32 +0000115 memset( (char *)&whereto, 0x00, sizeof(struct sockaddr) );
robbiewedaaedb2002-01-16 21:31:11 +0000116 memcpy(&whereto, hp->ai_addr, hp->ai_addrlen);
Garrett Cooper2c282152010-12-16 00:55:50 -0800117
robbiewedaaedb2002-01-16 21:31:11 +0000118 /* Determine Packet Size - either use what was passed in or default */
119 printf ("Determine packet size \n");
Garrett Cooper8fb1cdb2010-11-28 22:56:35 -0800120 if (argc >= 3)
Garrett Cooper2c282152010-12-16 00:55:50 -0800121 datalen = atoi( av[2] ) - 8;
robbiewedaaedb2002-01-16 21:31:11 +0000122 else
123 datalen = 64-8;
124 if (datalen > MAXPACKET) {
125 printf("Pingpong: packet size too large\n");
126 exit(1);
127 }
robbiewedaaedb2002-01-16 21:31:11 +0000128
robbiewedaaedb2002-01-16 21:31:11 +0000129 /* Set number of packets to be sent */
130 printf ("Determine number of packets to send \n");
131 if (argc >= 4)
132 npackets = atoi(av[3]);
133
robbiewedaaedb2002-01-16 21:31:11 +0000134 /* Get PID of current process */
135 ident = getpid() & 0xFFFF;
136
robbiewedaaedb2002-01-16 21:31:11 +0000137 /* Get network protocol to use (check /etc/protocol) */
138 if ((proto = getprotobyname("ipv6-icmp")) == NULL) {
robbiew590cdde2002-02-26 19:16:11 +0000139 printf("ICMP6: unknown protocol\n");
robbiewedaaedb2002-01-16 21:31:11 +0000140 exit(1);
141 }
142
robbiewedaaedb2002-01-16 21:31:11 +0000143 /* Create a socket endpoint for communications - returns a descriptor */
144 if ((s = socket(AF_INET6, SOCK_RAW, proto->p_proto)) < 0) {
145 printf("Pingpong: socket - could not create link \n");
146 exit(1);
147 }
148
149 printf("echoing %s: %d data bytes\n", hostname, datalen );
Garrett Cooper2c282152010-12-16 00:55:50 -0800150 printf("Total packet size is %d bytes\n",datalen+8);
robbiewedaaedb2002-01-16 21:31:11 +0000151
152 setlinebuf( stdout );
153
154 /* Setup traps */
155 signal( SIGINT, finish );
156 signal( SIGCLD, finish );
157
robbiewedaaedb2002-01-16 21:31:11 +0000158 /* Fork a child process to continue sending packets */
159 printf ("Create a child process to continue to send packets \n");
160 switch (fork()) {
161 case -1:
162 printf("ERROR when forking a new process\n");
163 exit(1);
164 case 0:
165 /* Child's work */
166 ntransmitted=echopkt(datalen,npackets);
167 printf("%d packets transmitted, ",ntransmitted);
168 sleep(10);
169 break;
170 default:
171 printf ("Parent started - to receive packets \n");
172 /* Parent's work - receive packets back from child */
173 for (;;) {
174 int len = sizeof (packet);
175 unsigned int fromlen = sizeof (from);
176#ifdef __64BIT__
177 long cc;
178#else
179 int cc;
180#endif
181
182 /* Receive packet from socket */
robbiewedaaedb2002-01-16 21:31:11 +0000183 fromlen = sizeof (from);
Garrett Cooperdf3eb162010-11-28 22:44:32 -0800184 if ((cc=recvfrom(s, packet, len, 0, (struct sockaddr *)&from, &fromlen)) < 0) {
robbiewedaaedb2002-01-16 21:31:11 +0000185 printf("ERROR in recvfrom\n");
186 }
187 /* Verify contents of packet */
Garrett Cooper2c282152010-12-16 00:55:50 -0800188 if ((rc = ck_packet (packet, cc, &from)) == 0)
robbiewedaaedb2002-01-16 21:31:11 +0000189 nreceived++;
robbiewedaaedb2002-01-16 21:31:11 +0000190 }
191 }
Garrett Cooper794c1c12010-12-18 10:36:21 -0800192 return 0;
robbiewedaaedb2002-01-16 21:31:11 +0000193}
194
195echopkt(datalen,npackets)
196int datalen;
197int npackets;
198{
199 int count=0;
200 static u_char outpack[MAXPACKET];
201 register struct icmp6_hdr *icp = (struct icmp6_hdr *) outpack;
202 int i;
203#ifdef __64BIT__
204 long cc;
205#else
206 int cc;
207#endif
208
robbiew590cdde2002-02-26 19:16:11 +0000209 register u_char *datap = &outpack[8];
robbiewedaaedb2002-01-16 21:31:11 +0000210
robbiewedaaedb2002-01-16 21:31:11 +0000211 /* Setup the packet structure */
212 printf ("Setup ICMP packet structure to send to host \n");
213 icp->icmp6_type = ICMP6_ECHO_REQUEST;
214 icp->icmp6_code = 0;
215 icp->icmp6_cksum = 0;
216 icp->icmp6_id = ident; /* ID */
Garrett Cooper2c282152010-12-16 00:55:50 -0800217
robbiewedaaedb2002-01-16 21:31:11 +0000218 cc = datalen+8; /* skips ICMP portion */
219
Garrett Cooper2c282152010-12-16 00:55:50 -0800220 for (i=0; i<datalen; i++) {
robbiewff444192002-03-01 21:35:17 +0000221 *datap++ = 6;
robbiewedaaedb2002-01-16 21:31:11 +0000222 }
robbiewedaaedb2002-01-16 21:31:11 +0000223 ntransmitted=0;
224 while (count < npackets) {
225 count++;
226 /* Send packet through socket created */
227 printf ("Sending packet through created socket \n");
228 i = sendto( s, outpack, cc, 0, &whereto, sizeof(whereto) );
229
Garrett Cooper8fb1cdb2010-11-28 22:56:35 -0800230 if (i < 0 || i != cc) {
Garrett Cooper53740502010-12-16 00:04:01 -0800231 if (i < 0) perror("sendto");
robbiewedaaedb2002-01-16 21:31:11 +0000232 printf("pingpong6: wrote %s %d chars, ret=%d\n",hostname,cc,i);
233 fflush(stdout);
234 }
235 }
236 /* sleep(30); */
237 return(count);
238}
239
robbiewedaaedb2002-01-16 21:31:11 +0000240/*
Garrett Cooper2c282152010-12-16 00:55:50 -0800241 * F I N I S H
robbiewedaaedb2002-01-16 21:31:11 +0000242 *
243 * Outputs packet information to confirm transmission and reception.
244 */
245void finish(int n)
246{
247 printf("%d packets received, \n", nreceived );
248 exit(0);
249}
250
robbiewedaaedb2002-01-16 21:31:11 +0000251/*
252 * C K _ P A C K E T
253 *
254 * Checks contents of packet to verify information did not get destroyed
255 */
256
257ck_packet (buf, cc, from)
robbiewff444192002-03-01 21:35:17 +0000258u_char *buf; /* pointer to start of IP header */
robbiewedaaedb2002-01-16 21:31:11 +0000259int cc; /* total size of received packet */
260struct sockaddr_in6 *from; /* address of sender */
261{
robbiewff444192002-03-01 21:35:17 +0000262 int i;
robbiew590cdde2002-02-26 19:16:11 +0000263 struct icmp6_hdr icp_hdr;
264 struct icmp6_hdr *icp = (struct ip6_hdr *) buf; /* pointer to IP header */
robbiewedaaedb2002-01-16 21:31:11 +0000265 u_char *datap ;
robbiewedaaedb2002-01-16 21:31:11 +0000266
robbiew590cdde2002-02-26 19:16:11 +0000267 datap = (u_char *)icp + sizeof(icp_hdr);
robbiewedaaedb2002-01-16 21:31:11 +0000268 if (icp->icmp6_type != ICMP6_ECHO_REPLY) {
robbiew590cdde2002-02-26 19:16:11 +0000269 return(1); /* Not your packet 'cause not an echo */
robbiewedaaedb2002-01-16 21:31:11 +0000270 }
271 if (icp->icmp6_id != ident) {
robbiew590cdde2002-02-26 19:16:11 +0000272 return(1); /* Sent to us by someone else */
Garrett Cooper2c282152010-12-16 00:55:50 -0800273 }
robbiew590cdde2002-02-26 19:16:11 +0000274 printf("Receiving packet \n");
robbiewedaaedb2002-01-16 21:31:11 +0000275 /* Verify data in packet */
robbiew590cdde2002-02-26 19:16:11 +0000276
robbiewedaaedb2002-01-16 21:31:11 +0000277 printf ("Checking Data.\n");
Garrett Cooper2c282152010-12-16 00:55:50 -0800278 for (i=0; i<datalen; i++) {
279 if ((*datap) != 6) {
robbiewff444192002-03-01 21:35:17 +0000280 printf ("RVW: Data in [%d] is %d\n",i,(*datap));
281 printf ("Data cannot be validated. \n");
282 }
283 datap++;
284 }
robbiewedaaedb2002-01-16 21:31:11 +0000285 return(0);
Chris Dearmanec6edca2012-10-17 19:54:01 -0700286}