[Return to Library] [Contents] [Previous Chapter] [Next Section] [Next Chapter] [Index] [Help]


7    Digital UNIX STREAMS/Sockets Coexistence

This chapter describes the ifnet STREAMS module and dlb STREAMS pseudodriver communication bridges. Before reading it, you should be familiar with basic STREAMS and sockets concepts and have reviewed the information in Chapter 4 and Chapter 5.

The Digital UNIX network programming environment supports the STREAMS and sockets frameworks for network programming. However, there is no native communication path at the data link layer between the two frameworks. The term coexistence refers to the ability to exchange data between the sockets and STREAMS frameworks. The term communication bridge refers to the software (ifnet STREAMS module or the dlb STREAMS pseudodriver) that enables the two frameworks to exchange data at the data link layer.

Programs written to sockets and STREAMS must intercommunicate for the following reasons:


[Return to Library] [Contents] [Previous Chapter] [Next Section] [Next Chapter] [Index] [Help]


7.1    Bridging STREAMS Drivers to Sockets Protocol Stacks

The ifnet STREAMS module is a communication bridge that allows STREAMS network drivers to access sockets-based network protocols. The ifnet STREAMS module functions like any other STREAMS module, being pushed on the Stream above the STREAMS device driver. Once it is on the Stream, it handles all of the translation required between the DLPI interface of the STREAMS driver and the BSD ifnet layer. The ifnet STREAMS module exports both standard STREAMS interfaces as well as ifnet layer interfaces.

Note that STREAMS network drivers can also continue to use STREAMS-based network protocols while using the ifnet STREAMS module.

Figure 7-1 highlights the ifnet STREAMS module and shows its place in the network programming environment.

Figure 7-1: The ifnet STREAMS module


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


7.1.1    The STREAMS Driver

This section describes how to prepare the system running the STREAMS driver to use the ifnet STREAMS module.

Note

The ifnet STREAMS module only supports Ethernet STREAMS device drivers.

This section also lists the DLPI primitives that the STREAMS driver must support in order for the ifnet STREAMS module to operate successfully.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


7.1.1.1    Using the ifnet STREAMS Module

If your device driver supports the primitives listed in Section 7.1.1.2, no source code changes to either the driver or STREAMS kernel code are needed for you to use the ifnet STREAMS module.

To use the ifnet STREAMS module, the STRIFNET and DLPI options must be configured in your kernel and you must set up STREAMS for the driver.

The STRIFNET and DLPI options may have been configured into your system at installation time. (For information on configuring options during installation, see the Installation Guide.) You can check to see if the options are configured, by issuing the following command:

/usr/sbin/strsetup -c

If ifnet and dlb appear in the Name column, the options are configured in you kernel. If not, you must add them using the doconfig command.

To configure STRIFNET and DLPI into your kernel, perform the following steps:

  1. Log in as superuser.

  2. Enter the /usr/sbin/doconfig command. If you have a customized configuration file, you should use the /usr/sbin/doconfig -c command. For more information, see the doconfig(8) reference page.

  3. Enter a name for the kernel configuration file. It should be the name of your system in uppercase letters, and will probably be the default provided in square brackets ([]); for example:

    Enter a name for the kernel configuration file. [HOST1]:  [RETURN]

  4. Enter y when the system asks whether you want to replace the system configuration file; for example:

    A configuration file with the name 'HOST1' already exists.
    Do you want to replace it? (y/n) [n]:  y
     

     
    Saving /sys/conf/HOST1 as /sys/conf/HOST1.bck
     
    *** KERNEL CONFIGURATION AND BUILD PROCEDURE ***

  5. Select the options you want to include in you kernel.

    Note

    The STRIFNET and DLPI options are not available from this menu. To include these options, you must edit the configuration file, as shown in the following step.

  6. Add DLPI and STRIFNET to the options section of the kernel configuration file. Enter y when the system asks whether you want to edit the kernel configuration file. The doconfig command allows you to edit the configuration file with the ed editor. For information about using the ed editor, see ed(1). The following ed editing session shows how to add the DLPI and STRIFNET options to the kernel configuration file for host1. Note that the number of the line after which you append the new lines can differ between kernel configuration files:

    Do you want to edit the configuration file? (y/n) [n]:  y
     
    Using ed to edit the configuration file.  Press return when ready,
    or type 'quit' to skip the editing session: 
    2153
     
    48a
    options         DLPI
    options         STRIFNET
    \.
    1,$w
    2185
    q
     
    *** PERFORMING KERNEL BUILD ***

  7. After the new kernel is built, you must move it from the directory where doconfig places it to the root directory ( \/) and reboot your system. When you reboot, the strsetup -i command runs automatically, and creates the device special files for any new STREAMS modules.

  8. Run the strsetup -c command to verify that the device is configured properly.

    The following example shows the output from the strsetup -c command:

    /usr/sbin/strsetup -c

    STREAMS Configuration Information...Thu Nov  9 08:38:17 1995
    
     
    Name Type Major Module ID ---- ---- ----- --------- clone 32 0 dlb device 52 5010 dlpi device 53 800 kinfo device 54 5020 log device 55 44 nuls device 56 5001 echo device 57 5000 sad device 58 45 pipe device 59 5304 xtisoUDP device 60 5010 xtisoTCP device 61 5010 xtisoUDP+ device 62 5010 xtisoTCP+ device 63 5010 ptm device 64 7609 pts device 6 7608 bba device 65 24880 lat device 5 5 pppif module 6002 pppasync module 6000 pppcomp module 6001 bufcall module 0 ifnet module 5501 null module 5002 pass module 5003 errm module 5003 ptem module 5003 spass module 5007 rspass module 5008 pipemod module 5303 timod module 5006 tirdwr module 0 ldtty module 7701
     
    Configured devices = 16, modules = 15

For more detailed information on reconfiguring your kernel or the doconfig command see the System Administration manual and the doconfig(8) reference page.

To set up STREAMS for the driver you must do the following:

  1. Write an application program similar to the following:

    /*
     * Application program to set up the "pifnet" streams for IP
     * and ARP. This must be run prior to ifconfig
     */
    #include <stdio.h>
    #include <fcntl.h>
    #include <errno.h>
    #include <stropts.h>
    #include <sys/ioctl.h>
    #include <signal.h>
    #include "dlpihdr.h"
    
     
    #define IP_PROTOCOL 0x800 #define ARP_PROTOCOL 0x806 #define PIFNET_IOCTL_UNIT 1236
     
    main(argc, argv) int argc; char *argv[]; { extern char *getenv(); char *p; short unit = 0; char devName[256];
     
    if (argc != 3) usage(); strcpy(devName, argv[1]); unit = atoi(argv[2]);
     
    sigignore(SIGHUP); setupStream(devName, unit, IP_PROTOCOL); setupStream(devName, unit, ARP_PROTOCOL);
     
    /* * sleep forever to keep the Streams alive. */ if (fork()) /* detach */ exit(); pause(); }
     
    usage() { fprintf(stderr, "usage: pifnetd devname unit-number\n"); exit(1); }
     
    setupStream(devName, unit, serviceClass) char *devName; short unit; u_long serviceClass; { int fd, status; dl_bind_req_t bindreq; dl_bind_ack_t bindack; int flags; struct strioctl str; struct strbuf pstrbufctl, pstrbufdata, gstrbufctl, \ gstrbufdata; char ebuf[256];
     
    /* * build the stream */ fd = open(devName, O_RDWR, 0); if (fd < 0) { sprintf(ebuf, " open '%s' failed", devName); perror(ebuf); exit(1); } if (ioctl(fd, I_PUSH, "ifnet") < 0) { sprintf(ebuf, " ioctl I_PUSH failed"); perror(ebuf); exit(1); }
     
    /* * tell pifnet the unit number for the device */ str.ic_cmd = PIFNET_IOCTL_UNIT; str.ic_timout = 15; str.ic_len = sizeof (short); str.ic_dp = (char *) &unit; status = ioctl(fd, I_STR, &str); if (status < 0) { sprintf(ebuf, " %s - ioctl"); perror(ebuf); exit(1); }
     
    /* * bind the stream to a protocol */ bindreq.dl_primitive = DL_BIND_REQ; bindreq.dl_sap = serviceClass; bindreq.dl_max_conind = 0; bindreq.dl_service_mode = DL_CLDLS; bindreq.dl_conn_mgmt = 0; bindreq.dl_xidtest_flg = 0; pstrbufctl.len = sizeof(dl_bind_req_t); pstrbufctl.buf = (void *)&bindreq;
     
    pstrbufdata.buf = (char *)0; pstrbufdata.len = -1; pstrbufdata.maxlen = 0;
     
    status = putmsg(fd, &pstrbufctl, (struct strbuf *)0, 0); if (status < 0) { perror("putmsg"); exit(1); }
     
    /* * Check requested binding */ gstrbufctl.buf = (char *)&bindack; gstrbufctl.maxlen = sizeof(dl_bind_ack_t); gstrbufctl.len = 0; status = getmsg(fd, &gstrbufctl, (struct strbuf *)0, &flags); if (status < 0) { perror("getmsg"); exit(1); }
     
    if (bindack.dl_primitive != DL_BIND_ACK) { errno = EPROTO; perror(" DL_BIND_ACK"); exit(1); } }
     

    In this sample application the driver's name is /dev/streams/ln. The application creates two Streams; one for the Internet Protocol (IP) and one for the Address Resolution Protocol (ARP). After setting up the Streams, the application must keep running, using the pause command, in order to keep the Streams alive.

    Note that, if the driver is a style-2 driver, you must add a DL_ATTACH_REQ to the application program. For more information about the DL_ATTACH_REQ primitive or style-2 drivers, see the DLPI specification in /usr/share/doclib/dlpi/dlpi.ps.

  2. Generate an executable file for the application. Compile, link, and debug the program until it runs without errors.

  3. Move the executable into a directory that is convenient for you.

    The executable can be located in any directory.

  4. Add a line invoking the program to the /sbin/init.d/inet file.

    Although you can manually start the program each time you reboot, it is easiest to add a line to the /sbin/init.d/inet file to run it automatically when the system reboots. Be sure to add the line before the system's ifconfig lines.

    In the following example, each time the system reboots, the /sbin/init.d/inet file runs a program called run_ifnet, which resides in the /etc directory:


    .
    .
    .
    # # Enable network # case $1 in .start') echo "Configuring network" /sbin/hostname $HOSTNAME echo "hostname: \c" /sbin/hostname if [ "$NETDEV_0" != '' ]; then echo >/tmp/ifconfig_"$NETDEV_0".tmp
    # place command invoking executable BEFORE \
           ifconfig lines
                    /etc/run_ifnet

                    /sbin/ifconfig $NETDEV_0 $IFCONFIG_0 > \
                                   /tmp/ifconfig_"$NETDEV_0".tmp 2>&1
                   if [ $? != 0 ]; then
                            ERROR=`cat /tmp/ifconfig_"$NETDEV_0".tmp`
                            if [ "$ERROR" = "$ERRSTRING" ]; then
                                    /sbin/ifconfig $NETDEV_0 up
                            else
                                    echo "$0: $ERROR"
                            fi
                    fi
                    rm /tmp/ifconfig_"$NETDEV_0".tmp
            fi
    
    .
    .
    .

  5. Reboot the system.

    Use the /usr/sbin/shutdown -r command to shut down your system and have it reboot automatically; for example:

    /usr/sbin/shutdown -r now


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


7.1.1.2    Data Link Provider Interface Primitives

Note that the STREAMS device driver can be a style-1 or a style-2 DLPI provider, as described in the Data Link Provider Interface specification, which is located in /usr/share/doclib/dlpi/dlpi.ps. Note that you must have the OSFPGMR400 subset installed to access the DLPI specification on line.

The driver must support the following DLPI primitives. For detailed information about these primitives and how to use them, see the DLPI specification: DL_PHYS_ADDR_REQ/DL_PHYS_ADDR_ACK DL_BIND_REQ/DL_BIND_ACK DL_UNBIND_REQ DL_UNITDATA_REQ/DL_UNITDATA_IND/DL_UDERROR_IND DL_OK_ACK/DL_ERROR_ACK


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


7.2    Bridging BSD Drivers to STREAMS Protocol Stacks

The dlb STREAMS pseudodevice driver allows you to bridge BSD-style device drivers and STREAMS protocol stacks. The STREAMS pseudodevice driver is the Stream end in a Stream wanting to communicate with BSD-based drivers. The STREAMS pseudodevice driver provided by Digital UNIX has two interfaces, a subset of the DLPI interface that communicates with STREAMS protocol stacks and another interface that accesses the ifnet layer interface of the sockets framework.

Figure 7-2 highlights the dlb STREAMS pseudodriver and shows its place in the network programming environment.

Figure 7-2: DLPI STREAMS Pseudodriver


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


7.2.1    Supported DLPI Primitives and Media Types

The dlb STREAMS pseudodriver supports the following connectionless mode primitive and media types. For detailed information about these primitives and how to use them, see the Data Link Provider Interface specification which is in /usr/share/doclib/dlpi/dlpi.ps. DL_ATTACH_REQ/DL_DETACH_REQ/DL_OK_ACK DL_BIND_REQ/DL_BIND_ACK/DL_UNBIND_REQ DL_ENABMULTI_REQ/DL_DISABLMULTI_REQ DL_PROMISCON_REQ/DL_PROMISCONOFF_REQ DL_PHYS_ADDR_REQ/DL_PHYS_ADDR_ACK DL_SET_PHYS_ADDR_REQ DL_UNITDATA_REQ/DL_UNITDATA_IND DL_SUBS_BIND_REQ/DL_SUBS_BIND_ACK DL_SUBS_UNBIND_REQ/DL_SUBS_UNBIND_ACK

The Ethernet bus (DL_ETHER) is the media type supported by the STREAMS pseudodriver.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Chapter] [Index] [Help]


7.2.2    Using the STREAMS Pseudodriver

To use the dlb STREAMS pseudodriver the DLPI option must be configured into your kernel. The DLPI option may have been configured into your system at installation time.

You can check to see if the DLPI option is configured by issuing the following command:

/usr/sbin/strsetup -c

If dlb appears in the Name column, the option is configured in you kernel. If not, you must add it using the doconfig command.

For a description of how to reconfigure your kernel with the doconfig command, see Section 7.1.1.1.

For more information on reconfiguring your kernel or the doconfig command see the System Administration manual and the doconfig(8) reference page. For information on configuring options during installation, see the Installation Guide.