source: rtems/doc/networking/networkapp.t @ 068d7aa7

4.104.114.95
Last change on this file since 068d7aa7 was 068d7aa7, checked in by Joel Sherrill <joel.sherrill@…>, on 02/05/08 at 22:28:17

2008-02-05 Joel Sherrill <joel.sherrill@…>

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