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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [ecos-2.0/] [packages/] [net/] [tcpip/] [v2_0/] [doc/] [sample_program.html] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1254 phoenix
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
2
<html>
3
<head>
4
   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
5
   <meta name="GENERATOR" content="Mozilla/4.7 [en] (X11; I; Linux 2.2.14 ppc) [Netscape]">
6
</head>
7
<body>
8
 
9
<center>
10
<h1>
11
Sample Networking Program</h1></center>
12
 
13
<p><br>This example is derived from the test program <tt>".../net/tcpip/v1_3_1/tests/ping_test.c"</tt>.
14
<br>&nbsp;
15
<blockquote><tt><font size=-1>//==========================================================================</font></tt>
16
<br><tt><font size=-1>//</font></tt>
17
<br><tt><font size=-1>//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tests/ping_test.c</font></tt>
18
<br><tt><font size=-1>//</font></tt>
19
<br><tt><font size=-1>//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Simple test of PING
20
(ICMP) and networking support</font></tt>
21
<br><tt><font size=-1>//</font></tt>
22
<br><tt><font size=-1>//==========================================================================</font></tt>
23
<br><tt><font size=-1>//####BSDCOPYRIGHTBEGIN####</font></tt>
24
<br><tt><font size=-1>//</font></tt>
25
<br><tt><font size=-1>// -------------------------------------------</font></tt>
26
<br><tt><font size=-1>//</font></tt>
27
<br><tt><font size=-1>// Portions of this software may have been derived
28
from OpenBSD or other sources,</font></tt>
29
<br><tt><font size=-1>// and are covered by the appropriate copyright disclaimers
30
included herein.</font></tt>
31
<br><tt><font size=-1>//</font></tt>
32
<br><tt><font size=-1>// -------------------------------------------</font></tt>
33
<br><tt><font size=-1>//</font></tt>
34
<br><tt><font size=-1>//####BSDCOPYRIGHTEND####</font></tt>
35
<br><tt><font size=-1>//==========================================================================</font></tt>
36
<br><tt><font size=-1>//#####DESCRIPTIONBEGIN####</font></tt>
37
<br><tt><font size=-1>//</font></tt>
38
<br><tt><font size=-1>// Author(s):&nbsp;&nbsp;&nbsp; gthomas</font></tt>
39
<br><tt><font size=-1>// Contributors: gthomas</font></tt>
40
<br><tt><font size=-1>// Date:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
41
2000-01-10</font></tt>
42
<br><tt><font size=-1>// Purpose:</font></tt>
43
<br><tt><font size=-1>// Description:</font></tt>
44
<br><tt><font size=-1>//</font></tt>
45
<br><tt><font size=-1>//</font></tt>
46
<br><tt><font size=-1>//####DESCRIPTIONEND####</font></tt>
47
<br><tt><font size=-1>//</font></tt>
48
<br><tt><font size=-1>//==========================================================================</font></tt><tt><font size=-1></font></tt>
49
<p><tt><font size=-1>// PING test code</font></tt><b><tt><font size=-1></font></tt></b>
50
<p><b><tt><font size=-1>#include &lt;network.h></font></tt></b></blockquote>
51
This single include directive is all that is required to pick up the networking
52
support, including complete configuration information.
53
<blockquote><tt><font size=-1>#define STACK_SIZE CYGNUM_HAL_STACK_SIZE_TYPICAL</font></tt>
54
<br><tt><font size=-1>static char stack[STACK_SIZE];</font></tt>
55
<br><tt><font size=-1>static cyg_thread thread_data;</font></tt>
56
<br><tt><font size=-1>static cyg_handle_t thread_handle;</font></tt><tt><font size=-1></font></tt>
57
<p><tt><font size=-1>#define NUM_PINGS 16</font></tt>
58
<br><tt><font size=-1>#define MAX_PACKET 4096</font></tt>
59
<br><tt><font size=-1>static unsigned char pkt1[MAX_PACKET], pkt2[MAX_PACKET];</font></tt><tt><font size=-1></font></tt>
60
<p><tt><font size=-1>#define UNIQUEID 0x1234</font></tt><tt><font size=-1></font></tt>
61
<p><tt><font size=-1>void</font></tt>
62
<br><tt><font size=-1>cyg_test_exit(void)</font></tt>
63
<br><tt><font size=-1>{</font></tt>
64
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; diag_printf("... Done\n");</font></tt>
65
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; while (1) ;</font></tt>
66
<br><tt><font size=-1>}</font></tt><tt><font size=-1></font></tt>
67
<p><tt><font size=-1>void</font></tt>
68
<br><tt><font size=-1>pexit(char *s)</font></tt>
69
<br><tt><font size=-1>{</font></tt>
70
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; perror(s);</font></tt>
71
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; cyg_test_exit();</font></tt>
72
<br><tt><font size=-1>}</font></tt><tt><font size=-1></font></tt>
73
<p><tt><font size=-1>// Compute INET checksum</font></tt>
74
<br><tt><font size=-1>int</font></tt>
75
<br><tt><font size=-1>inet_cksum(u_short *addr, int len)</font></tt>
76
<br><tt><font size=-1>{</font></tt>
77
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; register int nleft = len;</font></tt>
78
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; register u_short *w = addr;</font></tt>
79
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; register u_short answer;</font></tt>
80
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; register u_int sum = 0;</font></tt>
81
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; u_short odd_byte = 0;</font></tt><tt><font size=-1></font></tt>
82
<p><tt><font size=-1>&nbsp;&nbsp;&nbsp; /*</font></tt>
83
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp; Our algorithm is
84
simple, using a 32 bit accumulator (sum),</font></tt>
85
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp; we add sequential
86
16 bit words to it, and at the end, fold</font></tt>
87
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp; back all the carry
88
bits from the top 16 bits into the lower</font></tt>
89
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp; 16 bits.</font></tt>
90
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp; */</font></tt>
91
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; while( nleft > 1 )&nbsp; {</font></tt>
92
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sum +=
93
*w++;</font></tt>
94
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nleft
95
-= 2;</font></tt>
96
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; }</font></tt><tt><font size=-1></font></tt>
97
<p><tt><font size=-1>&nbsp;&nbsp;&nbsp; /* mop up an odd byte, if necessary
98
*/</font></tt>
99
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; if( nleft == 1 ) {</font></tt>
100
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *(u_char
101
*)(&amp;odd_byte) = *(u_char *)w;</font></tt>
102
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sum +=
103
odd_byte;</font></tt>
104
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; }</font></tt><tt><font size=-1></font></tt>
105
<p><tt><font size=-1>&nbsp;&nbsp;&nbsp; /*</font></tt>
106
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp; * add back carry outs from
107
top 16 bits to low 16 bits</font></tt>
108
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp; */</font></tt>
109
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; sum = (sum >> 16) + (sum &amp;
110
0x0000ffff); /* add hi 16 to low 16 */</font></tt>
111
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; sum += (sum >> 16);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
112
/* add carry */</font></tt>
113
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; answer = ~sum;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
114
/* truncate to 16 bits */</font></tt>
115
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; return (answer);</font></tt>
116
<br><tt><font size=-1>}</font></tt><tt><font size=-1></font></tt>
117
<p><tt><font size=-1>static int</font></tt>
118
<br><tt><font size=-1>show_icmp(unsigned char *pkt, int len,</font></tt>
119
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
120
struct sockaddr_in *from, struct sockaddr_in *to)</font></tt>
121
<br><tt><font size=-1>{</font></tt>
122
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; cyg_tick_count_t *tp, tv;</font></tt>
123
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; struct ip *ip;</font></tt>
124
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; struct icmp *icmp;</font></tt>
125
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; tv = cyg_current_time();</font></tt>
126
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; ip = (struct ip *)pkt;</font></tt>
127
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; if ((len &lt; sizeof(*ip)) ||
128
ip->ip_v != IPVERSION) {</font></tt>
129
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; diag_printf("%s:
130
Short packet or not IP! - Len: %d, Version: %d\n",</font></tt>
131
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
132
inet_ntoa(from->sin_addr), len, ip->ip_v);</font></tt>
133
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return
134
0;</font></tt>
135
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; }</font></tt>
136
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; icmp = (struct icmp *)(pkt + sizeof(*ip));</font></tt>
137
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; len -= (sizeof(*ip) + 8);</font></tt>
138
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; tp = (cyg_tick_count_t *)&amp;icmp->icmp_data;</font></tt>
139
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; if (icmp->icmp_type != ICMP_ECHOREPLY)
140
{</font></tt>
141
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; diag_printf("%s:
142
Invalid ICMP - type: %d\n",</font></tt>
143
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
144
inet_ntoa(from->sin_addr), icmp->icmp_type);</font></tt>
145
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return
146
0;</font></tt>
147
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; }</font></tt>
148
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; if (icmp->icmp_id != UNIQUEID)
149
{</font></tt>
150
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; diag_printf("%s:
151
ICMP received for wrong id - sent: %x, recvd: %x\n",</font></tt>
152
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
153
inet_ntoa(from->sin_addr), UNIQUEID, icmp->icmp_id);</font></tt>
154
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; }</font></tt>
155
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; diag_printf("%d bytes from %s:
156
", len, inet_ntoa(from->sin_addr));</font></tt>
157
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; diag_printf("icmp_seq=%d", icmp->icmp_seq);</font></tt>
158
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; diag_printf(", time=%dms\n", (int)(tv
159
- *tp)*10);</font></tt>
160
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; return (from->sin_addr.s_addr
161
== to->sin_addr.s_addr);</font></tt>
162
<br><tt><font size=-1>}</font></tt><tt><font size=-1></font></tt>
163
<p><tt><font size=-1>static void</font></tt>
164
<br><tt><font size=-1>ping_host(int s, struct sockaddr_in *host)</font></tt>
165
<br><tt><font size=-1>{</font></tt>
166
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; struct icmp *icmp = (struct icmp
167
*)pkt1;</font></tt>
168
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; int icmp_len = 64;</font></tt>
169
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; int seq, ok_recv, bogus_recv;</font></tt>
170
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; cyg_tick_count_t *tp;</font></tt>
171
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; long *dp;</font></tt>
172
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; struct sockaddr_in from;</font></tt>
173
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; int i, len, fromlen;</font></tt><tt><font size=-1></font></tt>
174
<p><tt><font size=-1>&nbsp;&nbsp;&nbsp; ok_recv = 0;</font></tt>
175
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; bogus_recv = 0;</font></tt>
176
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; diag_printf("PING server %s\n",
177
<b>inet_ntoa(host->sin_addr)</b>);</font></tt></blockquote>
178
This function takes an IP address and returns a string representation.&nbsp;
179
Useful for printing the address.
180
<blockquote><tt><font size=-1>&nbsp;&nbsp;&nbsp; for (seq = 0;&nbsp; seq
181
&lt; NUM_PINGS;&nbsp; seq++) {</font></tt>
182
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Build
183
ICMP packet</font></tt>
184
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; icmp->icmp_type
185
= ICMP_ECHO;</font></tt>
186
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; icmp->icmp_code
187
= 0;</font></tt>
188
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; icmp->icmp_cksum
189
= 0;</font></tt>
190
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; icmp->icmp_seq
191
= seq;</font></tt>
192
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; icmp->icmp_id
193
= 0x1234;</font></tt>
194
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Set
195
up ping data</font></tt>
196
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tp = (cyg_tick_count_t
197
*)&amp;icmp->icmp_data;</font></tt>
198
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *tp++
199
= cyg_current_time();</font></tt>
200
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dp = (long
201
*)tp;</font></tt>
202
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i
203
= sizeof(*tp);&nbsp; i &lt; icmp_len;&nbsp; i += sizeof(*dp)) {</font></tt>
204
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
205
*dp++ = i;</font></tt>
206
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font></tt>
207
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Add
208
checksum</font></tt>
209
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; icmp->icmp_cksum
210
= inet_cksum( (u_short *)icmp, icmp_len+8);</font></tt>
211
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Send
212
it off</font></tt>
213
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>if
214
(sendto(s, icmp, icmp_len+8, 0, (struct sockaddr *)host, sizeof(*host))
215
&lt; 0) {</b></font></tt></blockquote>
216
This function sends a single packet, in this case via the ICMP protocol.&nbsp;
217
The destination address is specified by the <tt>host</tt> argument.
218
<blockquote><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
219
perror("sendto");</font></tt>
220
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
221
continue;</font></tt>
222
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font></tt>
223
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Wait
224
for a response</font></tt>
225
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fromlen
226
= sizeof(from);</font></tt>
227
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>len
228
= recvfrom(s, pkt2, sizeof(pkt2), 0, (struct sockaddr *)&amp;from, &amp;fromlen);</b></font></tt></blockquote>
229
This function waits for a packet to be sent to this interface.&nbsp; Note:
230
this operation can fail if no packet is received with a given amount of
231
time (this timeout value is setup in the <tt>ping_test()</tt> routine below).
232
<blockquote><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
233
if (len &lt; 0) {</font></tt>
234
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
235
perror("recvfrom");</font></tt>
236
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else
237
{</font></tt>
238
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
239
if (show_icmp(pkt2, len, &amp;from, host)) {</font></tt>
240
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
241
ok_recv++;</font></tt>
242
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
243
} else {</font></tt>
244
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
245
bogus_recv++;</font></tt>
246
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
247
}</font></tt>
248
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font></tt>
249
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; }</font></tt>
250
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; diag_printf("Sent %d packets,
251
received %d OK, %d bad\n", NUM_PINGS, ok_recv, bogus_recv);</font></tt>
252
<br><tt><font size=-1>}</font></tt><tt><font size=-1></font></tt>
253
<p><tt><font size=-1>static void</font></tt>
254
<br><tt><font size=-1>ping_test(struct bootp *bp)</font></tt>
255
<br><tt><font size=-1>{</font></tt>
256
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; struct protoent *p;</font></tt>
257
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; struct timeval tv;</font></tt>
258
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; struct sockaddr_in host;</font></tt>
259
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; int s;</font></tt><tt><font size=-1></font></tt>
260
<p><tt><font size=-1>&nbsp;&nbsp;&nbsp; <b>if ((p = getprotobyname("icmp"))
261
== (struct protoent *)0) {</b></font></tt></blockquote>
262
This function gets information about the ICMP protocol.&nbsp; This will
263
be used below to set up the "socket" (the handle to a network connection).
264
<blockquote><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
265
perror("getprotobyname");</font></tt>
266
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;</font></tt>
267
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; }</font></tt>
268
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; <b>s = socket(AF_INET, SOCK_RAW,
269
p->p_proto);</b></font></tt></blockquote>
270
Create the socket "s".&nbsp; A socket is an abstract object (sometimes
271
called a handle or endpoint).&nbsp; Sockets come in many flavors, RAW sockets
272
are used for communicating with non-structured protocols.&nbsp; DATAGRAM
273
sockets are used for packet oriented protocols, such as UDP.&nbsp; STREAM
274
sockets are used for reliable, sequenced byte streams, such as those provided
275
by TCP.
276
<blockquote><tt><font size=-1>&nbsp;&nbsp;&nbsp; if (s &lt; 0) {</font></tt>
277
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; perror("socket");</font></tt>
278
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;</font></tt>
279
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; }</font></tt>
280
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; tv.tv_sec = 1;</font></tt>
281
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; tv.tv_usec = 0;</font></tt>
282
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; <b>setsockopt(s, SOL_SOCKET, SO_RCVTIMEO,
283
&amp;tv, sizeof(tv));</b></font></tt></blockquote>
284
This function instructs the system that receive operations (see <tt>ping_host()</tt>
285
above) must complete within 1 second or issue a timed out error condition.
286
<blockquote><tt><font size=-1>&nbsp;&nbsp;&nbsp; // Set up host address</font></tt>
287
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; host.sin_family = AF_INET;</font></tt>
288
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; host.sin_addr = bp->bp_siaddr;</font></tt>
289
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; host.sin_port = 0;</font></tt>
290
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; ping_host(s, &amp;host);</font></tt>
291
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; // Now try a bogus host</font></tt>
292
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; host.sin_addr.s_addr = htonl(ntohl(host.sin_addr.s_addr)
293
+ 32);</font></tt>
294
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; ping_host(s, &amp;host);</font></tt>
295
<br><tt><font size=-1>}</font></tt>
296
<br><tt><font size=-1></font></tt>&nbsp;</blockquote>
297
This function drives the test.
298
<blockquote><tt><font size=-1>void</font></tt>
299
<br><tt><font size=-1>net_test(cyg_addrword_t p)</font></tt>
300
<br><tt><font size=-1>{</font></tt>
301
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; diag_printf("Start PING test\n");</font></tt>
302
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; <b>init_all_network_interfaces();</b></font></tt></blockquote>
303
This is a call to the network initialization code.&nbsp; Note that it must
304
be executed from a thread context, thus we can't put it in the <tt>cyg_start()
305
</tt>function which follows.&nbsp; The <tt>init_all_network_interfaces()</tt>
306
routine will cause the networking system to be initialized and any hardware
307
interfaces will be set up.&nbsp; Using the system configuration information,
308
an interface can be started using either <b>BOOTP</b>,&nbsp; or a predefined
309
configuration with static IP information.&nbsp; It is also possible to
310
indicate that an interface will be configured by the user code, outside
311
of "<tt>init_all_network_interfaces()</tt>".
312
<br><tt><font size=-1>&nbsp;</font></tt>
313
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; #ifdef CYGHWR_NET_DRIVER_ETH0</font></tt>
314
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (eth0_up)
315
{</font></tt>
316
<blockquote><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
317
ping_test(&amp;eth0_bootp_data);</font></tt>
318
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; }</font></tt>
319
<br><tt><font size=-1>#endif</font></tt></blockquote>
320
Notice that there is a BOOTP information structure kept about all hardware
321
interfaces.&nbsp; This is created and initialized by the call to <tt>init_all_network_interfaces()</tt>,
322
unless manual configuration is selected.&nbsp; This information can be
323
used by the application to learn things such as the local IP address, server
324
name, etc.
325
<blockquote><tt><font size=-1>#ifdef CYGHWR_NET_DRIVER_ETH1</font></tt>
326
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; if (eth1_up) {</font></tt>
327
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ping_test(&amp;eth1_bootp_data);</font></tt>
328
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; }</font></tt>
329
<br><tt><font size=-1>#endif</font></tt></blockquote>
330
Multiple hardware interfaces can be supported, depending on the hardware
331
platform.&nbsp; If the platform provides a single ethernet device then&nbsp;
332
<b><tt>CYGHWR_NET_DRIVER_ETH0 </tt></b>will be defined.&nbsp; If there
333
is a second interface, then will <b><tt>CYGHWR_NET_DRIVER_ETH1 </tt></b>be
334
defined.
335
<blockquote><tt><font size=-1>&nbsp;&nbsp;&nbsp; cyg_test_exit();</font></tt>
336
<br><tt><font size=-1>}</font></tt>
337
<br><tt><font size=-1></font></tt>&nbsp;</blockquote>
338
The following function creates an initial thread which runs the program.&nbsp;
339
This could just as easily be done by naming the <tt>net_test()</tt> function
340
<tt>main()</tt>.
341
<blockquote><tt><font size=-1>void</font></tt>
342
<br><tt><font size=-1>cyg_start(void)</font></tt>
343
<br><tt><font size=-1>{</font></tt>
344
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; // Create a main thread, so we
345
can run the scheduler and have time 'pass'</font></tt>
346
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; cyg_thread_create(10,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
347
// Priority - just a number</font></tt>
348
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
349
net_test,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // entry</font></tt>
350
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
351
0,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
352
// entry parameter</font></tt>
353
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
354
"Network test",&nbsp;&nbsp;&nbsp; // Name</font></tt>
355
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
356
&amp;stack[0],&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Stack</font></tt>
357
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
358
STACK_SIZE,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Size</font></tt>
359
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
360
&amp;thread_handle,&nbsp;&nbsp;&nbsp; // Handle</font></tt>
361
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
362
&amp;thread_data&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Thread data structure</font></tt>
363
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
364
);</font></tt>
365
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; cyg_thread_resume(thread_handle);&nbsp;
366
// Start it</font></tt>
367
<br><tt><font size=-1>&nbsp;&nbsp;&nbsp; cyg_scheduler_start();</font></tt>
368
<br><tt><font size=-1>}</font></tt></blockquote>
369
 
370
</body>
371
</html>

powered by: WebSVN 2.1.0

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