dli_802d.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 262 行

C
262
字号
#ifndef lintstatic  char  *sccsid = "@(#)dli_802d.c	4.1	(ULTRIX)	7/17/90";#endif lint#include <stdio.h>#include <ctype.h>#include <errno.h>#include <strings.h>#include <sys/types.h>#include <sys/socket.h>#include <net/if.h>#include <netinet/in.h>#include <netinet/if_ether.h>#include <netdnet/dli_var.h>#include <sys/ioctl.h> extern int errno; #define PROTOCOL_ID      {0x00, 0x00, 0x00, 0x00, 0x5}u_char protocolid[] = PROTOCOL_ID; /* *      d l i _ e x a m p l e : d l i _ 8 0 2 d * * Description: This daemon program transmits any message it receives *              to the originating node, i.e., it echoes the message  *              back.  The device and sap are supplied by the user.   *              The program uses 802.3 format packets. * * Inputs:      device, sap. * * Outputs:     Exit status. * * To compile:  cc -o dli_802d dli_802d.c * * Example:     dli_802d de0 ac * * Comments:    This example demonstrates the recvfrom & sendto system *              calls.  Since packets may arrive from different nodes *              we use the recvfrom call to read the packets.  This *              call gives us access to the packet header information *              so that we can determine where the packet came from.   *              When we write on the socket we must use the sendto  *              system call to explicitly give the destination of  *              the packet.  The use of the "DEFAULT" I/O control flag *              only applies *              (i.e. only has an affect) when the SNAP SAP is used. *              When the SNAP SAP is used, any arriving packets which *              have the specified protocol id and which are not *              destined for some other program will be given to this *              program. *//* * Digital Equipment Corporation supplies this software example on  * an "as-is" basis for general customer use.  Note that Digital  * does not offer any support for it, nor is it covered under any  * of Digital's support contracts.  */main(argc, argv, envp)int argc;char **argv, **envp; {     u_char inbuf[1500], outbuf[1500];    u_char devname[16];    u_char target_eaddr[6];    char *cp;    int rsize, devunit;    int i, sock, fromlen;    u_short obsiz;    u_char tmpsap, sap;    struct sockaddr_dl from;    u_char *pi = 0;     if ( argc < 3 )    {        fprintf(stderr, "usage: %s device hex-sap\n", argv[0]);        exit(1);    }      /* get device name and unit number. */    bzero(devname, sizeof(devname));    i = 0;    cp = argv[1];    while ( isalpha(*cp) )        devname[i++] = *cp++;    sscanf(cp, "%d", &devunit);     /* get sap */    sscanf(argv[2], "%x", &sap);     /* open dli socket. note that if (and only if) the snap sap */    /* was selected then a protocol id must also be specified. */    if ( sap == SNAP_SAP )        pi = protocolid;    if ((sock = dli_802_3_conn(devname, devunit, pi, target_eaddr,                     DLI_DEFAULT, TYPE1, sap, sap, UI_NPCMD)) < 0) {         perror("dli_802d, dli_conn failed");        exit(1);    }     /* listen and respond */    while ( 1 ) {        /* wait for message */        from.dli_family = AF_DLI;        fromlen = sizeof(struct sockaddr_dl);        if ((rsize = recvfrom(sock, inbuf, sizeof(inbuf), NULL,                               &from, &fromlen)) < 0 ) {            sprintf(inbuf, "%s: DLI reception failed", argv[0]);            perror(inbuf);            exit(2);        }         /* check header */        if ( fromlen != sizeof(struct sockaddr_dl) ) {            fprintf(stderr,"%s, incorrect header supplied\n",argv[0]);            continue;        }         /*         * Note that DLI swaps the source & destination saps and lan          * addresses in the sockaddr_dl structure returned by the          * recvfrom call.  That is, it places the DSAP in eh_802.ssap          * and the SSAP in eh_802.dsap; it also places the destination         * lan address in eh_802.src and the source lan address in          * eh_802.dst.  This allows for minimal to no manipulation of         * the address structure for subsequent sendto or dli         * connection calls.         */        /* any data? */        if ( ! rsize )             fprintf(stderr, "%s: NO data received from ", argv[0]);        else            fprintf(stderr, "%s: data received from ", argv[0]);        for ( i = 0; i < 6; i++ )             fprintf(stderr, "%x%s",                     from.choose_addr.dli_802addr.eh_802.dst[i],                    ((i<5)?"-":" "));        fprintf(stderr, "\n     on dsap %x ",                 from.choose_addr.dli_802addr.eh_802.ssap);        if ( from.choose_addr.dli_802addr.eh_802.dsap == SNAP_SAP )            fprintf(stderr,                     "(SNAP SAP), protocol id = %x-%x-%x-%x-%x\n    ",                    from.choose_addr.dli_802addr.eh_802.osi_pi[0],                    from.choose_addr.dli_802addr.eh_802.osi_pi[1],                    from.choose_addr.dli_802addr.eh_802.osi_pi[2],                    from.choose_addr.dli_802addr.eh_802.osi_pi[3],                    from.choose_addr.dli_802addr.eh_802.osi_pi[4]);        fprintf(stderr, " from ssap %x ",                 from.choose_addr.dli_802addr.eh_802.dsap);        fprintf(stderr, "\n\n");            /* send response to originator. */        if ( from.choose_addr.dli_802addr.eh_802.dsap == SNAP_SAP )            bcopy(protocolid,                   from.choose_addr.dli_802addr.eh_802.osi_pi, 5);        if ( sendto(sock, inbuf, rsize, NULL, &from, fromlen) < 0 ) {            sprintf(outbuf, "%s: DLI transmission failed", argv[0]);            perror(outbuf);            exit(2);        }    }} /* *              d l i _8 0 2 _ 3 _ c o n n * * * * Description: *      This subroutine opens a dli 802.3 socket, then binds an  *      associated device name and protocol type to the socket. * * Inputs: *      devname         = ptr to device name *      devunit         = device unit number *      ptype           = protocol type *      taddr           = target address *      ioctl           = io control flag *      svc             = service class *      sap             = source sap *      dsap            = destination sap *      ctl             = control field * * * Outputs: *      returns         = socket handle if success, otherwise -1 * * */dli_802_3_conn (devname,devunit,ptype,taddr,ioctl,svc,sap,dsap,ctl)char *devname;u_short devunit;u_char *ptype;u_char *taddr;u_char ioctl;u_char svc;u_char sap;u_char dsap;u_short ctl;{    int i, sock;    struct sockaddr_dl out_bind;        if ( (i = strlen(devname)) >          sizeof(out_bind.dli_device.dli_devname) )    {         fprintf(stderr, "dli_802d: bad device name");         return(-1);    }        if ((sock = socket(AF_DLI, SOCK_DGRAM, DLPROTO_DLI)) < 0)    {         perror("dli_802d, can't open DLI socket");         return(-1);    }        /*     * fill out bind structure.  note that we need to determine     * whether the ctl field is 8 bits (unnumbered format) or     * 16 bits (informational/supervisory format).  We do this     * by checking the low order 2 bits, which are both 1 only     * for unnumbered control fields.     */    bzero(&out_bind, sizeof(out_bind));    out_bind.dli_family = AF_DLI;    out_bind.dli_substructype = DLI_802;    bzero(&out_bind, sizeof(out_bind));    out_bind.dli_family = AF_DLI;    out_bind.dli_substructype = DLI_802;    bcopy(devname, out_bind.dli_device.dli_devname, i);    out_bind.dli_device.dli_devnumber = devunit;    out_bind.choose_addr.dli_802addr.ioctl = ioctl;    out_bind.choose_addr.dli_802addr.svc = svc;    if(ctl & 3)        out_bind.choose_addr.dli_802addr.eh_802.ctl.U_fmt=(u_char)ctl;    else        out_bind.choose_addr.dli_802addr.eh_802.ctl.I_S_fmt = ctl;    out_bind.choose_addr.dli_802addr.eh_802.ssap = sap;    out_bind.choose_addr.dli_802addr.eh_802.dsap = dsap;    if ( ptype )        bcopy(ptype,out_bind.choose_addr.dli_802addr.eh_802.osi_pi,5);    if ( taddr )         bcopy(taddr, out_bind.choose_addr.dli_802addr.eh_802.dst,               DLI_EADDRSIZE);    if ( bind(sock, &out_bind, sizeof(out_bind)) < 0 )    {         perror("dli_802d, can't bind DLI socket");         return(-1);    }        return(sock);} 

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?