OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [net/] [common/] [v2_0/] [tests/] [dhcp_test.c] - Blame information for rev 565

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
//==========================================================================
2
//
3
//      tests/dhcp_test.c
4
//
5
//      Simple test of DHCP (ICMP) and networking support
6
//
7
//==========================================================================
8
//####BSDCOPYRIGHTBEGIN####
9
//
10
// -------------------------------------------
11
//
12
// Portions of this software may have been derived from OpenBSD or other sources,
13
// and are covered by the appropriate copyright disclaimers included herein.
14
//
15
// -------------------------------------------
16
//
17
//####BSDCOPYRIGHTEND####
18
//==========================================================================
19
//#####DESCRIPTIONBEGIN####
20
//
21
// Author(s):    gthomas
22
// Contributors: gthomas
23
// Date:         2000-01-10
24
// Purpose:      
25
// Description:  
26
//              
27
//
28
//####DESCRIPTIONEND####
29
//
30
//==========================================================================
31
 
32
// DHCP test code
33
 
34
#include <network.h>
35
 
36
#include <pkgconf/system.h>
37
#include <pkgconf/net.h>
38
 
39
#include <dhcp.h>
40
 
41
#include <cyg/infra/testcase.h>
42
 
43
#ifdef CYGBLD_DEVS_ETH_DEVICE_H    // Get the device config if it exists
44
#include CYGBLD_DEVS_ETH_DEVICE_H  // May provide CYGTST_DEVS_ETH_TEST_NET_REALTIME
45
#endif
46
 
47
#ifdef CYGPKG_NET_TESTS_USE_RT_TEST_HARNESS // do we use the rt test?
48
# ifdef CYGTST_DEVS_ETH_TEST_NET_REALTIME // Get the test ancilla if it exists
49
#  include CYGTST_DEVS_ETH_TEST_NET_REALTIME
50
# endif
51
#endif
52
 
53
// Fill in the blanks if necessary
54
#ifndef TNR_OFF
55
# define TNR_OFF()
56
#endif
57
#ifndef TNR_ON
58
# define TNR_ON()
59
#endif
60
#ifndef TNR_INIT
61
# define TNR_INIT()
62
#endif
63
#ifndef TNR_PRINT_ACTIVITY
64
# define TNR_PRINT_ACTIVITY()
65
#endif
66
 
67
 
68
 
69
#define STACK_SIZE (CYGNUM_HAL_STACK_SIZE_TYPICAL + 0x1000)
70
static char stack[STACK_SIZE];
71
static cyg_thread thread_data;
72
static cyg_handle_t thread_handle;
73
 
74
#define NUM_PINGS 16
75
#define MAX_PACKET 4096
76
#define MIN_PACKET   64
77
#define MAX_SEND   4000
78
 
79
#define PACKET_ADD  ((MAX_SEND - MIN_PACKET)/NUM_PINGS)
80
#define nPACKET_ADD  1 
81
 
82
static unsigned char pkt1[MAX_PACKET], pkt2[MAX_PACKET];
83
 
84
#define UNIQUEID 0x1234
85
 
86
void
87
pexit(char *s)
88
{
89
    CYG_TEST_FAIL_FINISH(s);
90
}
91
 
92
// Compute INET checksum
93
int
94
inet_cksum(u_short *addr, int len)
95
{
96
    register int nleft = len;
97
    register u_short *w = addr;
98
    register u_short answer;
99
    register u_int sum = 0;
100
    u_short odd_byte = 0;
101
 
102
    /*
103
     *  Our algorithm is simple, using a 32 bit accumulator (sum),
104
     *  we add sequential 16 bit words to it, and at the end, fold
105
     *  back all the carry bits from the top 16 bits into the lower
106
     *  16 bits.
107
     */
108
    while( nleft > 1 )  {
109
        sum += *w++;
110
        nleft -= 2;
111
    }
112
 
113
    /* mop up an odd byte, if necessary */
114
    if( nleft == 1 ) {
115
        *(u_char *)(&odd_byte) = *(u_char *)w;
116
        sum += odd_byte;
117
    }
118
 
119
    /*
120
     * add back carry outs from top 16 bits to low 16 bits
121
     */
122
    sum = (sum >> 16) + (sum & 0x0000ffff); /* add hi 16 to low 16 */
123
    sum += (sum >> 16);                     /* add carry */
124
    answer = ~sum;                          /* truncate to 16 bits */
125
    return (answer);
126
}
127
 
128
static int
129
show_icmp(unsigned char *pkt, int len,
130
          struct sockaddr_in *from, struct sockaddr_in *to)
131
{
132
    cyg_tick_count_t *tp, tv;
133
    struct ip *ip;
134
    struct icmp *icmp;
135
    tv = cyg_current_time();
136
    ip = (struct ip *)pkt;
137
    if ((len < sizeof(*ip)) || ip->ip_v != IPVERSION) {
138
        diag_printf("%s: Short packet or not IP! - Len: %d, Version: %d\n",
139
                    inet_ntoa(from->sin_addr), len, ip->ip_v);
140
        return 0;
141
    }
142
    icmp = (struct icmp *)(pkt + sizeof(*ip));
143
    len -= (sizeof(*ip) + 8);
144
    tp = (cyg_tick_count_t *)&icmp->icmp_data;
145
    if (icmp->icmp_type != ICMP_ECHOREPLY) {
146
        diag_printf("%s: Invalid ICMP - type: %d\n",
147
                    inet_ntoa(from->sin_addr), icmp->icmp_type);
148
        return 0;
149
    }
150
    if (icmp->icmp_id != UNIQUEID) {
151
        diag_printf("%s: ICMP received for wrong id - sent: %x, recvd: %x\n",
152
                    inet_ntoa(from->sin_addr), UNIQUEID, icmp->icmp_id);
153
    }
154
    diag_printf("%d bytes from %s: ", len, inet_ntoa(from->sin_addr));
155
    diag_printf("icmp_seq=%d", icmp->icmp_seq);
156
    diag_printf(", time=%dms\n", (int)(tv - *tp)*10);
157
    return (from->sin_addr.s_addr == to->sin_addr.s_addr);
158
}
159
 
160
static void
161
ping_host(int s, struct sockaddr_in *host)
162
{
163
    struct icmp *icmp = (struct icmp *)pkt1;
164
    int icmp_len = MIN_PACKET;
165
    int seq, ok_recv, bogus_recv;
166
    cyg_tick_count_t *tp;
167
    long *dp;
168
    struct sockaddr_in from;
169
    int i, len, fromlen;
170
 
171
    ok_recv = 0;
172
    bogus_recv = 0;
173
    diag_printf("PING server %s\n", inet_ntoa(host->sin_addr));
174
    for (seq = 0;  seq < NUM_PINGS;  seq++, icmp_len += PACKET_ADD ) {
175
        TNR_ON();
176
        // Build ICMP packet
177
        icmp->icmp_type = ICMP_ECHO;
178
        icmp->icmp_code = 0;
179
        icmp->icmp_cksum = 0;
180
        icmp->icmp_seq = seq;
181
        icmp->icmp_id = 0x1234;
182
        // Set up ping data
183
        tp = (cyg_tick_count_t *)&icmp->icmp_data;
184
        *tp++ = cyg_current_time();
185
        dp = (long *)tp;
186
        for (i = sizeof(*tp);  i < icmp_len;  i += sizeof(*dp)) {
187
            *dp++ = i;
188
        }
189
        // Add checksum
190
        icmp->icmp_cksum = inet_cksum( (u_short *)icmp, icmp_len+8);
191
        // Send it off
192
        if (sendto(s, icmp, icmp_len+8, 0, (struct sockaddr *)host, sizeof(*host)) < 0) {
193
            TNR_OFF();
194
            perror("sendto");
195
            continue;
196
        }
197
        // Wait for a response
198
        fromlen = sizeof(from);
199
        len = recvfrom(s, pkt2, sizeof(pkt2), 0, (struct sockaddr *)&from, &fromlen);
200
        TNR_OFF();
201
        if (len < 0) {
202
            perror("recvfrom");
203
            icmp_len = MIN_PACKET - PACKET_ADD; // go back to small packet size
204
            seq+=4;
205
        } else {
206
            if (show_icmp(pkt2, len, &from, host)) {
207
                ok_recv++;
208
            } else {
209
                bogus_recv++;
210
            }
211
        }
212
    }
213
    TNR_OFF();
214
}
215
 
216
static void
217
ping_test(struct bootp *bp)
218
{
219
    struct protoent *p;
220
    struct timeval tv;
221
    struct sockaddr_in host;
222
    int s;
223
 
224
    if ((p = getprotobyname("icmp")) == (struct protoent *)0) {
225
        pexit("getprotobyname");
226
        return;
227
    }
228
    s = socket(AF_INET, SOCK_RAW, p->p_proto);
229
    if (s < 0) {
230
        pexit("socket");
231
        return;
232
    }
233
    tv.tv_sec = 1;
234
    tv.tv_usec = 0;
235
    setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
236
    // Set up host address
237
    host.sin_family = AF_INET;
238
    host.sin_len = sizeof(host);
239
    host.sin_addr = bp->bp_siaddr;
240
    host.sin_port = 0;
241
    ping_host(s, &host);
242
    // Now try a bogus host
243
    host.sin_addr.s_addr = htonl(ntohl(host.sin_addr.s_addr) + 32);
244
    ping_host(s, &host);
245
    close(s);
246
}
247
 
248
void
249
net_test(cyg_addrword_t p)
250
{
251
#ifndef CYGPKG_NET_DHCP
252
    CYG_TEST_NA( "DHCP is not enabled" );
253
    CYG_TEST_EXIT( "DHCP is not enabled" );
254
#else
255
    int i;
256
    diag_printf("Start DHCP test\n");
257
    TNR_INIT();
258
    init_all_network_interfaces();
259
 
260
    for ( i = 10; i > 0; i-- ) {
261
#ifdef CYGHWR_NET_DRIVER_ETH0
262
        if (eth0_up) {
263
            ping_test(&eth0_bootp_data);
264
        }
265
#endif
266
        // Now do the DHCP renewal ritual...
267
        if ( cyg_semaphore_trywait( &dhcp_needs_attention )) {
268
            if ( ! dhcp_bind() ) {
269
                // All done
270
                dhcp_halt();
271
                CYG_TEST_FAIL_FINISH( "Rebind after lease failed");
272
                break;
273
            }
274
        }
275
#ifdef CYGHWR_NET_DRIVER_ETH1
276
        if (eth1_up) {
277
            ping_test(&eth1_bootp_data);
278
        }
279
#endif
280
 
281
#ifndef CYGOPT_NET_DHCP_DHCP_THREAD
282
        // Now do the DHCP renewal ritual...
283
        if ( cyg_semaphore_trywait( &dhcp_needs_attention )) {
284
            if ( ! dhcp_bind() ) {
285
                // All done
286
                dhcp_halt();
287
                CYG_TEST_FAIL_FINISH( "Rebind after lease failed");
288
                break;
289
            }
290
        }
291
#endif // not CYGOPT_NET_DHCP_DHCP_THREAD 
292
 
293
        if ( 1 == (i & 3) ) {
294
            dhcp_release();             // relinquish leases
295
            dhcp_halt();
296
            init_all_network_interfaces();
297
        }
298
    }
299
    dhcp_release();
300
 
301
    TNR_PRINT_ACTIVITY();
302
    CYG_TEST_PASS_FINISH("Dhcp test OK");
303
#endif
304
}
305
 
306
void
307
cyg_start(void)
308
{
309
    // Create a main thread, so we can run the scheduler and have time 'pass'
310
    cyg_thread_create(10,                // Priority - just a number
311
                      net_test,          // entry
312
                      0,                 // entry parameter
313
                      "Network test",    // Name
314
                      &stack[0],         // Stack
315
                      STACK_SIZE,        // Size
316
                      &thread_handle,    // Handle
317
                      &thread_data       // Thread data structure
318
            );
319
    cyg_thread_resume(thread_handle);  // Start it
320
    cyg_scheduler_start();
321
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.