dli_802.c

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

C
267
字号
#ifndef lintstatic  char  *sccsid = "@(#)dli_802.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 * * Description: This program sends out a message to a node where a *              companion program, dli_802d, echoes the message back. *              The 802.3 packet format is used.  The ethernet *              address of the node where the companion program is *              running, the sap, and the message are supplied by the  *              user.  The companion program should be started before  *              executing this program. * * Inputs:      device, target address, sap, short message. * * Outputs:     Exit status. * * To compile:  cc -o dli_802 dli_802.c * * Example:     dli_802 qe0 08-00-2b-02-e2-ff ac "Echo this" * * Comments:    This example demonstrates the use of 802 "TYPE1"  *              service.  With TYPE1 service, the processing of *              XID and TEST messages is handled transparently by *              DLI, i.e., this program doesn't have to be concerned *              with handling them.  If the SNAP SAP (0xAA) is *              selected, a 5 byte protocol id is also required. *              This example automatically uses a protocol id of *              of PROTOCOL_ID when ths SNAP SAP is used.  Also, *              note the use of DLI_NORMAL for the i/o control flag. *              DLI makes use of this only when that SNAP_SAP/Protocol *              ID pair is used. DLI will filter all incoming messages *              by comparing the Ethernet source address and Protocol  *              ID against the target address and Protocol ID set up  *              in the bind call.  Only if a match occurs will DLI  *              pass the message up to the application.   *//* * 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 target_eaddr[6];    u_char devname[16];    int rsize, devunit;    char *cp;     int i, sock, fromlen;    struct sockaddr_dl from;    u_short obsiz;    u_int sap;    u_char  *pi = 0;      if ( argc < 5 )    {        fprintf(stderr, "%s %s %s\n",                "usage:",                argv[0],                "device ethernet-address hex-sap short-message");        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 phys addr of remote node */    bzero(target_eaddr, sizeof(target_eaddr));    i = 0;    cp = argv[2];    while ( *cp ) {        if ( *cp == '-' ) {            cp++;            continue;        }        else {            sscanf(cp, "%2x", &target_eaddr[i++]);            cp += 2;        }    }     /* get sap */    sscanf(argv[3], "%x", &sap);     /* get message */    bzero(outbuf, sizeof(outbuf));    if ( (obsiz = strlen(argv[4])) > 1500 ) {        fprintf(stderr, "%s: message is too long\n", argv[0]);        exit(2);    }    strcpy(outbuf, argv[4]);      /* open dli socket. notice that if (and only if) the snap sap */    /* was selected then a protocol id must also be provided. */    if ( sap == SNAP_SAP )        pi = protocolid;    if ( (sock = dli_802_3_conn(devname, devunit, pi, target_eaddr,                     DLI_NORMAL, TYPE1, sap, sap, UI_NPCMD)) < 0 ) {        perror("dli_802, dli_econn failed");        exit(3);    }      /* send message to target. minimum message size is 46 bytes. */    if ( write(sock, outbuf, (obsiz < 46 ? 46 : obsiz)) < 0 ) {        sprintf(outbuf, "%s: DLI transmission failed", argv[0]);        perror(outbuf);        exit(4);    }     /* wait for response from correct address */    while (1) {        bzero(&from, sizeof(from));        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(5);        }        if ( fromlen != sizeof(struct sockaddr_dl) ) {                fprintf(stderr,"%s, invalid address size\n",argv[0]);                exit(6);        }        if ( bcmp(from.choose_addr.dli_802addr.eh_802.dst,                   target_eaddr, sizeof(target_eaddr)) == 0 )                break;    }    if ( ! rsize ) {        fprintf(stderr, "%s, no data returned\n", argv[0]);        exit(7);    }    /* print message */    printf("%s\n", inbuf);     close(sock); } /* *              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_802: bad device name");         return(-1);    }        if ((sock = socket(AF_DLI, SOCK_DGRAM, DLPROTO_DLI)) < 0)    {         perror("dli_802, 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;    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_802, can't bind DLI socket");         return(-1);    }        return(sock);} 

⌨️ 快捷键说明

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