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

4.115am
Last change on this file since ca49bfd was ca49bfd, checked in by Amar Takhar <verm@…>, on 01/16/16 at 23:26:00

Split document.

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