source: rtems/doc/networking/networkapp.t @ 593904c

4.104.114.84.95
Last change on this file since 593904c was 593904c, checked in by Joel Sherrill <joel.sherrill@…>, on Feb 11, 2003 at 11:08:49 PM

2003-02-11 Jay Monkman <jtm@…>

  • networkapp.t: Add an example code snippet for adding a default route.
  • Property mode set to 100644
File size: 24.1 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@};
99@end group
100@end example
101
102The structure entries are described in the following table.
103If your application uses BOOTP/DHCP to obtain network configuration
104information and if you are happy with the default values described
105below, you need to provide only the first two entries in this structure.
106
107@table @code
108
109@item struct rtems_bsdnet_ifconfig *ifconfig
110A pointer to the first configuration structure of the first network
111device.  This structure is described in the following section.
112You must provide a value for this entry since there is no default value for it.
113
114
115@item void (*bootp)(void)
116This entry should be set to @code{rtems_bsdnet_do_bootp}
117if your application will use BOOTP/DHCP
118to obtain network configuration information.
119It should be set to @code{NULL}
120if your application does not use BOOTP/DHCP.
121
122
123@item int network_task_priority
124The priority at which the network task and network device
125receive and transmit tasks will run.
126If a value of 0 is specified the tasks will run at priority 100.
127
128@item unsigned long mbuf_bytecount
129The number of bytes to allocate from the heap for use as mbufs. 
130If a value of 0 is specified, 64 kbytes will be allocated.
131
132@item unsigned long mbuf_cluster_bytecount
133The number of bytes to allocate from the heap for use as mbuf clusters. 
134If a value of 0 is specified, 128 kbytes will be allocated.
135
136@item char *hostname
137The host name of the system.
138If this, or any of the following, entries are @code{NULL} the value
139may be obtained from a BOOTP/DHCP server.
140
141@item char *domainname
142The name of the Internet domain to which the system belongs.
143
144@item char *gateway
145The Internet host number of the network gateway machine,
146specified in `dotted decimal' (@code{129.128.4.1}) form.
147
148@item char *log_host
149The Internet host number of the machine to which @code{syslog} messages
150will be sent.
151
152@item char *name_server[3]
153The Internet host numbers of up to three machines to be used as
154Internet Domain Name Servers.
155
156@item char *ntp_server[3]
157The Internet host numbers of up to three machines to be used as
158Network Time Protocol (NTP) Servers.
159
160@end table
161
162In addition, the following fields in the @code{rtems_bsdnet_ifconfig}
163are of interest.
164
165@table @b
166
167@item int port
168The I/O port number (ex: 0x240) on which the external Ethernet
169can be accessed.
170
171@item int irno
172The interrupt number of the external Ethernet controller.
173
174@item int bpar
175The address of the shared memory on the external Ethernet controller.
176
177
178@end table
179
180@subsection Network device configuration
181Network devices are specified and configured by declaring and initializing a
182@code{struct rtems_bsdnet_ifconfig} structure for each network device.
183
184The structure entries are described in the following table.  An application
185which uses a single network interface, gets network configuration information
186from a BOOTP/DHCP server, and uses the default values for all driver
187parameters needs to initialize only the first two entries in the
188structure.
189
190@table @code
191@item char *name
192The full name of the network device.  This name consists of the
193driver name and the unit number (e.g. @code{"scc1"}).
194The @code{bsp.h} include file usually defines RTEMS_BSP_NETWORK_DRIVER_NAME as
195the name of the primary (or only) network driver.
196
197@item int (*attach)(struct rtems_bsdnet_ifconfig *conf)
198The address of the driver @code{attach} function.   The network
199initialization function calls this function to configure the driver and
200attach it to the network stack.
201The @code{bsp.h} include file usually defines RTEMS_BSP_NETWORK_DRIVER_ATTACH as
202the name of the  attach function of the primary (or only) network driver.
203
204@item struct rtems_bsdnet_ifconfig *next
205A pointer to the network device configuration structure for the next network
206interface, or @code{NULL} if this is the configuration structure of the
207last network interface.
208
209@item char *ip_address
210The Internet address of the device,
211specified in `dotted decimal' (@code{129.128.4.2}) form, or @code{NULL}
212if the device configuration information is being obtained from a
213BOOTP/DHCP server.
214
215@item char *ip_netmask
216The Internet inetwork mask of the device,
217specified in `dotted decimal' (@code{255.255.255.0}) form, or @code{NULL}
218if the device configuration information is being obtained from a
219BOOTP/DHCP server.
220
221
222@item void *hardware_address
223The hardware address of the device, or @code{NULL} if the driver is
224to obtain the hardware address in some other way (usually  by reading
225it from the device or from the bootstrap ROM).
226
227@item int ignore_broadcast
228Zero if the device is to accept broadcast packets, non-zero if the device
229is to ignore broadcast packets.
230
231@item int mtu
232The maximum transmission unit of the device, or zero if the driver
233is to choose a default value (typically 1500 for Ethernet devices).
234
235@item int rbuf_count
236The number of receive buffers to use, or zero if the driver is to
237choose a default value
238
239@item int xbuf_count
240The number of transmit buffers to use, or zero if the driver is to
241choose a default value
242Keep in mind that some network devices may use 4 or more
243transmit descriptors for a single transmit buffer.
244
245@end table
246
247A complete network configuration specification can be as simple as the one
248shown in the following example.
249This configuration uses a single network interface, gets
250network configuration information
251from a BOOTP/DHCP server, and uses the default values for all driver
252parameters.
253
254@example
255static struct rtems_bsdnet_ifconfig netdriver_config = @{
256        RTEMS_BSP_NETWORK_DRIVER_NAME,
257        RTEMS_BSP_NETWORK_DRIVER_ATTACH
258@};
259struct rtems_bsdnet_config rtems_bsdnet_config = @{
260        &netdriver_config,
261        rtems_bsdnet_do_bootp,
262@};
263@end example
264
265
266@subsection Network initialization
267The networking tasks must be started before any network I/O operations
268can be performed. This is done by calling:
269
270
271@example
272rtems_bsdnet_initialize_network ();
273@end example
274
275This function is declared in @code{rtems/rtems_bsdnet.h}.
276t returns 0 on success and -1 on failure with an error code
277in @code{errno}.  It is not possible to undo the effects of
278a partial initialization, though, so the function can be
279called only once irregardless of the return code.  Consequently,
280if the condition for the failure can be corrected, the
281system must be reset to permit another network initialization
282attempt.
283
284
285
286@section Application Programming Interface
287
288The RTEMS network package provides almost a complete set of BSD network
289services.  The network functions work like their BSD counterparts
290with the following exceptions:
291
292@itemize @bullet
293@item A given socket can be read or written by only one task at a time.
294
295@item The @code{select} function only works for file descriptors associated
296with sockets.
297
298@item You must call @code{openlog} before calling any of the @code{syslog} functions.
299
300@item @b{Some of the network functions are not thread-safe.}
301For example the following functions return a pointer to a static
302buffer which remains valid only until the next call:
303
304@table @code
305@item gethostbyaddr
306@item gethostbyname
307@item inet_ntoa
308(@code{inet_ntop} is thread-safe, though).
309@end table
310
311@item The RTEMS network package gathers statistics.
312
313@item Addition of a mechanism to "tap onto" an interface
314and monitor every packet received and transmitted.
315
316@item Addition of @code{SO_SNDWAKEUP} and @code{SO_RCVWAKEUP} socket options.
317
318@end itemize
319
320Some of the new features are discussed in more detail in the following
321sections.
322
323@subsection Network Statistics
324
325There are a number of functions to print statistics gathered by
326the network stack.
327These function are declared in @code{rtems/rtems_bsdnet.h}.
328
329@table @code
330@item rtems_bsdnet_show_if_stats
331Display statistics gathered by network interfaces.
332
333@item rtems_bsdnet_show_ip_stats
334Display IP packet statistics.
335
336@item rtems_bsdnet_show_icmp_stats
337Display ICMP packet statistics.
338
339@item rtems_bsdnet_show_tcp_stats
340Display TCP packet statistics.
341
342@item rtems_bsdnet_show_udp_stats
343Display UDP packet statistics.
344
345@item rtems_bsdnet_show_mbuf_stats
346Display mbuf statistics.
347
348@item rtems_bsdnet_show_inet_routes
349Display the routing table.
350
351@end table
352
353@subsection Tapping Into an Interface
354
355RTEMS add two new ioctls to the BSD networking code:
356SIOCSIFTAP and SIOCGIFTAP.  These may be used to set and get a
357@i{tap function}.  The tap function will be called for every
358Ethernet packet received by the interface.
359
360These are called like other interface ioctls, such as SIOCSIFADDR.
361When setting the tap function with SIOCSIFTAP, set the ifr_tap field
362of the ifreq struct to the tap function.  When retrieving the tap
363function with SIOCGIFTAP, the current tap function will be returned in
364the ifr_tap field.  To stop tapping packets, call SIOCSIFTAP with a
365ifr_tap field of 0.
366
367The tap function is called like this:
368
369@example
370int tap (struct ifnet *, struct ether_header *, struct mbuf *)
371@end example
372
373The tap function should return 1 if the packet was fully handled, in
374which case the caller will simply discard the mbuf.  The tap function
375should return 0 if the packet should be passed up to the higher
376networking layers.
377
378The tap function is called with the network semaphore locked.  It must
379not make any calls on the application levels of the networking level
380itself.  It is safe to call other non-networking RTEMS functions.
381
382@subsection Socket Options
383
384RTEMS adds two new @code{SOL_SOCKET} level options for @code{setsockopt} and
385@code{getsockopt}: @code{SO_SNDWAKEUP} and @code{SO_RCVWAKEUP}.  For both, the
386option value should point to a sockwakeup structure.  The sockwakeup
387structure has the following fields:
388
389@example
390@group
391  void    (*sw_pfn) (struct socket *, caddr_t);
392  caddr_t sw_arg;
393@end group
394@end example
395
396These options are used to set a function to be called when there is
397data available from the socket (@code{SO_RCVWAKEUP}) and when there is space
398available to accept data written to the socket (@code{SO_SNDWAKEUP}).
399
400If @code{setsockopt} is called with the @code{SO_RCVWAKEUP} option, and the
401@code{sw_pfn} field is not zero, then when there is data
402available to be read from
403the socket, the function pointed to by the @code{sw_pfn} field will be
404called.  A pointer to the socket structure will be passed as the first
405argument to the function.  The @code{sw_arg} field set by the
406@code{SO_RCVWAKEUP} call will be passed as the second argument to the function.
407
408If @code{setsockopt} is called with the @code{SO_SNDWAKEUP}
409function, and the @code{sw_pfn} field is not zero, then when
410there is space available to accept data written to the socket,
411the function pointed to by the @code{sw_pfn} field
412will be called.  The arguments passed to the function will be as with
413@code{SO_SNDWAKEUP}.
414
415When the function is called, the network semaphore will be locked.
416The function must be careful not to call any networking functions.  It
417is OK to call an RTEMS function; for example, it is OK to send an
418RTEMS event.
419
420The purpose of these functions is to permit a more efficient
421alternative to the select call when dealing with a large number of
422sockets.
423
424@subsection Adding an IP Alias
425
426The following code snippet adds an IP alias:
427
428@example
429void addAlias(const char *pName, const char *pAddr, const char *pMask)
430@{
431  struct ifaliasreq      aliasreq;
432  struct sockaddr_in    *in;
433
434  /* initialize alias request */
435  memset(&aliasreq, 0, sizeof(aliasreq));
436  sprintf(aliasreq.ifra_name, pName);
437
438  /* initialize alias address */
439  in = (struct sockaddr_in *)&aliasreq.ifra_addr;
440  in->sin_family = AF_INET;
441  in->sin_len    = sizeof(aliasreq.ifra_addr);
442  in->sin_addr.s_addr = inet_addr(pAddr);
443
444  /* initialize alias mask */
445  in = (struct sockaddr_in *)&aliasreq.ifra_mask;
446  in->sin_family = AF_INET;
447  in->sin_len    = sizeof(aliasreq.ifra_mask);
448  in->sin_addr.s_addr = inet_addr(pMask);
449
450  /* call to setup the alias */
451  rtems_bsdnet_ifconfig(pName, SIOCAIFADDR, &aliasreq);
452@}
453@end example
454
455Thanks to @uref{mailto:mikes@@poliac.com,Mike Seirs} for this example
456code.
457
458@subsection Adding a Default Route
459
460The function provided in this section is functionally equivalent to
461the command @code{route add default gw yyy.yyy.yyy.yyy}:
462
463@example
464void mon_ifconfig(int argc, char *argv[],  unsigned32 command_arg,
465                  boolean verbose)
466@{
467    struct sockaddr_in  ipaddr;
468    struct sockaddr_in  dstaddr;
469    struct sockaddr_in  netmask;
470    struct sockaddr_in  broadcast;
471    char               *iface;
472    int                 f_ip        = 0;
473    int                 f_ptp       = 0;
474    int                 f_netmask   = 0;
475    int                 f_up        = 0;
476    int                 f_down      = 0;
477    int                 f_bcast     = 0;
478    int                 cur_idx;
479    int                 rc;
480    int                 flags;
481
482    bzero((void*) &ipaddr, sizeof(ipaddr));
483    bzero((void*) &dstaddr, sizeof(dstaddr));
484    bzero((void*) &netmask, sizeof(netmask));
485    bzero((void*) &broadcast, sizeof(broadcast));
486   
487    ipaddr.sin_len = sizeof(ipaddr);
488    ipaddr.sin_family = AF_INET;
489   
490    dstaddr.sin_len = sizeof(dstaddr);
491    dstaddr.sin_family = AF_INET;
492   
493    netmask.sin_len = sizeof(netmask);
494    netmask.sin_family = AF_INET;
495   
496    broadcast.sin_len = sizeof(broadcast);
497    broadcast.sin_family = AF_INET;
498   
499    cur_idx = 0;
500    if (argc <= 1) @{
501        /* display all interfaces */
502        iface = NULL;
503        cur_idx += 1;
504    @} else @{
505        iface = argv[1];
506        if (isdigit(*argv[2])) @{
507            if (inet_pton(AF_INET, argv[2], &ipaddr.sin_addr) < 0) @{
508                printf("bad ip address: %s\n", argv[2]);
509                return;
510            @}
511            f_ip = 1;
512            cur_idx += 3;
513        @} else @{
514            cur_idx += 2;
515        @}
516    @}
517   
518    if ((f_down !=0) && (f_ip != 0)) @{
519        f_up = 1;
520    @}
521   
522    while(argc > cur_idx) @{
523        if (strcmp(argv[cur_idx], "up") == 0) @{
524            f_up = 1;
525            if (f_down != 0) @{
526                printf("Can't make interface up and down\n");
527            @}
528        @} else if(strcmp(argv[cur_idx], "down") == 0) @{
529            f_down = 1;
530            if (f_up != 0) @{
531                printf("Can't make interface up and down\n");
532            @}
533        @} else if(strcmp(argv[cur_idx], "netmask") == 0) @{
534            if ((cur_idx + 1) >= argc) @{
535                printf("No netmask address\n");
536                return;
537            @}
538            if (inet_pton(AF_INET, argv[cur_idx+1], &netmask.sin_addr) < 0) @{
539                printf("bad netmask: %s\n", argv[cur_idx]);
540                return;
541            @}
542            f_netmask = 1;
543            cur_idx += 1;
544        @} else if(strcmp(argv[cur_idx], "broadcast") == 0) @{
545            if ((cur_idx + 1) >= argc) @{
546                printf("No broadcast address\n");
547                return;
548            @}
549            if (inet_pton(AF_INET, argv[cur_idx+1], &broadcast.sin_addr) < 0) @{
550                printf("bad broadcast: %s\n", argv[cur_idx]);
551                return;
552            @}
553            f_bcast = 1;
554            cur_idx += 1;
555        @} else if(strcmp(argv[cur_idx], "pointopoint") == 0) @{
556            if ((cur_idx + 1) >= argc) @{
557                printf("No pointopoint address\n");
558                return;
559            @}
560            if (inet_pton(AF_INET, argv[cur_idx+1], &dstaddr.sin_addr) < 0) @{
561                printf("bad pointopoint: %s\n", argv[cur_idx]);
562                return;
563            @}
564           
565            f_ptp = 1;
566            cur_idx += 1;
567        @} else @{
568            printf("Bad parameter: %s\n", argv[cur_idx]);
569            return;
570        @}
571       
572        cur_idx += 1;
573    @}
574   
575    printf("ifconfig ");
576    if (iface != NULL) @{
577        printf("%s ", iface);
578        if (f_ip != 0) @{
579            char str[256];
580            inet_ntop(AF_INET, &ipaddr.sin_addr, str, 256);
581            printf("%s ", str);
582        @}
583       
584        if (f_netmask != 0) @{
585            char str[256];
586            inet_ntop(AF_INET, &netmask.sin_addr, str, 256);
587            printf("netmask %s ", str);
588        @}
589       
590        if (f_bcast != 0) @{
591            char str[256];
592            inet_ntop(AF_INET, &broadcast.sin_addr, str, 256);
593            printf("broadcast %s ", str);
594        @}
595       
596        if (f_ptp != 0) @{
597            char str[256];
598            inet_ntop(AF_INET, &dstaddr.sin_addr, str, 256);
599            printf("pointopoint %s ", str);
600        @}
601       
602        if (f_up != 0) @{
603            printf("up\n");
604        @} else if (f_down != 0) @{
605            printf("down\n");
606        @} else @{
607            printf("\n");
608        @}
609    @}
610   
611    if ((iface == NULL) || ((f_ip == 0) && (f_down == 0) && (f_up == 0))) @{
612        rtems_bsdnet_show_if_stats();
613        return;
614    @}
615   
616    flags = 0;
617    if (f_netmask) @{
618        rc = rtems_bsdnet_ifconfig(iface, SIOCSIFNETMASK, &netmask);
619        if (rc < 0) @{
620            printf("Could not set netmask: %s\n", strerror(errno));
621            return;
622        @}
623    @}
624   
625    if (f_bcast) @{
626        rc = rtems_bsdnet_ifconfig(iface, SIOCSIFBRDADDR, &broadcast);
627        if (rc < 0) @{
628            printf("Could not set broadcast: %s\n", strerror(errno));
629            return;
630        @}
631    @}
632   
633    if (f_ptp) @{
634        rc = rtems_bsdnet_ifconfig(iface, SIOCSIFDSTADDR, &dstaddr);
635        if (rc < 0) @{
636            printf("Could not set destination address: %s\n", strerror(errno));
637            return;
638        @}
639        flags |= IFF_POINTOPOINT;
640    @}
641   
642    /* This must come _after_ setting the netmask, broadcast addresses */   
643    if (f_ip) @{
644        rc = rtems_bsdnet_ifconfig(iface, SIOCSIFADDR, &ipaddr);
645        if (rc < 0) @{
646            printf("Could not set IP address: %s\n", strerror(errno));
647            return;
648        @}
649    @}
650   
651    if (f_up != 0) @{
652        flags |= IFF_UP;
653    @}
654   
655    if (f_down != 0) @{
656        printf("Warning: taking interfaces down is not supported\n");
657    @}
658   
659    rc = rtems_bsdnet_ifconfig(iface, SIOCSIFFLAGS, &flags);
660    if (rc < 0) @{
661        printf("Could not set interface flags: %s\n", strerror(errno));
662        return;
663    @}
664@}
665
666
667
668void mon_route(int argc, char *argv[],  unsigned32 command_arg,
669               boolean verbose)
670@{
671    int                cmd;
672    struct sockaddr_in dst;
673    struct sockaddr_in gw;
674    struct sockaddr_in netmask;
675    int                f_host;
676    int                f_gw       = 0;
677    int                cur_idx;
678    int                flags;
679    int                rc;
680   
681    memset(&dst, 0, sizeof(dst));
682    memset(&gw, 0, sizeof(gw));
683    memset(&netmask, 0, sizeof(netmask));
684   
685    dst.sin_len = sizeof(dst);
686    dst.sin_family = AF_INET;
687    dst.sin_addr.s_addr = inet_addr("0.0.0.0"); 
688   
689    gw.sin_len = sizeof(gw);
690    gw.sin_family = AF_INET;
691    gw.sin_addr.s_addr = inet_addr("0.0.0.0");
692   
693    netmask.sin_len = sizeof(netmask);
694    netmask.sin_family = AF_INET;
695    netmask.sin_addr.s_addr = inet_addr("255.255.255.0");
696   
697    if (argc < 2) @{
698        rtems_bsdnet_show_inet_routes();
699        return;
700    @}
701   
702    if (strcmp(argv[1], "add") == 0) @{
703        cmd = RTM_ADD;
704    @} else if (strcmp(argv[1], "del") == 0) @{
705        cmd = RTM_DELETE;
706    @} else @{
707        printf("invalid command: %s\n", argv[1]);
708        printf("\tit should be 'add' or 'del'\n");
709        return;
710    @}
711   
712    if (argc < 3) @{
713        printf("not enough arguments\n");
714        return;
715    @}
716   
717    if (strcmp(argv[2], "-host") == 0) @{
718        f_host = 1;
719    @} else if (strcmp(argv[2], "-net") == 0) @{
720        f_host = 0;
721    @} else @{
722        printf("Invalid type: %s\n", argv[1]);
723        printf("\tit should be '-host' or '-net'\n");
724        return;
725    @}
726   
727    if (argc < 4) @{
728        printf("not enough arguments\n");
729        return;
730    @}
731   
732    inet_pton(AF_INET, argv[3], &dst.sin_addr);
733   
734    cur_idx = 4;
735    while(cur_idx < argc) @{
736        if (strcmp(argv[cur_idx], "gw") == 0) @{
737            if ((cur_idx +1) >= argc) @{
738                printf("no gateway address\n");
739                return;
740            @}
741            f_gw = 1;
742            inet_pton(AF_INET, argv[cur_idx + 1], &gw.sin_addr);
743            cur_idx += 1;
744        @} else if(strcmp(argv[cur_idx], "netmask") == 0) @{
745            if ((cur_idx +1) >= argc) @{
746                printf("no netmask address\n");
747                return;
748            @}
749            f_gw = 1;
750            inet_pton(AF_INET, argv[cur_idx + 1], &netmask.sin_addr);
751            cur_idx += 1;
752        @} else @{
753            printf("Unknown argument\n");
754            return;
755        @}
756        cur_idx += 1;
757    @}
758   
759    flags = RTF_STATIC;
760    if (f_gw != 0) @{
761        flags |= RTF_GATEWAY;
762    @}
763    if (f_host != 0) @{
764        flags |= RTF_HOST;
765    @}
766
767    rc = rtems_bsdnet_rtrequest(cmd, &dst, &gw, &netmask, flags, NULL);
768    if (rc < 0) @{
769        printf("Error adding route\n");
770    @}
771@}
772@end example
773
774Thanks to @uref{mailto:jtm@@smoothmsmoothie.com,Jay Monkman} for this example
775code.
776
777@subsection Time Synchronization Using NTP
778
779@example
780int rtems_bsdnet_synchronize_ntp (int interval, rtems_task_priority priority);
781@end example
782
783If the interval argument is 0 the routine synchronizes the RTEMS time-of-day
784clock with the first NTP server in the rtems_bsdnet_ntpserve array and
785returns.  The priority argument is ignored.
786
787If the interval argument is greater than 0, the routine also starts an
788RTEMS task at the specified priority and polls the NTP server every
789`interval' seconds.  NOTE: This mode of operation has not yet been
790implemented.
791
792On successful synchronization of the RTEMS time-of-day clock the routine
793returns 0.  If an error occurs a message is printed and the routine returns -1
794with an error code in errno.
795There is no timeout -- if there is no response from an NTP server the
796routine will wait forever.
797
798
799
800
Note: See TracBrowser for help on using the repository browser.