eCos Reference Manual
Prev |  | Next

# Chapter 22. Sockets

If a network stack is present, then the FILEIO infrastructure also provides access to the standard BSD socket calls.

The netstack table contains entries which describe the network protocol stacks that are in the system image. Each resident stack should export an entry to this table using the NSTAB_ENTRY() macro.

Each table entry has the following structure:

    struct cyg_nstab_entry
    {
        cyg_bool            valid;          // true if stack initialized
        cyg_uint32          syncmode;       // synchronization protocol
        char                *name;          // stack name
        char                *devname;       // hardware device name
        CYG_ADDRWORD        data;           // private data value

        int     (*init)( cyg_nstab_entry *nste );
        int     (*socket)( cyg_nstab_entry *nste, int domain, int type,
    		       int protocol, cyg_file *file );
    };

This table is analogous to a combination of the filesystem and mount tables.

The `valid` field is set true if the stack's `init()` function returned successfully and the `syncmode` field contains the CYG_SYNCMODE_SOCK_* bits described above.

The `name` field contains the name of the protocol stack.

The `devname` field names the device that the stack is using. This may reference a device under "/dev", or may be a name that is only meaningful to the stack itself.

The `init()` function pointer is called during system initialization to start the protocol stack running. If it returns non-zero the `valid` field is set false and the stack will be ignored subsequently.

The `socket()` function is called to attempt to create a socket in the stack. When the `socket()` API function is called the netstack table is scanned and for each valid entry the `socket()` function pointer is called. If this returns non-zero then the scan continues to the next valid stack, or terminates with an error if the end of the table is reached.

The result of a successful socket call is an initialized file object with the `f_xops` field pointing to the following structure:

    struct cyg_sock_ops
    {
        int (*bind)      ( cyg_file *fp, const sockaddr *sa, socklen_t len );
        int (*connect)   ( cyg_file *fp, const sockaddr *sa, socklen_t len );
        int (*accept)    ( cyg_file *fp, cyg_file *new_fp,
                           struct sockaddr *name, socklen_t *anamelen );
        int (*listen)    ( cyg_file *fp, int len );
        int (*getname)   ( cyg_file *fp, sockaddr *sa, socklen_t *len, int peer );
        int (*shutdown)  ( cyg_file *fp, int flags );
        int (*getsockopt)( cyg_file *fp, int level, int optname,
                           void *optval, socklen_t *optlen);
        int (*setsockopt)( cyg_file *fp, int level, int optname,
                           const void *optval, socklen_t optlen);
        int (*sendmsg)   ( cyg_file *fp, const struct msghdr *m,
                           int flags, ssize_t *retsize );
        int (*recvmsg)   ( cyg_file *fp, struct msghdr *m,
                           socklen_t *namelen, ssize_t *retsize );
    };

It should be obvious from the names of these functions which API calls they provide support for. The `getname()` function pointer provides support for both `getsockname()` and `getpeername()` while the `sendmsg()` and `recvmsg()` function pointers provide support for `send()`, `sendto()`, `sendmsg()`, `recv()`, `recvfrom()` and `recvmsg()` as appropriate.

Prev | Home | Next
Automounter | Up | Select