Mercurial > ecos-v3_0-branch
annotate packages/net/autotest/current/tests/routeping.inl @ 2729:74dbf4c3f2e1 after-copyright-change-20090129
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
| author | jlarmour |
|---|---|
| date | Thu, 29 Jan 2009 17:47:46 +0000 |
| parents | b0b9630950c9 |
| children |
| rev | line source |
|---|---|
| 2138 | 1 //========================================================================== |
| 2 // | |
| 3 // autotest/current/tests/routeping.inl | |
| 4 // | |
| 5 // Simple pinging test, the server pings me and I ping her. | |
| 6 // | |
| 7 //========================================================================== | |
|
2729
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2138
diff
changeset
|
8 // ####ECOSGPLCOPYRIGHTBEGIN#### |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2138
diff
changeset
|
9 // ------------------------------------------- |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2138
diff
changeset
|
10 // This file is part of eCos, the Embedded Configurable Operating System. |
| 2138 | 11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. |
| 12 // | |
|
2729
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2138
diff
changeset
|
13 // eCos is free software; you can redistribute it and/or modify it under |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2138
diff
changeset
|
14 // the terms of the GNU General Public License as published by the Free |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2138
diff
changeset
|
15 // Software Foundation; either version 2 or (at your option) any later |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2138
diff
changeset
|
16 // version. |
| 2138 | 17 // |
|
2729
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2138
diff
changeset
|
18 // eCos is distributed in the hope that it will be useful, but WITHOUT |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2138
diff
changeset
|
19 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2138
diff
changeset
|
20 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2138
diff
changeset
|
21 // for more details. |
| 2138 | 22 // |
|
2729
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2138
diff
changeset
|
23 // You should have received a copy of the GNU General Public License |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2138
diff
changeset
|
24 // along with eCos; if not, write to the Free Software Foundation, Inc., |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2138
diff
changeset
|
25 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| 2138 | 26 // |
|
2729
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2138
diff
changeset
|
27 // As a special exception, if other files instantiate templates or use |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2138
diff
changeset
|
28 // macros or inline functions from this file, or you compile this file |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2138
diff
changeset
|
29 // and link it with other works to produce a work based on this file, |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2138
diff
changeset
|
30 // this file does not by itself cause the resulting work to be covered by |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2138
diff
changeset
|
31 // the GNU General Public License. However the source code for this file |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2138
diff
changeset
|
32 // must still be made available in accordance with section (3) of the GNU |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2138
diff
changeset
|
33 // General Public License v2. |
| 2138 | 34 // |
|
2729
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2138
diff
changeset
|
35 // This exception does not invalidate any other reasons why a work based |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2138
diff
changeset
|
36 // on this file might be covered by the GNU General Public License. |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2138
diff
changeset
|
37 // ------------------------------------------- |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2138
diff
changeset
|
38 // ####ECOSGPLCOPYRIGHTEND#### |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2138
diff
changeset
|
39 // ####BSDALTCOPYRIGHTBEGIN#### |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2138
diff
changeset
|
40 // ------------------------------------------- |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2138
diff
changeset
|
41 // Portions of this software may have been derived from FreeBSD, OpenBSD, |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2138
diff
changeset
|
42 // or other sources, and if so are covered by the appropriate copyright |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2138
diff
changeset
|
43 // and license included herein. |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2138
diff
changeset
|
44 // ------------------------------------------- |
|
74dbf4c3f2e1
Update all copyright banners to reflect FSF ownership; fix and improve licence text.
jlarmour
parents:
2138
diff
changeset
|
45 // ####BSDALTCOPYRIGHTEND#### |
| 2138 | 46 //========================================================================== |
| 47 //#####DESCRIPTIONBEGIN#### | |
| 48 // | |
| 49 // Author(s): hmt,gthomas | |
| 50 // Contributors: hmt,gthomas | |
| 51 // Date: 2000-10-23 | |
| 52 // Purpose: | |
| 53 // Description: | |
| 54 // | |
| 55 // | |
| 56 //####DESCRIPTIONEND#### | |
| 57 // | |
| 58 //========================================================================== | |
| 59 | |
| 60 #include <pkgconf/system.h> | |
| 61 | |
| 62 #include <cyg/infra/testcase.h> // testing infrastructure | |
| 63 | |
| 64 #include <pkgconf/net.h> | |
| 65 | |
| 66 #ifdef CYGBLD_DEVS_ETH_DEVICE_H // Get the device config if it exists | |
| 67 #include CYGBLD_DEVS_ETH_DEVICE_H // May provide CYGTST_DEVS_ETH_TEST_NET_REALTIME | |
| 68 #endif | |
| 69 | |
| 70 #ifdef CYGPKG_NET_TESTS_USE_RT_TEST_HARNESS // do we use the rt test? | |
| 71 # ifdef CYGTST_DEVS_ETH_TEST_NET_REALTIME // Get the test ancilla if it exists | |
| 72 # include CYGTST_DEVS_ETH_TEST_NET_REALTIME | |
| 73 # endif | |
| 74 #endif | |
| 75 | |
| 76 | |
| 77 // Fill in the blanks if necessary | |
| 78 #ifndef TNR_OFF | |
| 79 # define TNR_OFF() | |
| 80 #endif | |
| 81 #ifndef TNR_ON | |
| 82 # define TNR_ON() | |
| 83 #endif | |
| 84 #ifndef TNR_INIT | |
| 85 # define TNR_INIT() | |
| 86 #endif | |
| 87 #ifndef TNR_PRINT_ACTIVITY | |
| 88 # define TNR_PRINT_ACTIVITY() | |
| 89 #endif | |
| 90 | |
| 91 // ------------------------------------------------------------------------ | |
| 92 | |
| 93 #include <errno.h> | |
| 94 #include <network.h> | |
| 95 | |
| 96 #include "autohost.inl" | |
| 97 | |
| 98 // ------------------------------------------------------------------------ | |
| 99 | |
| 100 externC int sscanf( char * /* str */, const char * /* format */, ... ); | |
| 101 | |
| 102 // ------------------------------------------------------------------------ | |
| 103 | |
| 104 static int route_add_s( struct sockaddr_in *target, | |
| 105 struct sockaddr_in *gw, | |
| 106 int maskbits, | |
| 107 int metric ) | |
| 108 { | |
| 109 struct ecos_rtentry route; | |
| 110 struct sockaddr_in mask; | |
| 111 | |
| 112 int s; | |
| 113 | |
| 114 memcpy( &mask, gw, sizeof(*gw) ); | |
| 115 maskbits--; | |
| 116 mask.sin_addr.s_addr = htonl( (0xfffffffful ^ ((0x80000000ul >> maskbits)-1)) ); | |
| 117 | |
| 118 memset( &route, 0, sizeof(route) ); | |
| 119 | |
| 120 memcpy( &route.rt_dst , target, sizeof(*target) ); | |
| 121 memcpy( &route.rt_gateway, gw , sizeof(*gw) ); | |
| 122 memcpy( &route.rt_genmask, &mask , sizeof(mask) ); | |
| 123 | |
| 124 route.rt_flags = RTF_UP|RTF_GATEWAY; | |
| 125 route.rt_metric = metric; | |
| 126 | |
| 127 route.rt_dev = NULL; | |
| 128 | |
| 129 diag_printf("INFO:<Route - dst: %s", | |
| 130 inet_ntoa(((struct sockaddr_in *)&route.rt_dst)->sin_addr)); | |
| 131 diag_printf(", mask: %s", | |
| 132 inet_ntoa(((struct sockaddr_in *)&route.rt_genmask)->sin_addr)); | |
| 133 diag_printf(", gateway: %s>\n", | |
| 134 inet_ntoa(((struct sockaddr_in *)&route.rt_gateway)->sin_addr)); | |
| 135 | |
| 136 s = socket( AF_INET, SOCK_DGRAM, 0 ); | |
| 137 if (s < 0) { | |
| 138 perror( "socket" ); | |
| 139 return false; | |
| 140 } | |
| 141 if (ioctl(s, SIOCADDRT, &route)) { | |
| 142 perror("SIOCADDRT"); | |
| 143 close(s); | |
| 144 return false; | |
| 145 } | |
| 146 diag_printf( "PASS:<Route added OK>\n" ); | |
| 147 close(s); | |
| 148 return true; | |
| 149 } | |
| 150 | |
| 151 | |
| 152 | |
| 153 int route_add( char *target, | |
| 154 char *gw, | |
| 155 int maskbits, | |
| 156 int metric ) | |
| 157 { | |
| 158 struct sockaddr_in t_s, gw_s; | |
| 159 int ints[4]; | |
| 160 | |
| 161 memset( &t_s, 0, sizeof(t_s) ); | |
| 162 memset( &gw_s, 0, sizeof(gw_s) ); | |
| 163 | |
| 164 t_s.sin_len = gw_s.sin_len = sizeof(t_s); | |
| 165 t_s.sin_family = gw_s.sin_family = AF_INET; | |
| 166 | |
| 167 if ( 4 != sscanf( target, "%d.%d.%d.%d", ints, ints+1, ints+2, ints+3 ) ) | |
| 168 CYG_TEST_FAIL( "sscanf of target IP addr" ); | |
| 169 else | |
| 170 t_s.sin_addr.s_addr = htonl( | |
| 171 (ints[0] << 24) | | |
| 172 (ints[1] << 16) | | |
| 173 (ints[2] << 8) | | |
| 174 (ints[3] ) ); | |
| 175 | |
| 176 if ( 4 != sscanf( gw, "%d.%d.%d.%d", ints, ints+1, ints+2, ints+3 ) ) | |
| 177 CYG_TEST_FAIL( "sscanf of target IP addr" ); | |
| 178 else | |
| 179 gw_s.sin_addr.s_addr = htonl( | |
| 180 (ints[0] << 24) | | |
| 181 (ints[1] << 16) | | |
| 182 (ints[2] << 8) | | |
| 183 (ints[3] ) ); | |
| 184 | |
| 185 return route_add_s( &t_s, &gw_s, maskbits, metric ); | |
| 186 } | |
| 187 | |
| 188 // ------------------------------------------------------------------------ | |
| 189 | |
| 190 #define NUM_PINGS 16 | |
| 191 #define MAX_PACKET 4096 | |
| 192 #define MIN_PACKET 64 | |
| 193 #define MAX_SEND 4000 | |
| 194 | |
| 195 #define PACKET_ADD ((MAX_SEND - MIN_PACKET)/NUM_PINGS) | |
| 196 #define nPACKET_ADD 1 | |
| 197 | |
| 198 static unsigned char pkt1[MAX_PACKET], pkt2[MAX_PACKET]; | |
| 199 | |
| 200 #define UNIQUEID 0x1234 | |
| 201 | |
| 202 // Compute INET checksum | |
| 203 int | |
| 204 inet_cksum(u_short *addr, int len) | |
| 205 { | |
| 206 register int nleft = len; | |
| 207 register u_short *w = addr; | |
| 208 register u_short answer; | |
| 209 register u_int sum = 0; | |
| 210 u_short odd_byte = 0; | |
| 211 | |
| 212 /* | |
| 213 * Our algorithm is simple, using a 32 bit accumulator (sum), | |
| 214 * we add sequential 16 bit words to it, and at the end, fold | |
| 215 * back all the carry bits from the top 16 bits into the lower | |
| 216 * 16 bits. | |
| 217 */ | |
| 218 while( nleft > 1 ) { | |
| 219 sum += *w++; | |
| 220 nleft -= 2; | |
| 221 } | |
| 222 | |
| 223 /* mop up an odd byte, if necessary */ | |
| 224 if( nleft == 1 ) { | |
| 225 *(u_char *)(&odd_byte) = *(u_char *)w; | |
| 226 sum += odd_byte; | |
| 227 } | |
| 228 | |
| 229 /* | |
| 230 * add back carry outs from top 16 bits to low 16 bits | |
| 231 */ | |
| 232 sum = (sum >> 16) + (sum & 0x0000ffff); /* add hi 16 to low 16 */ | |
| 233 sum += (sum >> 16); /* add carry */ | |
| 234 answer = ~sum; /* truncate to 16 bits */ | |
| 235 return (answer); | |
| 236 } | |
| 237 | |
| 238 static int | |
| 239 errshorts, errinvalids, errbadids, errwronghosts, errsendtos, errrecvfroms; | |
| 240 #define ERRRESET() \ | |
| 241 errshorts=errinvalids=errbadids=errwronghosts=errsendtos=errrecvfroms=0 | |
| 242 | |
| 243 static int | |
| 244 check_icmp(unsigned char *pkt, int len, | |
| 245 struct sockaddr_in *from, struct sockaddr_in *to) | |
| 246 { | |
| 247 cyg_tick_count_t *tp, tv; | |
| 248 struct ip *ip; | |
| 249 struct icmp *icmp; | |
| 250 tv = cyg_current_time(); | |
| 251 ip = (struct ip *)pkt; | |
| 252 if (len < sizeof(*ip)) | |
| 253 if (ip->ip_v != IPVERSION) { | |
| 254 errshorts++; | |
| 255 return 0; | |
| 256 } | |
| 257 icmp = (struct icmp *)(pkt + sizeof(*ip)); | |
| 258 len -= (sizeof(*ip) + 8); | |
| 259 tp = (cyg_tick_count_t *)&icmp->icmp_data; | |
| 260 if (icmp->icmp_type != ICMP_ECHOREPLY) { | |
| 261 errinvalids++; | |
| 262 return 0; | |
| 263 } | |
| 264 if (icmp->icmp_id != UNIQUEID) { | |
| 265 errbadids++; | |
| 266 return 0; | |
| 267 } | |
| 268 if (from->sin_addr.s_addr != to->sin_addr.s_addr) { | |
| 269 errwronghosts++; | |
| 270 return 0; | |
| 271 } | |
| 272 return 1; | |
| 273 } | |
| 274 | |
| 275 // expect is | |
| 276 // 0 - require failure | |
| 277 // 1 - require success | |
| 278 // 2 - don't care | |
| 279 | |
| 280 #define FAILURE_REQUIRED 0 | |
| 281 #define SUCCESS_REQUIRED 1 | |
| 282 #define NOTHING_REQUIRED 2 | |
| 283 | |
| 284 static void | |
| 285 ping_host(int s, struct sockaddr_in *host, int expect ) | |
| 286 { | |
| 287 struct icmp *icmp = (struct icmp *)pkt1; | |
| 288 int icmp_len = MIN_PACKET; | |
| 289 int seq, ok_recv, bogus_recv; | |
| 290 cyg_tick_count_t *tp; | |
| 291 long *dp; | |
| 292 struct sockaddr_in from; | |
| 293 int i, len, fromlen; | |
| 294 | |
| 295 ERRRESET(); | |
| 296 ok_recv = 0; | |
| 297 bogus_recv = 0; | |
| 298 TNR_OFF(); | |
| 299 diag_printf("INFO:<PING server %s ....>\n", inet_ntoa(host->sin_addr)); | |
| 300 for (seq = 0; seq < NUM_PINGS; seq++, icmp_len += PACKET_ADD ) { | |
| 301 TNR_ON(); | |
| 302 cyg_thread_delay( 47 ); // Half a second... | |
| 303 // Build ICMP packet | |
| 304 icmp->icmp_type = ICMP_ECHO; | |
| 305 icmp->icmp_code = 0; | |
| 306 icmp->icmp_cksum = 0; | |
| 307 icmp->icmp_seq = seq; | |
| 308 icmp->icmp_id = 0x1234; | |
| 309 // Set up ping data | |
| 310 tp = (cyg_tick_count_t *)&icmp->icmp_data; | |
| 311 *tp++ = cyg_current_time(); | |
| 312 dp = (long *)tp; | |
| 313 for (i = sizeof(*tp); i < icmp_len; i += sizeof(*dp)) { | |
| 314 *dp++ = i; | |
| 315 } | |
| 316 // Add checksum | |
| 317 icmp->icmp_cksum = inet_cksum( (u_short *)icmp, icmp_len+8); | |
| 318 // Send it off | |
| 319 if (sendto(s, icmp, icmp_len+8, 0, (struct sockaddr *)host, sizeof(*host)) < 0) { | |
| 320 errsendtos++; | |
| 321 continue; | |
| 322 } | |
| 323 // Wait for a response | |
| 324 fromlen = sizeof(from); | |
| 325 len = recvfrom(s, pkt2, sizeof(pkt2), 0, (struct sockaddr *)&from, &fromlen); | |
| 326 if (len < 0) { | |
| 327 errrecvfroms++; | |
| 328 icmp_len = MIN_PACKET - PACKET_ADD; // just in case - long routes | |
| 329 } else { | |
| 330 if ( check_icmp(pkt2, len, &from, host) ) | |
| 331 ok_recv++; | |
| 332 else | |
| 333 bogus_recv++; | |
| 334 } | |
| 335 } | |
| 336 TNR_OFF(); | |
| 337 diag_printf("INFO:<Sent %d packets, received %d OK, %d bad>\n", NUM_PINGS, ok_recv, bogus_recv); | |
| 338 if ( errsendtos + errrecvfroms ) | |
| 339 diag_printf("INFO:<%d sendto errors, %d recvfrom errors>\n", errsendtos, errrecvfroms ); | |
| 340 | |
| 341 if ( SUCCESS_REQUIRED == expect ) { | |
| 342 CYG_TEST_CHECK( 0 < ok_recv, "No pings succeeded" ); | |
| 343 CYG_TEST_CHECK( 0 == errsendtos, "Sendto failures" ); | |
| 344 #ifndef XFAIL | |
| 345 CYG_TEST_CHECK( NUM_PINGS/2 < ok_recv, "Not enough pings succeeded" ); | |
| 346 CYG_TEST_CHECK( NUM_PINGS/2 > bogus_recv, "Too many pings failed" ); | |
| 347 #endif | |
| 348 } | |
| 349 if ( FAILURE_REQUIRED == expect ) { | |
| 350 CYG_TEST_CHECK( 0 == ok_recv, "Pings succeeded" ); | |
| 351 CYG_TEST_CHECK( bogus_recv + errsendtos + errrecvfroms == NUM_PINGS, "Not enough failures" ); | |
| 352 #ifndef XFAIL | |
| 353 CYG_TEST_CHECK( 0 == bogus_recv, "Some pings got bogus recv" ); | |
| 354 #endif | |
| 355 } | |
| 356 CYG_TEST_PASS( SUCCESS_REQUIRED == expect ? "Expected successful ping behaviour" : | |
| 357 FAILURE_REQUIRED == expect ? "Expected failure ping behaviour" : | |
| 358 "Non-predicted ping behaviour" ); | |
| 359 | |
| 360 TNR_ON(); | |
| 361 return; | |
| 362 } | |
| 363 | |
| 364 static void | |
| 365 ping_test(struct bootp *bp) | |
| 366 { | |
| 367 struct protoent *p; | |
| 368 struct timeval tv; | |
| 369 struct sockaddr_in host; | |
| 370 int s; | |
| 371 | |
| 372 if ((p = getprotobyname("icmp")) == (struct protoent *)0) { | |
| 373 pexit("getprotobyname"); | |
| 374 return; | |
| 375 } | |
| 376 s = socket(AF_INET, SOCK_RAW, p->p_proto); | |
| 377 if (s < 0) { | |
| 378 pexit("socket"); | |
| 379 return; | |
| 380 } | |
| 381 tv.tv_sec = 1; | |
| 382 tv.tv_usec = 0; | |
| 383 setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); | |
| 384 // Set up host address | |
| 385 host.sin_family = AF_INET; | |
| 386 host.sin_len = sizeof(host); | |
| 387 host.sin_addr = bp->bp_siaddr; | |
| 388 host.sin_port = 0; | |
| 389 ping_host(s, &host, SUCCESS_REQUIRED ); | |
| 390 // Now try a bogus host | |
| 391 host.sin_addr.s_addr = htonl(ntohl(host.sin_addr.s_addr) + 32); | |
| 392 ping_host(s, &host, NOTHING_REQUIRED ); // Success is optional | |
| 393 close(s); | |
| 394 } | |
| 395 | |
| 396 static void | |
| 397 station_ping(char *name, int expect) | |
| 398 { | |
| 399 struct protoent *p; | |
| 400 struct timeval tv; | |
| 401 struct sockaddr_in host; | |
| 402 int s; | |
| 403 | |
| 404 int ints[4]; | |
| 405 | |
| 406 if ((p = getprotobyname("icmp")) == (struct protoent *)0) { | |
| 407 pexit("getprotobyname"); | |
| 408 return; | |
| 409 } | |
| 410 s = socket(AF_INET, SOCK_RAW, p->p_proto); | |
| 411 if (s < 0) { | |
| 412 pexit("socket"); | |
| 413 return; | |
| 414 } | |
| 415 tv.tv_sec = 1; | |
| 416 tv.tv_usec = 0; | |
| 417 setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); | |
| 418 // Set up host address | |
| 419 host.sin_family = AF_INET; | |
| 420 host.sin_len = sizeof(host); | |
| 421 host.sin_port = 0; | |
| 422 | |
| 423 if ( 4 != sscanf( name, "%d.%d.%d.%d", ints, ints+1, ints+2, ints+3 ) ) | |
| 424 CYG_TEST_FAIL( "sscanf of host IP addr" ); | |
| 425 else { | |
| 426 host.sin_addr.s_addr = htonl( | |
| 427 (ints[0] << 24) | | |
| 428 (ints[1] << 16) | | |
| 429 (ints[2] << 8) | | |
| 430 (ints[3] ) ); | |
| 431 | |
| 432 ping_host(s, &host, expect ); | |
| 433 | |
| 434 } | |
| 435 close(s); | |
| 436 } | |
| 437 | |
| 438 // ------------------------------------------------------------------------ | |
| 439 | |
| 440 #define STACK_SIZE (CYGNUM_HAL_STACK_SIZE_TYPICAL + 0x10000) | |
| 441 static char stack[STACK_SIZE]; | |
| 442 static cyg_thread thread_data; | |
| 443 static cyg_handle_t thread_handle; | |
| 444 | |
| 445 static void | |
| 446 do_ping_tests(struct bootp *bp, int N, int testtime, int filesize) | |
| 447 { | |
| 448 int i; | |
| 449 char order[256]; | |
| 450 diag_printf( "INFO: telling %s to run %d pings for %d seconds, %d bytes and up\n", | |
| 451 inet_ntoa(bp->bp_siaddr), N, testtime, filesize ); | |
| 452 | |
| 453 // For 2nd and subsequent orders, we vary the ping data size: | |
| 454 for ( i = 0; i < N; i++ ) { | |
| 455 sprintf( order, "%s %s %d %d", "SLOW_PING", | |
| 456 inet_ntoa(bp->bp_yiaddr), | |
| 457 testtime, | |
| 458 filesize + 100 * i ); | |
| 459 autohost_tell( bp, order ); | |
| 460 } | |
| 461 } | |
| 462 | |
| 463 #define TESTTIME (5 * 60) // Seconds | |
| 464 | |
| 465 #define NUM_SESSIONS 10 // why not? | |
| 466 | |
| 467 // ------------------------------------------------------------------------ | |
| 468 // | |
| 469 // The plan is as follows: | |
| 470 // | |
| 471 // The host(s) will be set up so as to have additional interfaces as follows: | |
| 472 // | |
| 473 // eth0-host -> 10.0.3.1 and maybe others | |
| 474 // eth1-host -> 10.0.4.1 and maybe others | |
| 475 // 10.0.5.x should not exist | |
| 476 // | |
| 477 // These additional addresses can exist as extra loopback addresses, lo0:0, | |
| 478 // lo0:1 and so on in a linux box. | |
| 479 // | |
| 480 // We want to ping all of the following: | |
| 481 // | |
| 482 // eth0-host should always work | |
| 483 // eth0-host+32 not expected to work | |
| 484 // eth1-host should always work | |
| 485 // eth1-host+32 not expected to work | |
| 486 // www.cygnus.com should always work if default gw is correct | |
| 487 // 10.0.3.1 should only work if route via eth0-host is added | |
| 488 // 10.0.3.99 might work if route via eth0-host is added | |
| 489 // 10.0.4.1 should only work if route via eth0-host is added | |
| 490 // 10.0.4.99 might work if route via eth0-host is added | |
| 491 // 10.0.5.1 should never work | |
| 492 // 10.0.5.99 should never work | |
| 493 // | |
| 494 // So we test those places in the following contexts: | |
| 495 // | |
| 496 // 1) No special routing added | |
| 497 // 2) route via eth0-host to 10.0.3.x is added | |
| 498 // 3) route via eth1-host to 10.0.4.x is added | |
| 499 // 4) Both routes are added | |
| 500 // | |
| 501 // and check for correct operation and correct failure in all cases. | |
| 502 // | |
| 503 // Because of the time taken, these are separate test cases which include | |
| 504 // this INL file after making suitable #defines. | |
| 505 // | |
| 506 // All the while, the hosts shall ping us, and when all is going we loop for | |
| 507 // the rest of the test time. | |
| 508 // | |
| 509 | |
| 510 void | |
| 511 net_test(cyg_addrword_t param) | |
| 512 { | |
| 513 #ifdef DOHOSTPINGS | |
| 514 int i; | |
| 515 int numtests; | |
| 516 #endif | |
| 517 int net3expect = FAILURE_REQUIRED; | |
| 518 int net4expect = FAILURE_REQUIRED; | |
| 519 | |
| 520 cyg_tick_count_t ticks; | |
| 521 CYG_TEST_INIT(); | |
| 522 CYG_TEST_INFO("Start PING routing test"); | |
| 523 init_all_network_interfaces(); | |
| 524 | |
| 525 autohost_init(); | |
| 526 | |
| 527 TNR_INIT(); | |
| 528 | |
| 529 #ifdef ADDROUTETONET_10_0_3_x | |
| 530 #ifdef CYGHWR_NET_DRIVER_ETH0 | |
| 531 if (eth0_up) { | |
| 532 route_add( "10.0.3.0", inet_ntoa(eth0_bootp_data.bp_siaddr), 24, 1 ); | |
| 533 net3expect = SUCCESS_REQUIRED; | |
| 534 } | |
| 535 #endif | |
| 536 #endif // ADDROUTETONET_10_0_3_x | |
| 537 | |
| 538 #ifdef ADDROUTETONET_10_0_4_x | |
| 539 #ifdef CYGHWR_NET_DRIVER_ETH1 | |
| 540 if (eth1_up) { | |
| 541 route_add( "10.0.4.0", inet_ntoa(eth1_bootp_data.bp_siaddr), 24, 1 ); | |
| 542 net4expect = SUCCESS_REQUIRED; | |
| 543 } | |
| 544 #endif | |
| 545 #endif // ADDROUTETONET_10_0_4_x | |
| 546 | |
| 547 numtests = NUM_SESSIONS; // The number of pingers started OK | |
| 548 i = numtests; | |
| 549 #ifdef DOHOSTPINGS | |
| 550 // Now command the host to do ping to us... | |
| 551 #ifdef CYGHWR_NET_DRIVER_ETH0 | |
| 552 if (eth0_up) { | |
| 553 do_ping_tests(ð0_bootp_data, 1, TESTTIME, 64); | |
| 554 do_ping_tests(ð0_bootp_data, 1, TESTTIME, 2000); | |
| 555 i -= 2; | |
| 556 } | |
| 557 #endif | |
| 558 #ifdef CYGHWR_NET_DRIVER_ETH1 | |
| 559 if (eth1_up && i > 0) { | |
| 560 do_ping_tests(ð1_bootp_data, 1, TESTTIME, 100); | |
| 561 do_ping_tests(ð1_bootp_data, 1, TESTTIME, 1800); | |
| 562 i -= 2; | |
| 563 } | |
| 564 #endif | |
| 565 #endif // DOHOSTPINGS | |
| 566 numtests -= i; // Adjust to how many we *actually* requested | |
| 567 | |
| 568 ticks = cyg_current_time() + TESTTIME * 100; // FIXME - assume cS clock. | |
| 569 | |
| 570 // Let the server run for 5 minutes | |
| 571 TNR_ON(); | |
| 572 | |
| 573 while (1) { | |
| 574 #ifdef CYGHWR_NET_DRIVER_ETH0 | |
| 575 if (eth0_up) | |
| 576 ping_test(ð0_bootp_data); | |
| 577 if ( ticks < cyg_current_time() ) break; | |
| 578 #endif | |
| 579 #ifdef CYGHWR_NET_DRIVER_ETH1 | |
| 580 if (eth1_up) | |
| 581 ping_test(ð1_bootp_data); | |
| 582 if ( ticks < cyg_current_time() ) break; | |
| 583 #endif | |
| 584 #ifdef CYGHWR_NET_DRIVER_ETH0 | |
| 585 if (eth0_up) { | |
| 586 station_ping( "10.0.3.1", net3expect ); | |
| 587 if ( ticks < cyg_current_time() ) break; | |
| 588 station_ping( "10.0.3.99", net3expect ); | |
| 589 } | |
| 590 if ( ticks < cyg_current_time() ) break; | |
| 591 #endif | |
| 592 #ifdef CYGHWR_NET_DRIVER_ETH1 | |
| 593 if (eth1_up) { | |
| 594 station_ping( "10.0.4.1", net4expect ); | |
| 595 if ( ticks < cyg_current_time() ) break; | |
| 596 station_ping( "10.0.4.99", net4expect ); | |
| 597 } | |
| 598 if ( ticks < cyg_current_time() ) break; | |
| 599 #endif | |
| 600 station_ping( "10.0.5.1", FAILURE_REQUIRED ); // Not valid | |
| 601 if ( ticks < cyg_current_time() ) break; | |
| 602 station_ping( "10.0.5.99", FAILURE_REQUIRED ); // Not valid | |
| 603 if ( ticks < cyg_current_time() ) break; | |
| 604 #ifdef PING_WWW_CYGNUS_COM | |
| 605 station_ping( "205.180.83.41", NOTHING_REQUIRED ); // www.cygnus.com | |
| 606 if ( ticks < cyg_current_time() ) break; | |
| 607 #endif | |
| 608 }; | |
| 609 | |
| 610 // Additional delay 'cos host may be slower than us - and it has to | |
| 611 // complete a transfer anyway: | |
| 612 cyg_thread_delay( 30 *100); // FIXME - assume cS clock. | |
| 613 TNR_OFF(); | |
| 614 | |
| 615 autohost_end( 0 ); // check for N pass messages from hosts | |
| 616 | |
| 617 TNR_PRINT_ACTIVITY(); | |
| 618 CYG_TEST_EXIT("Done"); | |
| 619 } | |
| 620 | |
| 621 void | |
| 622 cyg_start(void) | |
| 623 { | |
| 624 // Create a main thread, so we can run the scheduler and have time 'pass' | |
| 625 cyg_thread_create(10, // Priority - just a number | |
| 626 net_test, // entry | |
| 627 0, // entry parameter | |
| 628 "Network test", // Name | |
| 629 &stack[0], // Stack | |
| 630 STACK_SIZE, // Size | |
| 631 &thread_handle, // Handle | |
| 632 &thread_data // Thread data structure | |
| 633 ); | |
| 634 cyg_thread_resume(thread_handle); // Start it | |
| 635 cyg_scheduler_start(); | |
| 636 } | |
| 637 | |
| 638 // EOF routeping.inl |
