comparison packages/net/tcpip/current/doc/sample_program.html @ 97:ced4577552cd ecos-sw-2000-06-06

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