source: rtems/doc/networking/networkapp.t @ 9b4422a2

4.115
Last change on this file since 9b4422a2 was 9b4422a2, checked in by Joel Sherrill <joel.sherrill@…>, on 05/03/12 at 15:09:24

Remove All CVS Id Strings Possible Using a Script

Script does what is expected and tries to do it as
smartly as possible.

+ remove occurrences of two blank comment lines

next to each other after Id string line removed.

+ remove entire comment blocks which only exited to

contain CVS Ids

+ If the processing left a blank line at the top of

a file, it was removed.

  • Property mode set to 100644
File size: 29.9 KB
Line 
1@c
2@c  Written by Eric Norum
3@c
4@c  COPYRIGHT (c) 1988-2002.
5@c  On-Line Applications Research Corporation (OAR).
6@c  All rights reserved.
7
8@chapter Using Networking in an RTEMS Application
9
10@section Makefile changes
11@subsection Including the required managers
12The FreeBSD networking code requires several RTEMS managers
13in the application:
14
15@example
16MANAGERS = io event semaphore
17@end example
18
19@subsection Increasing the size of the heap
20The networking tasks allocate a lot of memory.  For most applications
21the heap should be at least 256 kbytes.
22The amount of memory set aside for the heap can be adjusted by setting
23the @code{CFLAGS_LD} definition as shown below:
24
25@example
26CFLAGS_LD += -Wl,--defsym -Wl,HeapSize=0x80000
27@end example
28
29This sets aside 512 kbytes of memory for the heap.
30
31@section System Configuration
32
33The networking tasks allocate some RTEMS objects.  These
34must be accounted for in the application configuration table.  The following
35lists the requirements.
36
37@table @b
38@item TASKS
39One network task plus a receive and transmit task for each device.
40
41@item SEMAPHORES
42One network semaphore plus one syslog mutex semaphore if the application uses
43openlog/syslog.
44
45@item EVENTS
46The network stack uses @code{RTEMS_EVENT_24} and @code{RTEMS_EVENT_25}.
47This has no effect on the application configuration, but
48application tasks which call the network functions should not
49use these events for other purposes.
50
51@end table
52
53@section Initialization
54@subsection Additional include files
55The source file which declares the network configuration
56structures and calls the network initialization function must include
57
58@example
59#include <rtems/rtems_bsdnet.h>
60@end example
61
62@subsection Network Configuration
63The network configuration is specified by declaring
64and initializing the @code{rtems_bsdnet_config}
65structure.
66
67@example
68@group
69struct rtems_bsdnet_config @{
70  /*
71   * This entry points to the head of the ifconfig chain.
72   */
73  struct rtems_bsdnet_ifconfig *ifconfig;
74
75  /*
76   * This entry should be rtems_bsdnet_do_bootp if BOOTP
77   * is being used to configure the network, and NULL
78   * if BOOTP is not being used.
79   */
80  void                    (*bootp)(void);
81
82  /*
83   * The remaining items can be initialized to 0, in
84   * which case the default value will be used.
85   */
86  rtems_task_priority  network_task_priority;  /* 100        */
87  unsigned long        mbuf_bytecount;         /* 64 kbytes  */
88  unsigned long        mbuf_cluster_bytecount; /* 128 kbytes */
89  char                *hostname;               /* BOOTP      */
90  char                *domainname;             /* BOOTP      */
91  char                *gateway;                /* BOOTP      */
92  char                *log_host;               /* BOOTP      */
93  char                *name_server[3];         /* BOOTP      */
94  char                *ntp_server[3];          /* BOOTP      */
95  unsigned long        sb_efficiency;          /* 2          */
96  /* UDP TX: 9216 bytes */
97  unsigned long        udp_tx_buf_size;
98  /* UDP RX: 40 * (1024 + sizeof(struct sockaddr_in)) */
99  unsigned long        udp_rx_buf_size;
100  /* TCP TX: 16 * 1024 bytes */
101  unsigned long        tcp_tx_buf_size;
102  /* TCP TX: 16 * 1024 bytes */
103  unsigned long        tcp_rx_buf_size;
104@};
105@end group
106@end example
107
108The structure entries are described in the following table.
109If your application uses BOOTP/DHCP to obtain network configuration
110information and if you are happy with the default values described
111below, you need to provide only the first two entries in this structure.
112
113@table @code
114
115@item struct rtems_bsdnet_ifconfig *ifconfig
116A pointer to the first configuration structure of the first network
117device.  This structure is described in the following section.
118You must provide a value for this entry since there is no default value for it.
119
120@item void (*bootp)(void)
121This entry should be set to @code{rtems_bsdnet_do_bootp} if your
122application by default uses the BOOTP/DHCP client protocol to obtain
123network configuration information.  It should be set to @code{NULL} if
124your application does not use BOOTP/DHCP.
125
126You can also use @code{rtems_bsdnet_do_bootp_rootfs} to have a set of
127standard files created with the information return by the BOOTP/DHCP
128protocol. The IP address is added to @file{/etc/hosts} with the host
129name and domain returned. If no host name or domain is returned
130@code{me.mydomain} is used. The BOOTP/DHCP server's address is also
131added to @file{/etc/hosts}. The domain name server listed in the
132BOOTP/DHCP information are added to @file{/etc/resolv.conf}. A
133@code{search} record is also added if a domain is returned. The files
134are created if they do not exist.
135
136The default @code{rtems_bsdnet_do_bootp} and
137@code{rtems_bsdnet_do_bootp_rootfs} handlers will loop for-ever
138waiting for a BOOTP/DHCP server to respond. If an error is detected
139such as not valid interface or valid hardware address the target will
140reboot allowing any hardware reset to correct itself.
141
142You can provide your own custom handler which allows you to perform
143an initialization that meets your specific system requirements. For
144example you could try BOOTP/DHCP then enter a configuration tool if no
145server is found allowing the user to switch to a static configuration.
146
147@item int network_task_priority
148The priority at which the network task and network device
149receive and transmit tasks will run.
150If a value of 0 is specified the tasks will run at priority 100.
151
152@item unsigned long mbuf_bytecount
153The number of bytes to allocate from the heap for use as mbufs. 
154If a value of 0 is specified, 64 kbytes will be allocated.
155
156@item unsigned long mbuf_cluster_bytecount
157The number of bytes to allocate from the heap for use as mbuf clusters. 
158If a value of 0 is specified, 128 kbytes will be allocated.
159
160@item char *hostname
161The host name of the system.
162If this, or any of the following, entries are @code{NULL} the value
163may be obtained from a BOOTP/DHCP server.
164
165@item char *domainname
166The name of the Internet domain to which the system belongs.
167
168@item char *gateway
169The Internet host number of the network gateway machine,
170specified in 'dotted decimal' (@code{129.128.4.1}) form.
171
172@item char *log_host
173The Internet host number of the machine to which @code{syslog} messages
174will be sent.
175
176@item char *name_server[3]
177The Internet host numbers of up to three machines to be used as
178Internet Domain Name Servers.
179
180@item char *ntp_server[3]
181The Internet host numbers of up to three machines to be used as
182Network Time Protocol (NTP) Servers.
183
184@item unsigned long sb_efficiency
185This is the first of five configuration parameters related to
186the amount of memory each socket may consume for buffers.  The
187TCP/IP stack reserves buffers (e.g. mbufs) for each open socket.  The
188TCP/IP stack has different limits for the transmit and receive
189buffers associated with each TCP and UDP socket.  By tuning these
190parameters, the application developer can make trade-offs between
191memory consumption and performance.  The default parameters favor
192performance over memory consumption.  See
193@uref{http://www.rtems.org/ml/rtems-users/2004/february/msg00200.html}
194for more details but note that after the RTEMS 4.8 release series,
195the sb_efficiency default was changed from @code{8} to @code{2}.
196
197The user should also be aware of the @code{SO_SNDBUF} and @code{SO_RCVBUF}
198IO control operations.  These can be used to specify the
199send and receive buffer sizes for a specific socket.  There
200is no standard IO control to change the @code{sb_efficiency} factor.
201
202The @code{sb_efficiency} parameter is a buffering factor used
203in the implementation of the TCP/IP stack.  The default is @code{2}
204which indicates double buffering.  When allocating memory for each
205socket, this number is multiplied by the buffer sizes for that socket.
206
207@item unsigned long udp_tx_buf_size
208This configuration parameter specifies the maximum amount of
209buffer memory which may be used for UDP sockets to transmit
210with.  The default size is 9216 bytes which corresponds to
211the maximum datagram size.
212
213@item unsigned long udp_rx_buf_size
214This configuration parameter specifies the maximum amount of
215buffer memory which may be used for UDP sockets to receive
216into.  The default size is the following length in bytes:
217
218@example
21940 * (1024 + sizeof(struct sockaddr_in)
220@end example
221
222@item unsigned long tcp_tx_buf_size
223This configuration parameter specifies the maximum amount of
224buffer memory which may be used for TCP sockets to transmit
225with.  The default size is sixteen kilobytes.
226
227@item unsigned long tcp_rx_buf_size
228This configuration parameter specifies the maximum amount of
229buffer memory which may be used for TCP sockets to receive
230into.  The default size is sixteen kilobytes.
231
232@end table
233
234In addition, the following fields in the @code{rtems_bsdnet_ifconfig}
235are of interest.
236
237@table @b
238
239@item int port
240The I/O port number (ex: 0x240) on which the external Ethernet
241can be accessed.
242
243@item int irno
244The interrupt number of the external Ethernet controller.
245
246@item int bpar
247The address of the shared memory on the external Ethernet controller.
248
249
250@end table
251
252@subsection Network device configuration
253Network devices are specified and configured by declaring and initializing a
254@code{struct rtems_bsdnet_ifconfig} structure for each network device.
255
256The structure entries are described in the following table.  An application
257which uses a single network interface, gets network configuration information
258from a BOOTP/DHCP server, and uses the default values for all driver
259parameters needs to initialize only the first two entries in the
260structure.
261
262@table @code
263@item char *name
264The full name of the network device.  This name consists of the
265driver name and the unit number (e.g. @code{"scc1"}).
266The @code{bsp.h} include file usually defines RTEMS_BSP_NETWORK_DRIVER_NAME as
267the name of the primary (or only) network driver.
268
269@item int (*attach)(struct rtems_bsdnet_ifconfig *conf)
270The address of the driver @code{attach} function.   The network
271initialization function calls this function to configure the driver and
272attach it to the network stack.
273The @code{bsp.h} include file usually defines RTEMS_BSP_NETWORK_DRIVER_ATTACH as
274the name of the  attach function of the primary (or only) network driver.
275
276@item struct rtems_bsdnet_ifconfig *next
277A pointer to the network device configuration structure for the next network
278interface, or @code{NULL} if this is the configuration structure of the
279last network interface.
280
281@item char *ip_address
282The Internet address of the device,
283specified in `dotted decimal' (@code{129.128.4.2}) form, or @code{NULL}
284if the device configuration information is being obtained from a
285BOOTP/DHCP server.
286
287@item char *ip_netmask
288The Internet inetwork mask of the device,
289specified in `dotted decimal' (@code{255.255.255.0}) form, or @code{NULL}
290if the device configuration information is being obtained from a
291BOOTP/DHCP server.
292
293
294@item void *hardware_address
295The hardware address of the device, or @code{NULL} if the driver is
296to obtain the hardware address in some other way (usually  by reading
297it from the device or from the bootstrap ROM).
298
299@item int ignore_broadcast
300Zero if the device is to accept broadcast packets, non-zero if the device
301is to ignore broadcast packets.
302
303@item int mtu
304The maximum transmission unit of the device, or zero if the driver
305is to choose a default value (typically 1500 for Ethernet devices).
306
307@item int rbuf_count
308The number of receive buffers to use, or zero if the driver is to
309choose a default value
310
311@item int xbuf_count
312The number of transmit buffers to use, or zero if the driver is to
313choose a default value
314Keep in mind that some network devices may use 4 or more
315transmit descriptors for a single transmit buffer.
316
317@end table
318
319A complete network configuration specification can be as simple as the one
320shown in the following example.
321This configuration uses a single network interface, gets
322network configuration information
323from a BOOTP/DHCP server, and uses the default values for all driver
324parameters.
325
326@example
327static struct rtems_bsdnet_ifconfig netdriver_config = @{
328  RTEMS_BSP_NETWORK_DRIVER_NAME,
329  RTEMS_BSP_NETWORK_DRIVER_ATTACH
330@};
331struct rtems_bsdnet_config rtems_bsdnet_config = @{
332  &netdriver_config,
333  rtems_bsdnet_do_bootp,
334@};
335@end example
336
337
338@subsection Network initialization
339The networking tasks must be started before any network I/O operations
340can be performed. This is done by calling:
341
342
343@example
344rtems_bsdnet_initialize_network ();
345@end example
346
347This function is declared in @code{rtems/rtems_bsdnet.h}.
348t returns 0 on success and -1 on failure with an error code
349in @code{errno}.  It is not possible to undo the effects of
350a partial initialization, though, so the function can be
351called only once irregardless of the return code.  Consequently,
352if the condition for the failure can be corrected, the
353system must be reset to permit another network initialization
354attempt.
355
356
357
358@section Application Programming Interface
359
360The RTEMS network package provides almost a complete set of BSD network
361services.  The network functions work like their BSD counterparts
362with the following exceptions:
363
364@itemize @bullet
365@item A given socket can be read or written by only one task at a time.
366
367@item The @code{select} function only works for file descriptors associated
368with sockets.
369
370@item You must call @code{openlog} before calling any of the @code{syslog} functions.
371
372@item @b{Some of the network functions are not thread-safe.}
373For example the following functions return a pointer to a static
374buffer which remains valid only until the next call:
375
376@table @code
377@item gethostbyaddr
378@item gethostbyname
379@item inet_ntoa
380(@code{inet_ntop} is thread-safe, though).
381@end table
382
383@item The RTEMS network package gathers statistics.
384
385@item Addition of a mechanism to "tap onto" an interface
386and monitor every packet received and transmitted.
387
388@item Addition of @code{SO_SNDWAKEUP} and @code{SO_RCVWAKEUP} socket options.
389
390@end itemize
391
392Some of the new features are discussed in more detail in the following
393sections.
394
395@subsection Network Statistics
396
397There are a number of functions to print statistics gathered by
398the network stack.
399These function are declared in @code{rtems/rtems_bsdnet.h}.
400
401@table @code
402@item rtems_bsdnet_show_if_stats
403Display statistics gathered by network interfaces.
404
405@item rtems_bsdnet_show_ip_stats
406Display IP packet statistics.
407
408@item rtems_bsdnet_show_icmp_stats
409Display ICMP packet statistics.
410
411@item rtems_bsdnet_show_tcp_stats
412Display TCP packet statistics.
413
414@item rtems_bsdnet_show_udp_stats
415Display UDP packet statistics.
416
417@item rtems_bsdnet_show_mbuf_stats
418Display mbuf statistics.
419
420@item rtems_bsdnet_show_inet_routes
421Display the routing table.
422
423@end table
424
425@subsection Tapping Into an Interface
426
427RTEMS add two new ioctls to the BSD networking code:
428SIOCSIFTAP and SIOCGIFTAP.  These may be used to set and get a
429@i{tap function}.  The tap function will be called for every
430Ethernet packet received by the interface.
431
432These are called like other interface ioctls, such as SIOCSIFADDR.
433When setting the tap function with SIOCSIFTAP, set the ifr_tap field
434of the ifreq struct to the tap function.  When retrieving the tap
435function with SIOCGIFTAP, the current tap function will be returned in
436the ifr_tap field.  To stop tapping packets, call SIOCSIFTAP with a
437ifr_tap field of 0.
438
439The tap function is called like this:
440
441@example
442int tap (struct ifnet *, struct ether_header *, struct mbuf *)
443@end example
444
445The tap function should return 1 if the packet was fully handled, in
446which case the caller will simply discard the mbuf.  The tap function
447should return 0 if the packet should be passed up to the higher
448networking layers.
449
450The tap function is called with the network semaphore locked.  It must
451not make any calls on the application levels of the networking level
452itself.  It is safe to call other non-networking RTEMS functions.
453
454@subsection Socket Options
455
456RTEMS adds two new @code{SOL_SOCKET} level options for @code{setsockopt} and
457@code{getsockopt}: @code{SO_SNDWAKEUP} and @code{SO_RCVWAKEUP}.  For both, the
458option value should point to a sockwakeup structure.  The sockwakeup
459structure has the following fields:
460
461@example
462@group
463  void    (*sw_pfn) (struct socket *, caddr_t);
464  caddr_t sw_arg;
465@end group
466@end example
467
468These options are used to set a callback function to be called when, for
469example, there is
470data available from the socket (@code{SO_RCVWAKEUP}) and when there is space
471available to accept data written to the socket (@code{SO_SNDWAKEUP}).
472
473If @code{setsockopt} is called with the @code{SO_RCVWAKEUP} option, and the
474@code{sw_pfn} field is not zero, then when there is data
475available to be read from
476the socket, the function pointed to by the @code{sw_pfn} field will be
477called.  A pointer to the socket structure will be passed as the first
478argument to the function.  The @code{sw_arg} field set by the
479@code{SO_RCVWAKEUP} call will be passed as the second argument to the function.
480
481If @code{setsockopt} is called with the @code{SO_SNDWAKEUP}
482function, and the @code{sw_pfn} field is not zero, then when
483there is space available to accept data written to the socket,
484the function pointed to by the @code{sw_pfn} field
485will be called.  The arguments passed to the function will be as with
486@code{SO_SNDWAKEUP}.
487
488When the function is called, the network semaphore will be locked and
489the callback function runs in the context of the networking task.
490The function must be careful not to call any networking functions.  It
491is OK to call an RTEMS function; for example, it is OK to send an
492RTEMS event.
493
494The purpose of these callback functions is to permit a more efficient
495alternative to the select call when dealing with a large number of
496sockets.
497
498The callbacks are called by the same criteria that the select
499function uses for indicating "ready" sockets. In Stevens @cite{Unix
500Network Programming} on page 153-154 in the section "Under what Conditions
501Is a Descriptor Ready?" you will find the definitive list of conditions
502for readable and writable that also determine when the functions are
503called.
504
505When the number of received bytes equals or exceeds the socket receive
506buffer "low water mark" (default 1 byte) you get a readable callback. If
507there are 100 bytes in the receive buffer and you only read 1, you will
508not immediately get another callback. However, you will get another
509callback after you read the remaining 99 bytes and at least 1 more byte
510arrives. Using a non-blocking socket you should probably read until it
511produces error  EWOULDBLOCK and then allow the readable callback to tell
512you when more data has arrived.  (Condition 1.a.)
513
514For sending, when the socket is connected and the free space becomes at
515or above the "low water mark" for the send buffer (default 4096 bytes)
516you will receive a writable callback. You don't get continuous callbacks
517if you don't write anything. Using a non-blocking write socket, you can
518then call write until it returns a value less than the amount of data
519requested to be sent or it produces error EWOULDBLOCK (indicating buffer
520full and no longer writable). When this happens you can
521try the write again, but it is often better to go do other things and
522let the writable callback tell you when space is available to send
523again. You only get a writable callback when the free space transitions
524to above the "low water mark" and not every time you
525write to a non-full send buffer. (Condition 2.a.)
526
527The remaining conditions enumerated by Stevens handle the fact that
528sockets become readable and/or writable when connects, disconnects and
529errors occur, not just when data is received or sent. For example, when
530a server "listening" socket becomes readable it indicates that a client
531has connected and accept can be called without blocking, not that
532network data was received (Condition 1.c).
533
534@subsection Adding an IP Alias
535
536The following code snippet adds an IP alias:
537
538@example
539void addAlias(const char *pName, const char *pAddr, const char *pMask)
540@{
541  struct ifaliasreq      aliasreq;
542  struct sockaddr_in    *in;
543
544  /* initialize alias request */
545  memset(&aliasreq, 0, sizeof(aliasreq));
546  sprintf(aliasreq.ifra_name, pName);
547
548  /* initialize alias address */
549  in = (struct sockaddr_in *)&aliasreq.ifra_addr;
550  in->sin_family = AF_INET;
551  in->sin_len    = sizeof(aliasreq.ifra_addr);
552  in->sin_addr.s_addr = inet_addr(pAddr);
553
554  /* initialize alias mask */
555  in = (struct sockaddr_in *)&aliasreq.ifra_mask;
556  in->sin_family = AF_INET;
557  in->sin_len    = sizeof(aliasreq.ifra_mask);
558  in->sin_addr.s_addr = inet_addr(pMask);
559
560  /* call to setup the alias */
561  rtems_bsdnet_ifconfig(pName, SIOCAIFADDR, &aliasreq);
562@}
563@end example
564
565Thanks to @uref{mailto:mikes@@poliac.com,Mike Seirs} for this example
566code.
567
568@subsection Adding a Default Route
569
570The function provided in this section is functionally equivalent to
571the command @code{route add default gw yyy.yyy.yyy.yyy}:
572
573@example
574void mon_ifconfig(int argc, char *argv[],  unsigned32 command_arg,
575                  bool verbose)
576@{
577    struct sockaddr_in  ipaddr;
578    struct sockaddr_in  dstaddr;
579    struct sockaddr_in  netmask;
580    struct sockaddr_in  broadcast;
581    char               *iface;
582    int                 f_ip        = 0;
583    int                 f_ptp       = 0;
584    int                 f_netmask   = 0;
585    int                 f_up        = 0;
586    int                 f_down      = 0;
587    int                 f_bcast     = 0;
588    int                 cur_idx;
589    int                 rc;
590    int                 flags;
591
592    bzero((void*) &ipaddr, sizeof(ipaddr));
593    bzero((void*) &dstaddr, sizeof(dstaddr));
594    bzero((void*) &netmask, sizeof(netmask));
595    bzero((void*) &broadcast, sizeof(broadcast));
596   
597    ipaddr.sin_len = sizeof(ipaddr);
598    ipaddr.sin_family = AF_INET;
599   
600    dstaddr.sin_len = sizeof(dstaddr);
601    dstaddr.sin_family = AF_INET;
602   
603    netmask.sin_len = sizeof(netmask);
604    netmask.sin_family = AF_INET;
605   
606    broadcast.sin_len = sizeof(broadcast);
607    broadcast.sin_family = AF_INET;
608   
609    cur_idx = 0;
610    if (argc <= 1) @{
611        /* display all interfaces */
612        iface = NULL;
613        cur_idx += 1;
614    @} else @{
615        iface = argv[1];
616        if (isdigit(*argv[2])) @{
617            if (inet_pton(AF_INET, argv[2], &ipaddr.sin_addr) < 0) @{
618                printf("bad ip address: %s\n", argv[2]);
619                return;
620            @}
621            f_ip = 1;
622            cur_idx += 3;
623        @} else @{
624            cur_idx += 2;
625        @}
626    @}
627   
628    if ((f_down !=0) && (f_ip != 0)) @{
629        f_up = 1;
630    @}
631   
632    while(argc > cur_idx) @{
633        if (strcmp(argv[cur_idx], "up") == 0) @{
634            f_up = 1;
635            if (f_down != 0) @{
636                printf("Can't make interface up and down\n");
637            @}
638        @} else if(strcmp(argv[cur_idx], "down") == 0) @{
639            f_down = 1;
640            if (f_up != 0) @{
641                printf("Can't make interface up and down\n");
642            @}
643        @} else if(strcmp(argv[cur_idx], "netmask") == 0) @{
644            if ((cur_idx + 1) >= argc) @{
645                printf("No netmask address\n");
646                return;
647            @}
648            if (inet_pton(AF_INET, argv[cur_idx+1], &netmask.sin_addr) < 0) @{
649                printf("bad netmask: %s\n", argv[cur_idx]);
650                return;
651            @}
652            f_netmask = 1;
653            cur_idx += 1;
654        @} else if(strcmp(argv[cur_idx], "broadcast") == 0) @{
655            if ((cur_idx + 1) >= argc) @{
656                printf("No broadcast address\n");
657                return;
658            @}
659            if (inet_pton(AF_INET, argv[cur_idx+1], &broadcast.sin_addr) < 0) @{
660                printf("bad broadcast: %s\n", argv[cur_idx]);
661                return;
662            @}
663            f_bcast = 1;
664            cur_idx += 1;
665        @} else if(strcmp(argv[cur_idx], "pointopoint") == 0) @{
666            if ((cur_idx + 1) >= argc) @{
667                printf("No pointopoint address\n");
668                return;
669            @}
670            if (inet_pton(AF_INET, argv[cur_idx+1], &dstaddr.sin_addr) < 0) @{
671                printf("bad pointopoint: %s\n", argv[cur_idx]);
672                return;
673            @}
674           
675            f_ptp = 1;
676            cur_idx += 1;
677        @} else @{
678            printf("Bad parameter: %s\n", argv[cur_idx]);
679            return;
680        @}
681       
682        cur_idx += 1;
683    @}
684   
685    printf("ifconfig ");
686    if (iface != NULL) @{
687        printf("%s ", iface);
688        if (f_ip != 0) @{
689            char str[256];
690            inet_ntop(AF_INET, &ipaddr.sin_addr, str, 256);
691            printf("%s ", str);
692        @}
693       
694        if (f_netmask != 0) @{
695            char str[256];
696            inet_ntop(AF_INET, &netmask.sin_addr, str, 256);
697            printf("netmask %s ", str);
698        @}
699       
700        if (f_bcast != 0) @{
701            char str[256];
702            inet_ntop(AF_INET, &broadcast.sin_addr, str, 256);
703            printf("broadcast %s ", str);
704        @}
705       
706        if (f_ptp != 0) @{
707            char str[256];
708            inet_ntop(AF_INET, &dstaddr.sin_addr, str, 256);
709            printf("pointopoint %s ", str);
710        @}
711       
712        if (f_up != 0) @{
713            printf("up\n");
714        @} else if (f_down != 0) @{
715            printf("down\n");
716        @} else @{
717            printf("\n");
718        @}
719    @}
720   
721    if ((iface == NULL) || ((f_ip == 0) && (f_down == 0) && (f_up == 0))) @{
722        rtems_bsdnet_show_if_stats();
723        return;
724    @}
725   
726    flags = 0;
727    if (f_netmask) @{
728        rc = rtems_bsdnet_ifconfig(iface, SIOCSIFNETMASK, &netmask);
729        if (rc < 0) @{
730            printf("Could not set netmask: %s\n", strerror(errno));
731            return;
732        @}
733    @}
734   
735    if (f_bcast) @{
736        rc = rtems_bsdnet_ifconfig(iface, SIOCSIFBRDADDR, &broadcast);
737        if (rc < 0) @{
738            printf("Could not set broadcast: %s\n", strerror(errno));
739            return;
740        @}
741    @}
742   
743    if (f_ptp) @{
744        rc = rtems_bsdnet_ifconfig(iface, SIOCSIFDSTADDR, &dstaddr);
745        if (rc < 0) @{
746            printf("Could not set destination address: %s\n", strerror(errno));
747            return;
748        @}
749        flags |= IFF_POINTOPOINT;
750    @}
751   
752    /* This must come _after_ setting the netmask, broadcast addresses */   
753    if (f_ip) @{
754        rc = rtems_bsdnet_ifconfig(iface, SIOCSIFADDR, &ipaddr);
755        if (rc < 0) @{
756            printf("Could not set IP address: %s\n", strerror(errno));
757            return;
758        @}
759    @}
760   
761    if (f_up != 0) @{
762        flags |= IFF_UP;
763    @}
764   
765    if (f_down != 0) @{
766        printf("Warning: taking interfaces down is not supported\n");
767    @}
768   
769    rc = rtems_bsdnet_ifconfig(iface, SIOCSIFFLAGS, &flags);
770    if (rc < 0) @{
771        printf("Could not set interface flags: %s\n", strerror(errno));
772        return;
773    @}
774@}
775
776
777
778void mon_route(int argc, char *argv[],  unsigned32 command_arg,
779               bool verbose)
780@{
781    int                cmd;
782    struct sockaddr_in dst;
783    struct sockaddr_in gw;
784    struct sockaddr_in netmask;
785    int                f_host;
786    int                f_gw       = 0;
787    int                cur_idx;
788    int                flags;
789    int                rc;
790   
791    memset(&dst, 0, sizeof(dst));
792    memset(&gw, 0, sizeof(gw));
793    memset(&netmask, 0, sizeof(netmask));
794   
795    dst.sin_len = sizeof(dst);
796    dst.sin_family = AF_INET;
797    dst.sin_addr.s_addr = inet_addr("0.0.0.0"); 
798   
799    gw.sin_len = sizeof(gw);
800    gw.sin_family = AF_INET;
801    gw.sin_addr.s_addr = inet_addr("0.0.0.0");
802   
803    netmask.sin_len = sizeof(netmask);
804    netmask.sin_family = AF_INET;
805    netmask.sin_addr.s_addr = inet_addr("255.255.255.0");
806   
807    if (argc < 2) @{
808        rtems_bsdnet_show_inet_routes();
809        return;
810    @}
811   
812    if (strcmp(argv[1], "add") == 0) @{
813        cmd = RTM_ADD;
814    @} else if (strcmp(argv[1], "del") == 0) @{
815        cmd = RTM_DELETE;
816    @} else @{
817        printf("invalid command: %s\n", argv[1]);
818        printf("\tit should be 'add' or 'del'\n");
819        return;
820    @}
821   
822    if (argc < 3) @{
823        printf("not enough arguments\n");
824        return;
825    @}
826   
827    if (strcmp(argv[2], "-host") == 0) @{
828        f_host = 1;
829    @} else if (strcmp(argv[2], "-net") == 0) @{
830        f_host = 0;
831    @} else @{
832        printf("Invalid type: %s\n", argv[1]);
833        printf("\tit should be '-host' or '-net'\n");
834        return;
835    @}
836   
837    if (argc < 4) @{
838        printf("not enough arguments\n");
839        return;
840    @}
841   
842    inet_pton(AF_INET, argv[3], &dst.sin_addr);
843   
844    cur_idx = 4;
845    while(cur_idx < argc) @{
846        if (strcmp(argv[cur_idx], "gw") == 0) @{
847            if ((cur_idx +1) >= argc) @{
848                printf("no gateway address\n");
849                return;
850            @}
851            f_gw = 1;
852            inet_pton(AF_INET, argv[cur_idx + 1], &gw.sin_addr);
853            cur_idx += 1;
854        @} else if(strcmp(argv[cur_idx], "netmask") == 0) @{
855            if ((cur_idx +1) >= argc) @{
856                printf("no netmask address\n");
857                return;
858            @}
859            f_gw = 1;
860            inet_pton(AF_INET, argv[cur_idx + 1], &netmask.sin_addr);
861            cur_idx += 1;
862        @} else @{
863            printf("Unknown argument\n");
864            return;
865        @}
866        cur_idx += 1;
867    @}
868   
869    flags = RTF_STATIC;
870    if (f_gw != 0) @{
871        flags |= RTF_GATEWAY;
872    @}
873    if (f_host != 0) @{
874        flags |= RTF_HOST;
875    @}
876
877    rc = rtems_bsdnet_rtrequest(cmd, &dst, &gw, &netmask, flags, NULL);
878    if (rc < 0) @{
879        printf("Error adding route\n");
880    @}
881@}
882@end example
883
884Thanks to @uref{mailto:jtm@@smoothmsmoothie.com,Jay Monkman} for this example
885code.
886
887@subsection Time Synchronization Using NTP
888
889@example
890int rtems_bsdnet_synchronize_ntp (int interval, rtems_task_priority priority);
891@end example
892
893If the interval argument is 0 the routine synchronizes the RTEMS time-of-day
894clock with the first NTP server in the rtems_bsdnet_ntpserve array and
895returns.  The priority argument is ignored.
896
897If the interval argument is greater than 0, the routine also starts an
898RTEMS task at the specified priority and polls the NTP server every
899`interval' seconds.  NOTE: This mode of operation has not yet been
900implemented.
901
902On successful synchronization of the RTEMS time-of-day clock the routine
903returns 0.  If an error occurs a message is printed and the routine returns -1
904with an error code in errno.
905There is no timeout -- if there is no response from an NTP server the
906routine will wait forever.
907
908
909
910
Note: See TracBrowser for help on using the repository browser.