⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 138.htm

📁 unix高级编程原吗
💻 HTM
📖 第 1 页 / 共 3 页
字号:
        strgetmsg (fd, &ctl, (struct strbuf*) NULL, &flags, "dlbindack"); <br>

  <br>

        dlp = (union DL_primitives *) ctl.buf; <br>

  <br>

        expecting (DL_BIND_ACK, dlp); <br>

  <br>

        if (flags != RS_HIPRI) <br>

                err ("dlbindack: DL_OK_ACK was not M_PCPROTO"); <br>

  <br>

        if (ctl.len < sizeof (dl_bind_ack_t)) <br>

                err ("dlbindack: short response ctl.len: %d", ctl.len); <br>



} <br>

  <br>

dlokack (fd, bufp) <br>

int     fd; <br>

char    *bufp; <br>

{ <br>

        union  DL_primitives*dlp; <br>

        struct  strbuf  ctl; <br>

        int     flags; <br>

  <br>

        ctl.maxlen = MAXDLBUF; <br>

        ctl.len = 0; <br>

        ctl.buf = bufp; <br>

  <br>

        strgetmsg (fd, &ctl, (struct strbuf*) NULL, &flags, "dlokack"); <br>

  <br>

        dlp = (union DL_primitives *) ctl.buf; <br>

  <br>

        expecting (DL_OK_ACK, dlp); <br>

  <br>

        if (ctl.len < sizeof (dl_ok_ack_t)) <br>

                err ("dlokack: response ctl.len too short: %d", ctl.len); <br>



  <br>

        if (flags != RS_HIPRI) <br>

                err ("dlokack: DL_OK_ACK was not M_PCPROTO"); <br>

  <br>

        if (ctl.len < sizeof (dl_ok_ack_t)) <br>

                err ("dlokack: short response ctl.len: %d", ctl.len); <br>

} <br>

  <br>

dlinforeq (fd) <br>

int     fd; <br>

{ <br>

        dl_info_req_t  info_req; <br>

        struct  strbuf  ctl; <br>

        int     flags; <br>

  <br>

        info_req.dl_primitive = DL_INFO_REQ; <br>

  <br>

        ctl.maxlen = 0; <br>

        ctl.len = sizeof (info_req); <br>

        ctl.buf = (char *) &info_req; <br>

  <br>

        flags = RS_HIPRI; <br>



  <br>

        if (putmsg (fd, &ctl, (struct strbuf*) NULL, flags) < 0) <br>

                syserr ("dlinforeq: putmsg"); <br>

} <br>

  <br>

dlinfoack (fd, bufp) <br>

int     fd; <br>

char    *bufp; <br>

{ <br>

        union  DL_primitives*dlp; <br>

        struct  strbuf  ctl; <br>

        int     flags; <br>

  <br>

        ctl.maxlen = MAXDLBUF; <br>

        ctl.len = 0; <br>

        ctl.buf = bufp; <br>

  <br>

        strgetmsg (fd, &ctl, (struct strbuf*) NULL, &flags, "dlinfoack"); <br>

  <br>

        dlp = (union DL_primitives *) ctl.buf; <br>

  <br>

        expecting (DL_INFO_ACK, dlp); <br>



  <br>

        if (ctl.len < sizeof (dl_info_ack_t)) <br>

                err ("dlinfoack: response ctl.len too short: %d", ctl.len); <br>

  <br>

        if (flags != RS_HIPRI) <br>

                err ("dlinfoack: DL_INFO_ACK was not M_PCPROTO"); <br>

  <br>

        if (ctl.len < sizeof (dl_info_ack_t)) <br>

                err ("dlinfoack: short response ctl.len: %d", ctl.len); <br>

} <br>

  <br>

  <br>

When executed, the program produces the following output: <br>

  <br>

    # dlinfo <br>

    dlinfo: Usage: dlinfo device ppa sap <br>

  <br>

    # dlinfo /dev/le 0 0 <br>

    DL_INFO_ACK: max_sdu 1500 min_sdu 0 <br>

    addr_length 8 mac_type DL_CSMACD current_state DL_IDLE <br>

    sap_length -2 service_mode DL_CLDLS qos_length 0 <br>

    qos_offset 0 qos_range_length 0 qos_range_offset 0 <br>



    provider_style DL_STYLE2 addr_offset 76 version 2 <br>

    brdcst_addr_length 6 brdcst_addr_offset 84 <br>

    addr 8:0:20:10:ab:ed:0:0 <br>

    brdcst_addr ff:ff:ff:ff:ff:ff <br>

    # <br>

  <br>

Note that the DLSAP address length for the le driver is 8 and the sap_length is <br>

-2, which means that the first six bytes are the physical address (Ethernet <br>

address) and the final two bytes are the SAP (Ethernet type) for this <br>

particular provider. <br>

  <br>

  <br>

** Transmitting Messages <br>

  <br>

Once the file descriptor has been attached to a physical interface and a SAP <br>

has been bound, you can send and receive datalink messages using the <br>

DL_UNITDATA_REQ and DL_UNITDATA_IND DLPI primitives. <br>

  <br>

  <br>

/* Xmit data buffer. Fill with whatever pattern you like ... */ <br>

char    xmitbuf[MAXDLBUF]; <br>

  <br>

  <br>

main (ac, av) <br>

int     ac; <br>

char    *av[]; <br>

{ <br>

        char    *device; <br>

        int     ppa, fd, localsap, sapval, n, size, physlen, saplen; <br>

        u_char  phys[MAXDLADDR], sap[MAXDLADDR], addr[MAXDLADDR]; <br>

        int     addrlen; <br>

        long    buf[MAXDLBUF]; <br>

        union  DL_primitives*dlp; <br>

        int     i; <br>

  <br>

        ... <br>

  <br>

        if (ac != 8) <br>

                usage (av[0]); <br>

  <br>

        device = av[1]; <br>

        ppa = atoi (av[2]); <br>

        localsap = atoi (av[3]); <br>

        n = atoi (av[6]); <br>

        size = atoi (av[7]); <br>



  <br>

        ... <br>

  <br>

        /* Convert destination address string to address. */ <br>

  <br>

        physlen = stringtoaddr (av[4], phys); <br>

        sapval = atoi (av[5]); <br>

        for (i = 0; i < sizeof (long); i++) <br>

                sap[i] = (sapval >> (i * BITSPERBYTE)) & 0xff; <br>

  <br>

        ... <br>

  <br>

        /* Get info. */ <br>

  <br>

        dlinforeq (fd); <br>

        dlinfoack (fd, buf); <br>

  <br>

        ... <br>

  <br>

        saplen = ABS (dlp->info_ack.dl_sap_length); <br>

        addrlen = saplen + physlen; <br>

  <br>

  <br>

        /* Construct destination address. */ <br>

  <br>

        if (dlp->info_ack.dl_sap_length > 0) {  /* order is sap+phys */ <br>

                (void) memcpy ((char*)addr, (char*)sap, saplen); <br>

                (void) memcpy ((char*)addr+saplen, (char*)phys, physlen); <br>

        } else {  /* order is phys+sap */ <br>

                (void) memcpy ((char*)addr, (char*)phys, physlen); <br>

                (void) memcpy ((char*)addr+physlen, (char*)sap, saplen); <br>

        } <br>

  <br>

        /* Transmit 'size' packet 'n' times. */ <br>

  <br>

        for (i = 0; i < n; i++) <br>

                dlunitdatareq (fd, addr, addrlen, 0, 0, xmitbuf, size); <br>

  <br>

        ... <br>

  <br>

  <br>

dlunitdatareq (fd, addrp, addrlen, minpri, maxpri, datap, datalen) <br>

int     fd; <br>

u_char  *addrp; <br>

int     addrlen; <br>



u_long  minpri, maxpri; <br>

u_char  *datap; <br>

int     datalen; <br>

{ <br>

        long  buf[MAXDLBUF]; <br>

        union  DL_primitives*dlp; <br>

        struct  strbuf  data, ctl; <br>

  <br>

        dlp = (union DL_primitves*) buf; <br>

  <br>

        dlp->unitdata_req.dl_primitive = DL_UNITDATA_REQ; <br>

        dlp->unitdata_req.dl_dest_addr_length = addrlen; <br>

        dlp->unitdata_req.dl_dest_addr_offset = sizeof (dl_unitdata_req_t); <br>

        dlp->unitdata_req.dl_priority.dl_min = minpri; <br>

        dlp->unitdata_req.dl_priority.dl_max = maxpri; <br>

  <br>

        (void) memcpy (OFFADDR (dlp, sizeof (dl_unitdata_req_t)), <br>

                addrp, addrlen); <br>

  <br>

        ctl.maxlen = 0; <br>

        ctl.len = sizeof (dl_unitdata_req_t) + addrlen; <br>

        ctl.buf = (char *) buf; <br>



  <br>

        data.maxlen = 0; <br>

        data.len = datalen; <br>

        data.buf = (char *) datap; <br>

  <br>

        if (putmsg (fd, &ctl, &data, 0) < 0) <br>

                syserr ("dlunitdatareq: putmsg"); <br>

} <br>

  <br>

  <br>

  <br>

** Receiving Messages <br>

  <br>

Received datalink packets are subject to two levels of address matching. <br>

Packets which do not match the enabled physical address for the file descriptor <br>

are rejected. Packets which do not match the enabled SAP address(es) for the <br>

file descriptor are rejected. Physical and SAP level address matching are <br>

independent on a per-packet and per-file-descriptor basis. The physical and <br>

SAP addresses enabled on one opened file descriptor have no effect on the <br>

packets received on another file descriptor. Only those received packets which <br>

match both the enabled physical address(es) and enabled SAP address(es) are <br>

sent upstream to the user. <br>



  <br>

Attaching to a PPA enables that physical address on the file descriptor. <br>

Binding a SAP enables that SAP address on the file descriptor. Additional <br>

physical and SAP addresses can be enabled for the file descriptor using the <br>

promiscuous and multicast primitives. <br>

  <br>

        ... <br>

  <br>

        data.buf = (char *) databuf; <br>

        data.maxlen = MAXDLBUF; <br>

        data.len = 0; <br>

  <br>

        while (getmsg (fd, NULL, &data, &flags) == 0) { <br>

                if (data.len) { <br>

                        for (i = 0; i < data.len; i++) <br>

                                printf ("%02x ", data.buf[i] & 0xff); <br>

                        printf ("\n"); <br>

                } <br>

                data.len = 0; <br>

        } <br>

  <br>

        ... <br>

        ... <br>

  <br>

  <br>

** Raw Mode <br>

  <br>

One feature which is not included in the USL DLPI Version 2 specification but <br>

is frequently necessary for several types of applications is "raw" mode. <br>

Support for this mode has been added to SunOS 5.x. The user enables raw mode by <br>

issuing the DLIOCRAW ioctl, which is defined in the version of dlpi.h shipped <br>

with SunOS 5.x. After this, "raw" Ethernet frames which include the 14-byte <br>

Ethernet header may be sent downstream in M_DATA type messages, and all <br>

received frames will be sent upstream with Ethernet header included in M_DATA <br>

type messages. <br>

  <br>

The DLIOCRAW ioctl takes no arguments. <br>

  <br>

  <br>

** Getting and Setting the Physical Address <br>

  <br>

Use the DL_PHYS_ADDR_REQ primitive to request the current or default factory <br>

physical (Ethernet) address which is returned in the DL_PHYS_ADDR_ACK message. <br>

  <br>

        ... <br>

        ... <br>

  <br>

        /* Get our current physical address. */ <br>

  <br>

        dlphysaddrreq (fd, DL_CURR_PHYS_ADDR); <br>

        dlphysaddrack (fd, buf); <br>

  <br>

        dlp = (union DL_primitives*) buf; <br>

  <br>

        /* Create raw Ethernet header. */ <br>

  <br>

        ehp = (struct ether_header*) xmitbuf; <br>

        memcpy (&ehp->ether_dhost, phys, ETHERADDRL); <br>

        memcpy (&ehp->ether_shost, <br>

                OFFADDR (dlp, dlp->physaddr_ack.dl_addr_offset), ETHERADDRL); <br>

        ehp->ether_type = (u_short) sapval; <br>

  <br>

        /* Put file descriptor in "raw mode". */ <br>

  <br>

        if (strioctl (fd, DLIOCRAW, -1, 0, 0) < 0) <br>

                syserr ("ioctl DLIOCRAW"); <br>

  <br>

        /* Transmit it as an M_DATA msg. */ <br>



  <br>

        if (write (fd, xmitbuf, size) < 0) <br>

                syserr ("write"); <br>

  <br>

        ... <br>

  <br>

  <br>

dlphysaddrreq (fd, addrtype) <br>

int     fd; <br>

u_long  addrtype; <br>

{ <br>

        dl_phys_addr_req_t  phys_addr_req; <br>

        struct  strbuf  ctl; <br>

        int     flags; <br>

  <br>

        phys_addr_req.dl_primitive = DL_PHYS_ADDR_REQ; <br>

        phys_addr_req.dl_addr_type = addrtype; <br>

  <br>

        ctl.maxlen = 0; <br>

        ctl.len = sizeof (phys_addr_req); <br>

        ctl.buf = (char *) &phys_addr_req; <br>

  <br>

  <br>

        flags = 0; <br>

        if (putmsg (fd, &ctl, (struct strbuf*) NULL, flags) < 0) <br>

                syserr ("dlphysaddrreq: putmsg"); <br>

} <br>

  <br>

dlphysaddrack (fd, bufp) <br>

int     fd; <br>

char    *bufp; <br>

{ <br>

        union  DL_primitives*dlp; <br>

        struct  strbuf  ctl; <br>

        int     flags; <br>

  <br>

        ctl.maxlen = MAXDLBUF; <br>

⌨️ 快捷键说明

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