VxWorks / Tornado II FAQ


4. Network

4.1 Configuration problems

4.2 ARP

4.3 DHCP

4.4 FTP and TFTP

4.5 PPP

4.5.1 PPP on Windows 95

4.5.2 PPP on Windows NT

4.5.3 PPP on Solaris

4.6 Sockets

4.7 Telnet

4.8 Other network related questions

Index


4. Network

4.1 Configuration problems

Q: How can I make my target vissible from other subnets?

A: Add the following line to usrNetInit():

      if (params.gad[0] != EOS) routeAdd("0.0.0.0", params.gad);
    

The nice thing about doing it this way is your default route will always be to the gateway you enter at the boot prompt, so if you ever change that the default route will automatically follow.
(From: David E. Chavez)


Q: What is the correct sequence of function calls to install multiple END drivers and attach them to protocols

A: First make sure you have the extra interfaces in the table in confignet.h.
Then just look at the code in usrNetwork.c that brings up the boot device, and copy that to another function. Then you can call that function from usrRoot(), or the command line, or whenever...
Below is an example of this:

/*
 * attach_if does the magic to attach an interface to the TCP/IP stack,
 * aka the SENS stack.  The code was gleaned from usrNetInit() in
 * usrNetwork.c.
 */
STATUS attach_if(char *dev, int unit, char *ipaddr)
{
    int netmask = 0xffffff00;
    char dbuf[32], addrbuf[32];
    UINT32 checkipaddr = 0;

    printf("Enter attach_if for %s%d\n", dev, unit);

    if (*ipaddr == NULL)
    {
        printf("attach_if: NULL IP Addr for device %s%d\n", dev, unit);
        return(ERROR);
    }
    if (inet_addr(ipaddr) == 0)
    {   
        printf("attach_if: IP Addr = 0 for device %s%d\n", dev, unit);
        return(ERROR);
    }
    memset(dbuf, 0, sizeof(dbuf));
    memset(addrbuf, 0, sizeof(addrbuf));
    sprintf(dbuf,"%s%d",dev,unit);
    ifAddrGet(dbuf, addrbuf);
    checkipaddr = inet_addr(addrbuf);
    if (checkipaddr != 0)
    {
        printf("Interface %s already up - returning\n",dbuf);
        return 0;
    }

    /* Find the END_OBJ associated with it. */
    pEnd = endFindByName(dev, unit);
    if (pEnd == NULL)
    {
        printf("endFindByName failed for bootDev: %s unit %d !\n",
               dev, unit);
        return(ERROR);
    }
    if (muxIoctl(pEnd, EIOCGMIB2, (caddr_t) &endM2Tbl) == ERROR)
        return(ERROR);
    if (ipAttach(unit, dev) != OK)
    {
        logMsg("Failed to attach to device %s",
               (int)dev, 2, 3, 4, 5, 6);
        return(ERROR);
    }
    sprintf(dbuf,"%s%d",dev,unit);
    bootNetmaskExtract (ipaddr, (int *) &netmask); 
    if (usrNetIfConfig (dev, unit, ipaddr, dbuf, netmask) !=OK)
    {
        printf("attach_if: usrNetIfConfig failed for %s%d addr %s mask 0x%x\n",
               dev, unit, ipaddr, netmask);
        return(ERROR);
    }
    printf("Attached TCP/IP interface to %s%d with addr %s\n", dev, unit, ipaddr);
    return(OK);
}  /* end attach_if */
    

Be aware that you can not re-use the "unit number", even if you have different devices. VxWorks does not support the notion of a "minor" number when assigning network interfaces, only "major" numbers. These are the numbers in the END table in confignet.h, and must all be distinct. This does not mean you need multiple copies of the driver code - you still check the unit number in the driver and all that. I.e. on an 8260 with networks on the SCCs and FCCs, you can't have scc0 and fcc0, the unit number for any network interface must be unique.
(From: Dan, gold@ensemble.com, and Brian St. Pierre)


Q: How do I disable IP packet forwarding from one interface to another?

A: Edit target/h/netLib.h and change:

#define IP_FLAGS_DFLT           (IP_DO_FORWARDING | IP_DO_REDIRECT | \
                                 IP_DO_CHECKSUM_SND | IP_DO_CHECKSUM_RCV)
    
to:
#define IP_FLAGS_DFLT           (/* IP_DO_FORWARDING | */ IP_DO_REDIRECT | \
                                 IP_DO_CHECKSUM_SND | IP_DO_CHECKSUM_RCV)
    

(or do something else that has the same effect).
(From David Laight, dsl@tadpole.co.uk)


Q: How can I tune the performance of the network stack?

A: More information about this can be found in the following documents:

together with this source file: utilities.c.
(From: DrDiags, drdiags@covad.net)


Q: How do I change the MAC-address of an interface?

A: This answer consists of 2 parts, the first part describes how to change the MAC-address itself, the second part describes how to propagate this change onto the network.


I had to resolve this problem a while ago - in my case the result of someone removing one pcmcia network card and later adding a second.
On removal I call ipDetach() then ipAttach() and usrNetIfConfig() when a new card is installed. (I don't even attempt to remove the driver from the mux. I'm not that brave.)
Anyway during the remove I remove everything from the arp table and route table. (arpFlush() and ifRouteDelete() get most of them).
However in order to generate correct ARP responses it is necessary to hack the relevant data area - vxWorks arp only requests the MAC address when an interface is linked. The following code will update the data item:

    IP_DRV_CTRL *ip_info;
    int unit;
    extern int ipMaxUnits;

    for (unit = 0; unit < ipMaxUnits; unit++) {
        ip_info = ipDrvCtrl + unit;
        if (strcmp( if_name, ip_info->idr.ac_if.if_name ))
            continue;
        if (if_unit != ip_info->idr.ac_if.if_unit)
            continue;

        bcopy( new_address, ip_info->idr.ac_enaddr, 6 );
        break;
    }
    

(From David Laight, dsl@tadpole.co.uk)

Now you have to wait 5-20 minutes for the ARP tables on all the machines on the local LAN to time out their entry for your IP address. OR you need to broadcast an unsolicited or gratuitous ARP to update their ARP tables.
There are a few ways you can do this:

(From: James Marshall, james_marshall@agilent.com)


Q: How to delelte a IP address added by ifAddrAdd()

A: The vxWorks routing API sucks because it is buggy. I have had myriad problems with the mRoute* functions, so I refuse to use them anymore. ifAddrAdd works OK as long as you don't have any special needs. If you need to add an address to a point-to-point interface, for example, ifAddrAdd doesn't work.
However, the underlying Berkeley API works just fine and is flexible and powerful. It's less user-friendly, but that's a small price to pay for gaining the advantage of having code that actually works.
Here is an example of using the underlying API to implement the function that you need. And, yes, it is appalling that WRS did not supply a function that is orthogonal to ifAddrAdd.

STATUS ifAddrDel(char *pDevName, char *pIfAddr)
{
    int           sockFd;
    int           err;
    struct ifreq  ifr;
    u_long        ifAddr;

    /*
     * Convert string to int
     */
    ifAddr = inet_addr(pIfAddr);

    bzero ( (char *)&ifr, sizeof( struct ifreq ) );
    strcpy(ifr.ifr_name, pDevName);

    /* the interface address to delete is ifAddr */
    ifr.ifr_addr.sa_len = sizeof( struct sockaddr_in );
    ((struct sockaddr_in *)&ifr.ifr_addr)->sin_family = AF_INET;
    ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr = ifAddr;

    if( (sockFd = socket( AF_INET, SOCK_RAW, 0 )) == NULL ){   /* 2, 3, 0 */
        printf("ifAddrDel: couldn't open socket\n");
        return( ERROR );
    }

    /*
     * SIOCDIFADDR can be found in sys/ioctl.h. This is:
     * Socket IOControl Delete InterFace ADDress
     *
     * ioctl returns 0 on success, error code on failure
     */
    err = ioctl( sockFd, SIOCDIFADDR, (int)&ifr );

    close( sockFd );

    if( err ){
        printf("ifAddrDel: ioctl failed with error %d\n", err);
        return( ERROR );
    }

    return( OK );
}
    
(From: Victor Sperry, vsperry@paradyne.com)

Another solution from Gabi (gabi@tdsoft.com) to change the IP address of an interface:

#include <inetLib.h>
#include <arpLib.h>
#include <ipProto.h>
#include <routeLib.h>
#include <ifLib.h>
#include <hostLib.h>
extern STATUS ipDetach (int , char *);

#define M_ASSERT_RET(Cond,String) if (!(Cond)){ \
       printf("\r\nERROR IN FILE %s Line : %d - %s\r\n",__FILE__,__LINE__,(String)); return(ERROR);}
#define M_ASSERT(Cond,String) if ((Cond)==FALSE) \
       printf("\r\nERROR IN FILE %s Line : %d - %s\r\n",__FILE__,__LINE__,(String))
static BOOL   V_Debug = FALSE;
#define M_PRINT_DIBUG(String) if (V_Debug) printf("\r\n%s\r\n",(String));

/***************************************************************
 * Function Name: SYS_F_RenameDebugFlag
 * Description: Rename debug flag control.
 * Input: Flag [TRUE/FALSE]
 * Output: None
 * Return Value: None
 ***************************************************************/
void SYS_F_RenameDebugFlag (BOOL Flag)
{
        V_Debug = Flag;
}
/***************************************************************
 * Function Name: SYS_F_RenameIpAdrs
 * Description: Rename the IP address on the fly.
 * Input: pNetDevName(for ex' "fec"),DevNum(for ex' 1),newIpAddress,new subnet mask,GatwayIp
 * Output: None
 * Return Value: [OK/ERROR]
 ***************************************************************/
STATUS SYS_F_RenameIpAdrs (char *pNetDevName, int DevNum,char *pNewDevAddr,UINT32  SubNetMask,char *GatwayIp)
{
    char OldNetDevAddrs [INET_ADDR_LEN ];
    char NetWorkAddrs [INET_ADDR_LEN ];
    char ifname [20],targetName[20];
        STATUS hostOK;
        /* check parameters for validity */
        M_ASSERT_RET(pNetDevName[0]!=EOS&&pNewDevAddr[0]!=EOS,"Valid init parameters");


    /* build interface name */
    sprintf (ifname, "%s%d", pNetDevName, DevNum);

        /* get the old ipAddress & check if the interface attach */
        if (ifAddrGet(ifname,OldNetDevAddrs)==OK)
        {
           M_PRINT_DIBUG("Interface exsist!\r\n");

           if (V_Debug) 
           {
              printf("Table before modify the IP!\r\n");
              arpShow();
                  routeShow();
                  hostShow();
           }
           /* get the network address */
           inet_netof_string(OldNetDevAddrs,NetWorkAddrs);
           /* flush arp table */
           arpFlush();
           M_PRINT_DIBUG("Preform arpFlush!");
           /* delete any relevant arp to NetDev */
           arpDelete(OldNetDevAddrs);
           M_PRINT_DIBUG("Preform arpDelete!");
           /* delete the Host from the Host table */
           if ((hostOK=hostGetByAddr(inet_addr(OldNetDevAddrs),targetName))==OK)
              M_ASSERT(hostDelete(targetName,OldNetDevAddrs)==OK,"Fail to clear the host table");
           M_PRINT_DIBUG("Preform hostDelete!");
           /* detach the interface */
           M_ASSERT_RET(ipDetach(DevNum,pNetDevName)==OK,"Fail to detach");
           M_PRINT_DIBUG("Preform ipDetach!");
           /* delete any route to the interface */
           M_ASSERT(routeDelete(NetWorkAddrs,OldNetDevAddrs)!=ERROR,"Fail to operate routeDelete to NetWorkAddrs");
           M_PRINT_DIBUG("Preform routeDelete");
           /* delete any route to the interface */
           M_ASSERT(ifRouteDelete(pNetDevName,DevNum)!=ERROR,"Fail to operate ifRouteDelete,an interface is not specified");
           M_PRINT_DIBUG("Preform ifRouteDelete!");
           /* check if gateway define */
           if (strcmp(GatwayIp ,"0.0.0.0") && strcmp(GatwayIp ,"")) 
           {  
               routeDelete("0.0.0.0", GatwayIp);
           }
           else
           {
                   printf("Gatway not define!\r\n");
           }            
        }
        else
           M_PRINT_DIBUG("Interface Not exsist!\r\n");

        /* attach the interface */
        M_ASSERT_RET(ipAttach(DevNum,pNetDevName)==OK,"Fail to attach to the interface");
    M_PRINT_DIBUG("Preform ipAttach!");
        /* set the new IP address */
        M_ASSERT(ifMaskSet(ifname, SubNetMask)==OK,"Fail to set the subnetmask to the interface");

    /* set inet address */
    M_ASSERT(ifAddrSet(ifname, pNewDevAddr)==OK,"Fail to set inet address");

    /* add host name to host table */
        if (hostOK==OK)
           M_ASSERT(hostAdd (targetName, pNewDevAddr)==OK,"Fail to add the target name to host table");

    if ((strcmp(GatwayIp ,"0.0.0.0")!=0) && (strcmp(GatwayIp ,"")!=0))
       M_ASSERT(routeNetAdd("0.0.0.0", GatwayIp)==OK,"Fail to route the GatewayIp 0.0.0.0");
        /* table after modify the IP */
        if (V_Debug) 
        {
           printf("Table after modify the IP!\r\n");
           arpShow();
           routeShow();
           hostShow();
        } return(OK);
}
    


Q: How can I get the default gateway from the bootline to be the default gateway?

A: Thanks to a suggestion by Michael Lawnick I pilfered some code from the bootConfig.c file and threw it into usrAppInit.c. This was to get the gateway from the bootline.... The system now works the way it should from the factory. Here is an excerpt of my code:

#include "vxWorks.h"
#include "bootLib.h"
#include "prjParams.h"

void usrAppInit (void)
{
    BOOT_PARAMS params;

#ifdef USER_APPL_INIT
    USER_APPL_INIT;  /* for backwards compatibility */
#endif
    /* add application specific code here */
    bootStringToStruct (BOOT_LINE_ADRS, &params);
    if ((sysNvRamGet (BOOT_LINE_ADRS, BOOT_LINE_SIZE, 0) == ERROR) ||
        (*BOOT_LINE_ADRS == EOS))
    {
        /* either no non-volatile RAM or empty boot line */
        printf("Adding hardwired gateway\n");
        routeAdd ("0.0.0.0", "155.34.103.1");
    }
    else {
        printf("Adding gateway %s from bootline\n", params.gad);
        routeAdd("0.0.0.0", params.gad);
    }
}
    

(From: Joe Georger, jgeorger@ll.mit.edu)


Q: How do I change the IP address of an interface?

A: There are (at least) 2 ways to do this:


Q: Once every 20 minutes I loose one UDP message.

A: This can be caused by a time-out of the ARP table. When the ARP-table is filled all entries are dynamic. This means that they time-out after 20 minutes. The first packet to be sent after this time-out will generate an ARP request and the other side will respond with an ARP response. So far so good.
But there is a problem when comming to fragmented UDP frames. What happens there is that only the last frame is sent out after the ARP reply is received. This is caused by the fact that there is only buffer space for one frame. The first frame of the UDP message will generate the ARP request, but will be overwritten by all the next frames. When the reply is received only the last frame is still there and will be sent out. (This mechanism is documented!)

But how to solve this problem? The only way I know is to use a static ARP table. If you know what IP addresses you communicate with you should do a manual ARP request, and store the result in the ARP table with the permanent flag set. This way the entry will not time-out.


Q: When I try to connect a lot of interfaces to the Mux it fails with the 8th interface I try to connect.

A: Each interface will bind two protocols, IP and ARP (I believe, do a muxShow for details). So, you need a minimum MUX_MAX_BINDS of 34 (a pair has to be bound to the loopback also) if you are using 16 interfaces.
(From: James Clough, (drdiags@comcast.net)


Q: How do I change the timeout on UDP fragmentation?

A: Redefine the following #define "IPFRAGTTL" in the file tornado\\target\h\netinet\ip.h to the timeout you need.
(From: muralidharan P R, muralipr@ctd.hcltech.com)


Q: How can I get the IP address and port number of an open socket?

A: The file superInetStatShow.c contains an example on how to get information about IP addresses and ports. The output of this progam looks like this:

-> superInetstatShow
Active Internet connections (including servers)
PCB      Proto Recv-Q Send-Q  Local Address      Foreign Address     fd (state)
-------- ----- ------ ------  ------------------ ------------------ --- -------
76d4a2c   TCP       0      0  0.0.0.0.514        0.0.0.0.0           17 LISTEN    
76d48a0   TCP       0      0  0.0.0.0.111        0.0.0.0.0           11 LISTEN    
76d4714   TCP       0      0  0.0.0.0.9323       0.0.0.0.0            8 LISTEN    
76d4504   TCP       0      0  0.0.0.0.9321       0.0.0.0.0            5 LISTEN    
76d49a8   UDP       0      0  0.0.0.0.9368       0.0.0.0.0           16
76d4924   UDP       0      0  0.0.0.0.9306       0.0.0.0.0           15
76d481c   UDP       0      0  0.0.0.0.111        0.0.0.0.0           10
76d4798   UDP       0      0  0.0.0.0.9369       0.0.0.0.0            9
76d4690   UDP       0      0  127.0.0.1.1024     127.0.0.1.17185      7
76d460c   UDP       0      0  0.0.0.0.17185      0.0.0.0.0            6
value = 24 = 0x18
      
(From: Pete Kockritz, pkockritz at mac dot com)


4.2 ARP

Q: On bootup of my system I am getting the following message:

0x7F31990 (tNetTask): arp info overwritten for 8164de37 by 00.e0.16.66.96.52
    

What does this message mean?

A: This has happened because the network stack has updated its ARP entry for a given IP address after detecting that the ethernet address has changed. This normally should not happen in a well configured network....

'8164de37' is in fact the IP address whos ethernet address appears to have changed. eg. 129.100.222.55 in this case, and herein may well lie your problem.

At a guess, this is probably caused by having two hosts somewhere on the same network with the same IP address, one of which you would have in the ARP cache at boot-time - perhaps the boot server?

(From: molochai, molochai@vapour-trail.demon.co.uk)


Q: Does any one know why I get this msg: 0xf7bf88 (tNetTask): arptnew failed on 50f22423

A: The following message was written by Leonid Rosenboim:

An IP packet is being transmitted, and based upon how it matches network interfaces' IP addresses and mask, an outgoing interface is selected, at which point the interface driver calls arpresolve to get a MAC address for that IP address, either by sending an ARP request, or by using a cached entry.

At that point, if the ARP code, looking for an ARP cache entry, finds that this particular IP address has a specific routing entry which is not an ARP entry, it will return that particular error.

Since ARP uses has a common mechanism with the IP routing table, there could not be a routing entry and an ARP entry for the same destination IP address at the same time.

One possible reason for this is if an ICMP Redirect is received for a particuar IP address, which would be considered "local" if matching its address to the network interface's IP address and mask.

mRouteShow() at the time of this error should pretty much paint the picture in bright colour.


Q: How can I change the ARP timeout?

A: There is no official API for changing it that I know of, but you should be able to change the global variable that holds the value of the timeout, in seconds: arpt_keep. Obviously, that is not very safe in terms of future portability, but it should work for you today.
(From: John, john_94501@yahoo.com)


Q: I get the following error: arpresolve: can't allocate llinfo0x4f5a88. What does this mean?

A: The error message "arpresolve: unable to allocate llinfo" may be an indication that you have something wrong with your routing tables, although there may be other causes for this message too. The Tornado 2 network stack is less forgiving of network configuration problems than earlier versions, so you should check your boot parameters (gateway inet) and any routeAdd() calls in your startup to make sure they're correct for your network configuration.
I think the hex number you get may be an IP address associated with the problem, does 136.90.79.00 mean anything to you? That's what 0x4f5a88 comes out to if you byte-swap it and convert to decimal.
(From: Andrew Johnson, anj@aps.anl.gov)


4.3 DHCP

Q: I am trying to implement a DHCP server using vxWorks. To do it we have to implement a lease storage routine and address storage routine. I was wondering if there is any sample code that shows how to implement those routines.

A: A sample lease storage routine which I used to test that hook can be found in this file. This code is not officially supported by WindRiver.
(From: Stephen Macmanus, stephenm@wrs.com)


Q: I have a problem in using the DHCP to get an IP address for the device that I am using.

A: There are some 'enhancements' to the VxWorks DHCP client that you will need if you want it to work under certain circumstances (e.g. at all in our case).
Because it's an enhancement rather than a bug fix (!) you can only get hold of it by asking your WRS contact directly - you won't find it on WindSurf.
But we had exactly this problem - dhcp client refusing to go - and it was fixed by these updated binaries.
(From: Luke Diamand, Diamand@btinternet.com)


Q: When I start a DHCP server on a port other ports stop working after some time.

A: The problem with the standard DHCP server is that it opens a socket for the DHCP channel (port number 67). This channel is used for sending data only. When a DHCP reply from another server is received it is put in the queue, but this queue is never read. The solution is to add a task to read the queue.
This problem and solution is known by WindRiver as SPR 31821. This is not (yet) available on WindSurf, but is available to the support engineers.


Q: After upgrading to Torndado 2.0.2 (aka T2CP4) the Solaris DHCP-server rejects the first 4 discover packets as being "short"
The first 4 packets the vxWorks dhcp client sends out are all 'short', (only 333 bytes long in my case), ending immediately after the outgoing client options.
Packets 5-8 are all 590 bytes long, where the first 333 bytes are identical to the first four packets and all the additional bytes in the packet are zeros - and these packets ARE accepted by the server, so I am successfully booting.
However, this results in an unacceptable and unnecessary delay in the overall dhcp boot process.

A: The difference in the patched DHCP and the previous DHCP versions lies in the differences in the RFC. RFC 2131 allows DHCP options field to have a size equal to the option fields. There is no required minimum on the options field length. The patched client follows RFC 2131.
DHCP servers complying with RFC 1541 do not acknowledge client messages conforming to the new RFC (the long wait).

According to Sun Support this issue is filed as a RFE (4310649) and is likely to get fixed in Solaris 9.
(From: Bruce Crozier, Bruce.Crozier@fci.com)


Q: How can I get a NT server to send the right parameters back after a DHCP request?

A: What you have to do is ask to NT server to send you DHCP configs tags wanted ..
user dhcpcOptionSet ( ) to Add theses options after dhcpcInit and before binding ...

dhcpcOptionSet( pVoidCookie, _DHCP_ROUTER_TAG, 3,  4, NULL ) ;
    

See the RFC for more details on each tag and numbers
(From: "Steeve Gagne, steeve.gagne@simplernetworks.com)


Q: When I enable the DHCP client I cannot connect anymore using WDB.

A: I think I know what happens. Basically, this is a well known problem with SNARF protocol.
Here is a basic explaination:

  1. An end network interface can have at most 1 protocol registered as SNARF (Type 257), which protocol that sees all packets.
  2. The default build in Tornado 2.0 is to have the WDB agent use the End driver connection mode which registers the WDB agent as a SNARF protocol. In this mode, the WDB agent will be able to do system mode debugging over Ethernet.
  3. DHCP client, server and relay and etherInputHookAdd also register as SNARF protocol. However, the implementation of DHCP client, server, and relay preceded end drivers. The initialization of DHCP happens first. The WDB agent is configured after the network is initialized. If DHCP is used, the WDB agent communication setup will fail, and the target server will report RPC core backend timeout.

Solution:
To change how the WDB agent communicates to Tornado, selecting Network connection instead of END connection. In config.h, change "#define WDB_COMM_TYPE WDB_COMM_END" to "#define WDB_COMM_TYPE WDB_COMM_NETWORK"

Tradeoff:
After this change, the WDB agent will NOT be able to do system mode debugging over Ethernet. Only task mode debugging may be performed. If someone prefer system mode debugging sometimes, the DHCP Server must be removed and the WDB agent must be switched back to END connection.
(From: Charlie Zhao, czhao@hns.com)


Q: My target does not accept the DHCP offer.

A: There are a couple of problems with the default DHCP client as provided by WindRiver.

The first problem is that the client only accepts broadcast packets and not the (also allowed) unicast packets. In the DHCP request however the client does not request a broadcast packet (the Broadcast flag in the Flags field is not set).
The reason for this is that VxWorks filters out all messages that are not addressed specifically at its own IP address or broadcasts.

The second problem is the fact that VxWorks does not allow "short" DHCP replies. The replies should have at least the minimum BOOTP message length. If the messages are shorter, which is allowed in the DHCP standard, they are deleted.

Both probems can be fixed if you can get access to the source code (or ask an FAE to do it for you). The first problem can be fixed in the part where the outgoing DHCP message is composed. The second problem has to be fixed in BPF (Berkeley Packet Filtering) section of the DHCP client. Here a default minimum message length is used that is valid for BOOTP, and this minimum should be changed to the right minimum of the DHCP message.


4.4 FTP and TFTP

Q: When I send files to my target using FTP small files fail often, but larger don't have any problem at all.

A: The following was written by Curt McDowell (csm@broadcom.com) in the newsgroup:

I found a long-standing bug in VxWorks ftpLib that appears when transferring very small files from a relatively fast server to a relatively slow client.
Once ftpLib has initiated a transfer, it calls select() on both the control and data connections. It expects the data connection to become ready first. If the control connection becomes ready first, it assumes an error, closes both file descriptors and returns ERROR.
Unfortunately, it also assumes an error if the control and data connections become ready at the same time, which often happens in the conditions mentioned above.
The fix is to change one line in ftpLib.c (in my case 392) from

    if (FD_ISSET (ctrlSock, &readFds))
    

to

    if (FD_ISSET (ctrlSock, &readFds) && ! FD_ISSET (dataSock, &readFds))
    

Apparently there was an SPR opened for this problem about 18 months ago by Paul Banta. Unfortunately nothing ever came of this. Thanks go to Paul Banta, who also experienced the problem and reported in.
In the mean time, I have a version of the routine I call ftpXfer2() which has the same parameters as ftpXfer(). It does not contain any WRS code.
In addition to fixing the small-file flaky transfer problem, it also fixes a bug prohibiting FTP_CONTINUE responses, which allows file renaming to work as follows (error checking omitted):

    int c_fd;

    if (ftpXfer2(host, user, pass, "", "RNFR %s", dir, file_oldname,
                 &c_fd, NULL) == ERROR)
   ...

    if (ftpCommand(c_fd, "RNTO %s", (int) file_newname, 0,
                   0, 0, 0, 0) != FTP_COMPLETE)
   ...

    (void) ftpCommand(c_fd, "QUIT", 0, 0, 0, 0, 0, 0);
    close(c_fd);
    

And now for the code: ftpXfer2.c


Q: What is the meaning of all the ftp global variables?

A: These are the global variables of the FTP server:

(From: Hwa Jin Bae, hjb@pso.com)


Q: How do I change the priority of the TFTP-task?

A: The tftp task is spawned at priority 55, and new incoming connection are spawned at priority 100, you can change this through the global variable tftpdResponsePriority which is initially set to 100.
(From: Stephen Hill, shill@dsl.ftel.co.uk)


Q: Is there source code available for an FTP server?

A: Yes, there is an FTP server included in DosFS2. This is in the unsupported sources tree.


Q: How can I enable the debug information of the FTP server?

A: Set the global variable ftpDebug to 1 and you should get a lot of information.


Q: I am having problems connecting to the Windows XP FTP server.

A: As far as I remember, a collegue of mine had to change the IP-Timeout on XP to a much smaller value in registry. It was set very high by standard installation and the vxWorks-client tries a reconnection on the same port after a reboot. You can change it using the following steps:

  1. Goto HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters in the registry.
  2. Create a new entry called "TcpTimedWaitDelay", type "REG_DWORD"
  3. Give it the value you want, for example 5 for 5 seconds.
(From: Michael Lawnick, michael.lawnick@no_spam_pls.kontron.com)


Q: Ftp Server Bug on PWD command

A: We discovered a bug on the Ftdlib.c (SPR #20768 version) on PWD command management...
Inside the file Ftdlib.c in the ftpdProcessXpwd function, when ftpPathNormalize is called in this way:
ftpPathNormalize (pSlot, ".", pSlot->currPath, pSlot->newPath, NULL, &pSlot->newDirName);
The second parameter is a constant string... ("."). If you look inside the ftpPathNormalize:

LOCAL void ftpPathNormalize
    (
    FTPD_SESSION_DATA   *pSlot,
    char *              path,
    char *              currPath,
    char *              newPath,
    char **             pAbsPath,
    char **             pRelPath
    )
    {
    int relOffset = 0;
...

if (strcmp (path, ".") == 0) /* if we're requesting the current 
                              directory,leave path blank */
 path[0] = EOS; 
...
    

As you can see here they are assigning a new value to a constant string... :)

KABOOOMMM....
If you compile the file with the -Wwrite-strings the compiler complains about that.
(From: fabio.roncadi@gambro.com, Fabio Roncadi)


Q: Is there a maximum size for a file to be transferred using FTP?

A: Files received through FTP by a target are first stored in memory. So the maximum file size for an FTP transfer is the amount of free memory.


Q: Are there security issues with the VxWorks FTP server?

A: It might be possible to make the remote FTP server crash by issuing this command :CEL aaaa(...)aaaaThis problem is similar to the 'aix ftpd' overflow but on embedded vxworks based systems like the 3com nbx IP phone call manager and seems to cause the server to crash.
*** Note that Nessus solely relied on the banner of the remote server to issue this warning.
Solution: If you are using an embedded vxworks product, please contact the OEM vendor and reference WindRiver field patch TSR 296292. If this is the 3com NBX IP Phone call manager, contact 3com.
This affects VxWorks ftpd versions 5.4 and 5.4.2 For more information, see CERT VU 317417 http://www.kb.cert.org/vuls/id/317417 or full security alert at http://www.secnap.net/security/nbx001.html
Risk factor : High
See http://www.securityspace.com/smysecure/catid.html?id=11185


Q: How can I set the default path of the FTP server?

A: Use ioDefPathSet to set the default path
(From: pjl@dolby.com)


4.5 PPP

Q: PPP crashes when I do an FTP-GET from the target with a large number of small files.

A: The WRS support told me to use netStackSysPoolShow() when the problem appears. It shows the following information :

.../...
number of times failed to find space: 1
number of times drained protocols for space: 1
CLUSTER POOL TABLE
                size     clusters  free      usage

-------------------------------------------------------------------------------
                 512      20        0         21
.../...
    

There was not enought 512 bytes buffers in the network stack. So, I increase this setting (in the Tornado builder, I change some "define" in the "network buffer initialization" tab). And it seems to work better now.
(From: Emmanuel Herbreteau, eherbreteau@sepro-robotique.com)


Q: How can I set the username and password when using CHAP?

A: The username CHAP uses is the machine name, so you have to do a sethostname() with the username as the argument. Here's what I do leading up to the pppInit:

  sethostname("our username", strlen(username));
  pppSecretAdd("*", "*", "our password", NULL);
    

(From: John Finley, john@finley.com)


4.5.1 PPP on Windows 95

Q: How do I make a connection between my Windows 95 machine and my target using PPP over a null-modem cable?

A: Windows 95 does not support a null-modem connection in Dial Up networking. To get this working a new device has to be defined. Kevin Wells has written a device driver to create a null modem connection. I modified this driver a bit to get it working with VxWorks. The original page is at http://www.kevin-wells.com/net/. Also the documentation for this driver can be found here.

Now for the installation under VxWorks.
First enable PPP in the configuration. Then download the driver VxWorksPPP.inf. Install this driver using Modems in the "Control Panel". Select "Add...", on the next screen check the "Don't detect my modem" box. Press "Next" and on that screen select "Have disk...". Now enter the path to where the file VxWorksPPP.inf was put. Now select the right communication port and "Next". Windows will now install this modem connection. Go to the properties of this modem. Set the right connection speed. Select the "Connection" tab, and then select the "Advanced" menu. Switch off Flow Control. To see if the link is working "Record a log file" can be checked. Now a logfile named "ModemLog.txt" will be generated in your Windows directory. Close all the windows. (This procedure is described in more detail on the site of Kevin Wells).
Now define a new Dial-up Networking connection using this device. The phone number is not important, as there is no phone line used but a null-modem cable. After this connection is defined go to the properties of this connection, go to the "Server Type" tab and uncheck everything except TCP/IP. Now go to "TCP/IP Settings". Uncheck everything here also. Also select "Server assigned IP address" and "Server assigned name server address". Close all windows using the "OK" button.
Now the PPP server has to be started on VxWorks. This can be done using usrPPPInit or pppInit. The first one uses the default parameters, with the second one a configuration can be specified. Here I will use pppInit.
First a configuration file has to be defined. The different items can be found in the VxWorks Network Programmers Guide, chapter 3.4 and Table 3-3. I use the following file (named PPP_OPT on the target):

debug
driver_debug
no_pap
no_chap
no_vj
lcp_max_configure 10
lcp_echo_interval 30
lcp_echo_failure 5
    

The debug lines can be deleted, but are usefull to see that the connection is working the first time this is done.
First the Dial-up Networking connection should be started. When the window "Connecting to ...." appears with the message "Status: Dialing" start the PPP server on the target. This can be done using this command in the shell:

pppInit(0, "/tyCo/1", "90.0.0.1", "90.0.0.10", 38400, 0, "/D1/PPP_OPT")
    

This opens a PPP connection on serial port 1, using the address 90.0.0.1 as the address of the target and 90.0.0.10 as the address of the Windows 95 machine. The connection speed is 38400 (this should be the same as the selected speed on the Windows 95 machine) and the option file is "PPP_OPT" on device "/D1".

How does this solution work? Windows 95 expects a reply from a modem before it will start the PPP communication. VxWorks starts the PPP communication directly. (This can be observed by starting the PPP server and watching the data on the serial line). To get Windows 95 to start the PPP driver the expected reply has been set to "~" (see the VxWorksPPP.inf file for this). This is the first character of the standard connect string. When VxWorks sends this string it is recognised by Windows 95 as a valid connect string, and the PPP driver is started. From then on the communication is running between VxWorks and Windows 95.
One problem with this solution is that VxWorks has to be sending the connect string. When VxWorks does not send this string no connection can be made. That is the reason why first the Dial-up Networking has to be started and then pppInit.
The "line lcp_max_configure 10" means that VxWorks will be sending 10 configuration requests before the PPP server dies. When the startup sequence is used as given in this example this is OK, but when a system has to monitor the PPP link continuously this value should be increased. I don't know if there is a value that means "contious". Otherwise a task should monitor if the PPP server still exists. If not a call to pppInit has to be made to restart the PPP server.
This solution has been found with the help of Stuart Gray and David Richards from WindRiver Systems.


4.5.2 PPP on Windows NT

Q: How do I make a connection between my Windows NT machine and my target using PPP over a null-modem cable?

A: There is a document from WindRiver, called WTN50.pdf. This is a Tech Note and available through WindSurf on the WindRiver website.


4.5.3 PPP on Solaris

Q: How do I build a network connection using PPP?

A: I managed to get it working on Solaris 8 with PPP, but had to do two things to get it to work that I didn't have to do on Solaris 2.5.1 (both as root):

  1. chmod 666 /tmp/.asppp.fifo (Seems security had been tightened-up.)
  2. ndd -set /dev/ip ip_forwarding 1 (IP forwarding was not on by default.)

(From: Kurt Lloyd, kplloyd@lucent.com)


4.6 Sockets

Q: When I do a send using a socket connection to a second system, and this system crashes, the send still returns OK. How do I detect that the other side has failed?

A: The problem is that this is only detected using a timeout. The default parameters for KEEP ALIVE are set to detect a lost connection after some ridiculously long time like two hours. You can change this time by modifying the values of the variables tcp_keepintvl and tcp_keepidle. See the manual page for setsockopt under the SO_KEEPALIVE option.
(From: Charles H. Chapman, chc@nasa2.ksc.nasa.gov)


Q: After I used a lot of sockets my system stalls for 10 to 15 seconds. What is causing this delay?

A: The odds are that all your sockets are in TIME_WAIT state; each socket that is in TIME_WAIT hangs onto an mbuf or two until it finally expires and releases its resources, so the number of mbufs available limits the number of sockets you can have hanging around. You'll need to increase the network memory pools. You might also care to log into Windsurf and search for the phrase "What is TIME_WAIT? Bind fails with errno 0x30 = EADDRINUSE" or TSR #152244, which should lead you to a useful document.
(From: Dave Korn)

See also 6.4-B.


4.7 Telnet

Q: How can I use my own command line interface using Telnet, instead of using the target shell?

A: Ask your local sales representative and he can provide you with source code to a telnet server that supports the target shell and your own custom thing. It was a component written by their Israel local office.
It's on the FAE FTP site, this is internal and password protected so normal folks can't get to it. If your FAE doesn't know where that is then tell them to go to internal.wrs.com and then follow the links to sales then FAE, after that they can't miss it.
It is free and quite small. It worked for us the same day we got it.
(From: Serge Blais, blais_serge@yahoo.com)


Q: How can I change the priority of the telnet task?

A: Just before the call to telnetInit in prjConfig.c add the line

telnetPriority=XXX
    

where XXX is the new priority of the telnet task.


4.8 Other network related questions

Q: Does anyone point me in what is needed to support development of server/client TCP - BSD stream sockets applications using a NT platform with Microsoft Visual C/C++ (or Visual Studio) ?

A: The following is for MFC applications, see below for console (DOS like) apps:

  1. In the App-Wizard (when creating the project), make sure you check the "include Winsock support" button.
  2. Add the following to initialize the winsock dll (usually put in the OnInitXXX section) :
    //winsock stuff
    #ifdef WIN32
    #define WSOCK_VER 1   /* I have no idea what versions are what! 
                             version 1 seems to work with BSD 4.3 
                             type calls, ver 2 fails on a lot of 
                             machines  */
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;
    
        wVersionRequested = MAKEWORD( WSOCK_VER, 0 );
    
        err = WSAStartup( wVersionRequested, &wsaData );
        if ( err != 0 ) 
        {
            return(1);
        }
    
        /* Confirm that the WinSock DLL supports This version */
        /* Note that if the DLL supports versions greater    */
        /* than WSOCK_VER in addition to WSOCK_VER, it will return */
        /* WSOCK_VER in wVersion since that is the version we      */
        /* requested.                                        */
    
        if ( LOBYTE( wsaData.wVersion ) != WSOCK_VER ||HIBYTE( wsaData.wVersion) != 0 ) 
        {
            return(2);
        }
    #endif
            
  3. use all the regular BSD syntax calls. Look in help if you have problems (a few deviate slightly). Also, don't use iocti. Winsock needs ioctlsocket:
    #ifdef WIN32
        ioctlsocket (fd, FIONREAD, &numbytes);
    #else
        ioctl (fd, FIONREAD, &numbytes);
    #endif
            

If using console application, add the winsock lib to your linker setup (I think it is wsock32.lib) and follow #2 and #3.
(From: Christopher A Leddy, caleddy@west.raytheon.com)


Q: Has anyone succeed using an etherInputHook on an END style ethernet driver?

A: I've noticed on some T2 END ethernet drivers that the EtherHooks mechanism was disabled, i.e. the hook function simply never gets called. Two workarounds are possible for this: one is to use older BSD-style drivers (yes, this does work with the new SENS stack for backwards compatibility) and ether hooks, and the other is to implement a "SNARF" protocol which binds above the END's MUX and in general, provides the same functionality as the etherHooks.
The second solution is detailed in the SENS Network Protocol Toolkit. What they don't tell you is that there can be only one snarf protocol active at one time, and the default VxWorks image already installs such a protocol for what they call "system-mode debugging". Remove this and using the new method becomes almost as easy as the old etherHooks.
(From: Ran Shalgi, http://www.expand.com)


Q: Is there a TCP dump utility available for VxWorks?

A: Take a look at this program. It has been floating around for some time, I don't know the author: vxsniff.c

For PPC there is a precompiled version of snoop provided by Dot21 Real Time Systems. You can acquire the program by going to www.dot21rts.com. In the upper left part of the home page there is a download button. After registering you will be able to download this.
While it is similar to snoop, it is a menu driven system that allows selective capture and triggering of data.


Q: At boottime I get a "dc0 - no carrier" error. What does this mean?

A: I had to download the latest driver from WindRiver and make a change to my sysDec21x40End.c file. Look for the latest driver releases from WindSurf (click on download, tornado 2.0 drivers). That will update your driver binary.

After installing the new driver binary, add the following to the sysDec*.c file in the MV2700 directory:

    sprintf (cp, decParamTemplate,
                 (UINT) (iobaseCsr),     /* device io base */
                 (UINT) PCI_SLV_MEM_BUS, /* pciMemBase */
                  irqvec,                /* interrupt irq vector */
                  irqnum,                /* interrupt irq number */
                /*NET_END_USER_FLAGS);*/
                  NET_END_USER_FLAGS | DEC_USR_MII,
                  8,                     /* phyAddr*/
                  0,                     /*pPhyTbl*/
                                         /*phyFlags*/
                  DEC_USR_MII_10MB | DEC_USR_MII_100MB |
                  DEC_USR_MII_HD | DEC_USR_MII_FD );
    

This will allow the driver to properly negotiate **AND** setup the hardware for the correct mode. If the network link duplex changes while the system is booted, then the system will have to be reset in order for the driver to properly update the hardware settings. Actually, the driver works when changing from half to full but not from full to half.
(From: Greg Willden, gwillden@swri.edu)


Q: Is there any vxworks routine to get the default gateway address on a vxworks target?

A: I haven't seen an API routine, but... The data is globally available in the kernels we use via the bootline parameters:

BOOT_PARAMS params;
extern char *sysBootLine;
if (usrBootLineCrack (sysBootLine, &params) == OK)
{
    if (params.gad[0] != EOS)
    {
        /* it is specified... */
        routeAdd ("0.0.0.0", params.gad);
    }
}
    

(From: Edsel Harrell, eah@raytheon.com)


Q: How do I get the MAC address using the VxWorks API?

A: Here's how I do it:

        UINT8 macBuffer[8];
        sysCpmEnetAddrGet(0, macBuffer);
        MacAddr = nlprintf("0x%02X%02X%02X%02X%02X%02X",
                                                macBuffer[0],
                                                macBuffer[1],
                                                macBuffer[2],
                                                macBuffer[3],
                                                macBuffer[4],
                                                macBuffer[5]);
    

(From: Jim Way, Jway@datum.com)


Q: Is well-known port 7 implemented, and if not, how can I implement this?

A: As far as I know this is not implemented in release 5.4. Our implementation did a readfrom/sendto as this gives you the source address.
Here is the 'work part' of our echo daemon:

struct sockaddr sa;
char buffer[BUFFSIZE];
int i,size;

if((i=recvfrom(s,buffer,sizeof(buffer),0,&sa,&size))) < 0)
        return;
(void) sendto(s,buffer,i,0,&sa,sizeof(sa));
        return;
    

Since the recvfrom is blocking, you just create a SOCK_DGRAM socket and bind it to port 7, then perform the above in a 'while(1)' loop.
From: Michael Baumann, baumann@optivus.com)


Q: When calling netPoolDelete,does the memory get freed?

A: The pNetPool memory will not be freed. It will be bzero'd before netPoolDelete returns. The pPoolStat, if non-null will be freed and the CL_POOL clTbl[CL_TBL_SIZE] will be checked and nulled after freeing entries that have been malloc'd.
(From: DrDiags, drdiags@flashcom.net)


Q: Is there a rsh deamon for VxWorks?

A: Yes, you can find it here: rshd.c
(From: Matt Wette, Matthew.R.Wette@jpl.nasa.gov)


Q: Problems with high speed networks and netTask.

A: I think you might be right about this point. The netJobAdd (and netTask) presents some problems especially in throughput and latency performance when using very high speed networks. I am at least partly responsible for this unfortunately. The problem is a little more involved than just netTask.
One of the reasons why netTask exists is to allow packet handling to happen in task level code. Since most of kernel facilities (e.g. semTake) cannot be called from within interrupt level code, it is necessary to make sure most of packet handling code (TCP/IP stack) happens in task level. Doing a netJobAdd() is one solution for this. netJobAdd() is nothing but a msgQ. You send a message to netTask to do the job (I got a packet, so process it at task level). It also helps to minimize interrupt latency (interrupts are locked out for short time since most of the work is done in task level).
Another reason why netTask exists is because VxWorks TCP/IP stack is not re-entrant. The whole stack runs in non-reentrant fashion. So netTask does a "hack" -- it takes a semaphore, runs code in TCP/IP stack, then yields the semaphore.
These are not good reasons necessarily, but they are what they are.

The performance issues, especially in throughput performance case, are significant. It is possible to think of it this way: you have a system (VxWorks) which tries very hard to minimize interrupt latency and maintain good response time (i.e. real-time). The inherent requirement here goes somewhat against the goal of high throughput. If you have to toggle between interrupt and task level code back and forth for every packet, your interrupt latency is minimized, but you actually do more work per packet. The systems which I have worked on which emphasizes throughput overall do not work this way. The best throughput oriented system (e.g. Network Appliance file server appliances) uses combinations of cooperative multitasking kernel and heuristic (hand-tuned) packet handling / scheduling to maximize throughput while keeping latency low. Such systems also employ very low overhead socket layer (direct access to mbufs from applications).

There are a lot of things to consider when trying for the optimal performance (in both throughput and latency). VxWorks network stack is good, but it is not the best performing stack. If you port Linux or BSD on the same hardware and run TCP/IP benchmarks, you will see that Linux and BSD perform better in general. This is not just the VxWorks network stack issue either. It has to do with the overall architecture of VxWorks, being a real-time system. It has to do certain things that other systems do not. Things like keeping latency low. But in reality, the artificial constraints (code!) turn out the end result which provides small benefit in terms of latency with much larger throughput degradation. This is not to fault VxWorks at all, since it is very good at doing real-time stuff. But a lot of VxWorks usage nowadays is in the area of networking. And networking is not necessarily real-time. The minute you throw TCP/IP and ethernet and what not into your OS, your OS is not really hard real-time, at least from overall perspective.
Since overall requirement nowadays seems to favor good balance of latency and throughput performance in network portion of VxWorks, it makes a lot of sense to think of how to achieve it. You cannot achieve this by adding zBuf. If you study the design and actual real life performance of the so called zBuf, you will notice that it is no better or worse than normal buffers. There are better ways of solving that "extra copy" problem -- just use mbufs. Also, you cannot help solve this problem by adding a new driver paradigm (END, SENS). You simply introduce more overhead in the code path for very little benefit (if any).

In my opinion what should happen (what I should have done while at WRS) is to create alternate runtime behavior for the network traffic. If users wish to use VxWorks in non-realtime way, just for the goal of "fast networking", the users should be given a chance. This can be done. Some of things that should happen :

  1. re-think netTask. At minimum, it should be demoted to smaller roll. Right now it is a central clearing house for all network I/O. A packet comes in, netJobAdd'ed, and netTask does everything for the packet for its lifetime. This is done for all packets, all network interfaces, and the entire TCP/IP stack. Not only is this single point of failure (if something bad happens to netTask due to one of the network interfaces the whole network subsystem of VxWorks is down), it is definitely not in the spirit of keeping the realtime nature of the system. At minimum, each network interface should be allowed to have its own task at a desired priority. A packet comes in and handed off directly to each task. The handing off can be done in a simple way, just semGive. Much lower overhead (but there is still task switch overhead).
  2. re-think overall runtime. Some attempts are made even in current code to minimize calls to netJobAdd() , at least in some drivers not all. For example, it is silly to call netJobAdd() for every packet that comes in. It helps to see if it is necessary to call netJobAdd() first. If netTask is already running, you do not need to prompt him again to call your function, if your function is written in a loop to handle more than one packet at a time. However, this is insufficient. More system wide consideration to the whole packet processing must be considered. For example, if you have TTCP running for benchmarking, it helps to consider overall system runtime behavior from all the way down in interrupt handler to all the way up in TTCP application, paying attention to what other things are happening in the system in typical situations. That can help "hand tune" your system.
  3. re-think buffering. Simpler schemes work better than complex schemes. Latest SENS stacks have more complicated encapsulation around mbuf scheme. When you do things like that you are adding more code for no good reason. What should happen is : pay more attention to the behavior of buffers when system is under high load. Buffering system should be designed to accommodate high load gracefully, arriving at a steady state where buffer inflow and outflow are matched. Otherwise, you have a system that drops a lot of packets, or in some cases just does not work. It affects performance.

(From: Hwa Jin Bae, hjb@pso.com)


Q: How can I get a list of all network devices?

A: There is a global pointer variable called ifnet (of type struct ifnet *). You can do: for (ifp = ifnet; ifp; ifp = ifp->if_next) to get the whole list of devices. The first one is pointed by ifnet.
(From: Hwa Jin Bae, hjb@pso.com)


Q: What is the difference between BSD and END style drivers?

A: BSD is acronym for Berkeley Software Distribution. As in BSD Unix. BSD network driver for VxWorks looks similar to original BSD network drivers in terms of API, structure, and the layout of code.

END stands for Enhanced Network Driver, or something like that. It is structured differently, with different API and layout of the code, than the original BSD drivers. It is unique to VxWorks.

What is less clear is the fact that END eventually becomes BSD driver before getting attached up to the IP layer code. The TCP/IP stack in VxWorks, derived from BSD Unix code, still thinks everything is BSD style driver. In order to make END work with TCP/IP stack, a layer of code is provided that will turn END driver into a BSD driver.

So what makes END "enhanced"? A couple things are usually quoted. One is that it allows for better multicasting support. Another is that it supports polled mode I/O. There are some other reasons for the existence of END.

Having written both END and BSD style drivers, I am not at all convinced that END is a justified model. The reasons are:

  1. Multicast support is just as easily done in BSD mode as in END model. Just look at how BSD Unix does it.
  2. The polled mode can be supported easily in BSD model by extending existing struct ifnet.
  3. END is unique to vxWorks, and makes it harder to port BSD driver to vxWorks
  4. END incurs more overhead overall, since it eventually becomes BSD driver anyway.

There are some other subtle details that are more troubling in END design. In particular, there are some rules that seem to have been broken or at least not explicitly handled in the design. These are harder to explain in the limited space and time devoted to a USENET article. But they have to do with robustness of a network driver in face of critical situations such as when there are too many packets to be handled too fast, buffer exhaustion, careful management of loaned buffers, etc.
(From: Hwa Jin Bae, hjb@pso.com)


Q: Why does MuxDevUnload followed by a MuxDevLoad cause a crash?

A: Some of the PPC ethernet drivers won't do xxxEndUnload properly. This is because the driver statically allocates the driver control structures, and xxxEndUnload will try and free that memory (behind the scenes, it's not in the driver). Thus you usually end up with a memPartFree() error. The only way to know is to look at the driver source and see if they've statically allocated the driver control structure. I did fix this in our motCpmEnd() driver (and our other drivers) if that's what you're running. Just ask WRS for the source and have a look.
(From: Dan Gold, gold@no-spam.please.ensemble.com)


Index

4.1 A How can I make my target vissible from other subnets?
B What is the correct sequence of function calls to install multiple END drivers and attach them to protocols
C How do I disable IP packet forwarding from one interface to another?
D How can I tune the performance of the network stack?
E How do I change the MAC-address of an interface?
F How to delete a IP address added by ifAddrAdd()
G How can I get the default gateway from the bootline to be the default gateway?
H How do I change the IP address of an interface?
I Once every 20 minutes I loose one UDP message.
J When I try to connect a lot of interfaces to the Mux it fails with the 8th interface I try to connect.
K How do I change the timeout on UDP fragmentation?
L How can I get the IP address and port number of an open socket?
4.2 A On bootup of my system I get an "arp info overwritten" message.
B Does any one know why I get this msg: 0xf7bf88 (tNetTask): arptnew failed on 50f22423
C How can I change the ARP timeout?
D I get the following error: arpresolve: can't allocate llinfo0x4f5a88. What does this mean?
4.3 A Example of a lease storage routine and address storage routine for use in a DHCP server.
B I have a problem in using the DHCP to get an IP address for the device that I am using.
C When I start a DHCP server on a port other ports stop working after some time.
D After upgrading to Torndado 2.0.2 (aka T2CP4) the Solaris DHCP-server rejects the first 4 discover packets as being "short"
E How can I get a NT server to send the right parameters back after a DHCP request?
F When I enable the DHCP client I cannot connect anymore using WDB.
G My target does not accept the DHCP offer.
4.4 A When I send files to my target using FTP small files fail often, but larger don't have any problem at all.
B What is the meaning of all the ftp global variables?
C How do I change the priority of the TFTP-task?
D Is there source code available for an FTP server?
E How can I enable the debug information of the FTP server?
F I am having problems connecting to the Windows XP FTP server.
G Ftp Server Bug on PWD command
H Is there a maximum size for a file to be transferred using FTP?
I Are there security issues with the VxWorks FTP server?
J How can I set the default path of the FTP server?
4.5 A PPP crashes when I do an FTP-GET from the target with a large number of small files.
B How can I set the username and password when using CHAP?
4.5.1 A How do I make a connection between my Windows 95 machine and my target using PPP over a null-modem cable?
4.5.2 A How do I make a connection between my Windows NT machine and my target using PPP over a null-modem cable?
4.5.3 A How do I build a network connection using PPP?
4.6 A When I do a send using a socket connection to a second system, and this system crashes, the send still returns OK. How do I detect that the other side has failed?
B After I used a lot of sockets my system stalls for 10 to 15 seconds. What is causing this delay?
4.7 A How can I use my own command line interface using Telnet, instead of using the target shell?
B How can I change the priority of the telnet task?
4.8 A Does anyone point me in what is needed to support development of server/client TCP - BSD stream sockets applications using a NT platform with Microsoft Visual C/C++ (or Visual Studio) ?
B Has anyone succeed using an etherInputHook on an END style ethernet driver?
C Is there a TCP dump utility available for VxWorks?
D At boottime I get a "dc0 - no carrier" error. What does this mean?
E Is there any vxworks routine to get the default gateway address on a vxworks target?
F How do I get the MAC address using the VxWorks API?
G Is well-known port 7 implemented, and if not, how can I implement this?
H When calling netPoolDelete,does the memory get freed?
J Is there a rsh deamon for VxWorks?
M Problems with high speed networks and netTask.
N How can I get a list of all network devices?
O What is the difference between BSD and END style drivers?
P Why does MuxDevUnload followed by a MuxDevLoad cause a crash?


VxWorks Homepage
© J.A. Borkhuis, 2000 - 2005
Send me an e-mail if this page was helpfull