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