source: rtems-docs/networking/using_networking_rtems_app.rst @ b412038

4.115am
Last change on this file since b412038 was b412038, checked in by Chris Johns <chrisj@…>, on 04/11/16 at 03:53:58

Clean up and review of Networking User Guide.

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