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

📄 138.htm

📁 unix高级编程原吗
💻 HTM
📖 第 1 页 / 共 3 页
字号:
        ctl.len = 0; <br>

        ctl.buf = bufp; <br>

  <br>

        strgetmsg (fd, &ctl, (struct strbuf*) NULL, <br>

                &flags, "dlphysaddrack"); <br>

  <br>

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

  <br>

  <br>

        expecting (DL_PHYS_ADDR_ACK, dlp); <br>

  <br>

        if (flags != RS_HIPRI) <br>

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

  <br>

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

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

} <br>

  <br>

Use the DL_SET_PHYS_ADDR_REQ primitive to set the physical address of the <br>

attached interface. NOTE: this is a destructive operation, and unlike all other <br>

primitives, it will affect other file descriptors for this physical interface. <br>

The new physical address for the interface will be retained until the next <br>

DL_SET_PHYS_ADDR_REQ is issued or the system is rebooted. Only the superuser <br>

may issue this primitive. <br>

  <br>

  <br>

** Multicast Addressing <br>

  <br>

Use DL_ENABMULTI_REQ and DL_DISABMULTI_REQ to enable/disable specific multicast <br>

group addresses. These primitives allow the user to iteratively build a set of <br>

enabled multicast addresses on a per-file-descriptor basis. <br>



  <br>

  <br>

** Promiscuous Reception <br>

  <br>

DL_PROMISCON_REQ and DL_PROMISCOFF_REQ allow the user to enable/disable <br>

promiscuous-mode reception. These two primitives take a level argument which <br>

may be one of: <br>

  <br>

    DL_PROMISC_PHYS <br>

    DL_PROMISC_SAP <br>

    DL_PROMISC_MULTI <br>

  <br>

Each of the promiscuous levels acts like a "wildcard" for the particular level. <br>

Enabling DL_PROMISC_PHYS will match all physical addresses.  Enabling <br>

DL_PROMISC_SAP will match all SAP addresses.  Enabling DL_PROMISC_MULTI will <br>

match all multicast-group addresses. <br>

  <br>

The following example demonstrates how one would enable physical-level <br>

promiscuous mode: <br>

  <br>

        ... <br>

  <br>

  <br>

        /* Enable promiscuous mode. */ <br>

  <br>

        dlpromisconreq (fd, DL_PROMISC_PHYS); <br>

        dlokack (fd, buf); <br>

  <br>

        ... <br>

  <br>

  <br>

dlpromisconreq (fd, level) <br>

int     fd; <br>

u_long  level; <br>

{ <br>

        dl_promiscon_req_t  promiscon_req; <br>

        struct  strbuf  ctl; <br>

        int     flags; <br>

  <br>

        promiscon_req.dl_primitive = DL_PROMISCON_REQ; <br>

        promiscon_req.dl_level = level; <br>

  <br>

        ctl.maxlen = 0; <br>

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

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



  <br>

        flags = 0; <br>

  <br>

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

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

} <br>

  <br>

  <br>

Converting NIT Programs to Use DLPI <br>

----------------------------------- <br>

The Network Interface Tap (NIT) STREAMS pseudo-driver is not included in <br>

SunOS 5.x. In previous releases of SunOS, the underlying datalink device <br>

drivers were not directly accessible as UNIX special files; therefore, a <br>

pseudo-driver, NIT, was supported to allow those few user-level programs which <br>

required access to the raw datalink drivers to access the devices. <br>

  <br>

In SunOS 5.x, all networking drivers are real STREAMS hardware drivers <br>

accessible in the file system namespace. To access the "le0" networking <br>

interface, you now open /dev/le instead of /dev/nit , and issue DLPI primitives <br>

instead of NIT primitives. DLPI provides a superset of the features previously <br>

provided by the NIT pseudo-driver. <br>

  <br>

  <br>

Applications which used NIT in SunOS 4.x will require some source-level <br>

modifications to run in SunOS 5.x . With the information provided below, the <br>

application programmer should find these changes relatively simple and <br>

straightforward. <br>

  <br>

  <br>

SunOS 4.x included three NIT components: <br>

  <br>

  o  nit_if(4M) pseudo-driver <br>

  o  nit_pf(4M) packet filter module <br>

  o  nit_buf(4M) buffer module <br>

  <br>

The nit_if pseudo-driver is not included in SunOS 5.x. The packet filter and <br>

buffer modules have been ported to 5.x and minor enhancements made. Refer <br>

to the pfmod(1M) and bufmod(1M) manual pages for the complete programmatic <br>

interfaces for these two general-purpose STREAMS modules. <br>

  <br>

** Open Driver Directly <br>

  <br>

Open the datalink driver instead of /dev/nit : <br>

  <br>

        /* Open the device. */ <br>



  <br>

        if ((fd = open ("/dev/le", 2)) < 0) <br>

                syserr ("/dev/le"); <br>

  <br>

  <br>

** NIT ioctls to DLPI Primitives or Buffer Module ioctls <br>

  <br>

The NIT ioctl commands have changed slightly: <br>

  <br>

  o  Replace use of the SIOCGIFADDR ioctl with the DL_PHYS_ADDR_REQ <br>

     DLPI primitive to get the current or default physical Ethernet address. <br>

  <br>

  o  Replace use of the SIOCSIFADDR ioctl with the DL_SET_PHYS_ADDR_REQ DLPI <br>

     primitive to set the current physical Ethernet address. You must be <br>

     superuser to do this; the operation is destructive and permanently changes <br>

     the individual Ethernet address of the interface for all open Streams <br>

     until it is changed again or the system reboots. <br>

  <br>

  o  Replace use of the SIOCADDMULTI and SIOCDELMULTI ioctls with the <br>

     DL_ENABMULTI_REQ and DL_DISABMULTI_REQ DLPI primitives. Each datalink <br>

     provider will support a fixed number of specific multicast addresses. <br>

     Use the DL_PROMISCON_REQ with DL_PROMISC_MULTI dl_level value to enable <br>



     all multicast group addresses. <br>

  <br>

  o  Replace use of the NIOCBIND ioctl command with the DL_ATTACH_REQ and <br>

     DL_BIND_REQ DLPI primitives. The attach primitive performs the equivalent <br>

     function of the NIOCBIND ioctl, and the bind primitive then labels the <br>

     attached interface with a service access point (SAP) address. The bundled <br>

     Ethernet drivers implement the SAP address as the Ethernet type. You must <br>

     bind a SAP address to the interface before you can send or receive; this <br>

     is *not* an optional command. <br>

  <br>

  o  Replace use of the NIOCSSNAP ioctl command with the SBIOCSSNAP buffer <br>

     module ioctl command. You must push "bufmod" before issuing the SBIOCSSNAP <br>

     in the same manner as the old NIT NIOCSSNAP ioctl. <br>

  <br>

  o  The NIOCSFLAGS ioctl command has changed. Instead of setting the <br>

     NI_PROMISC flag, you must now issue the DL_PROMISCON_REQ DLPI primitive, <br>

     setting the DL_PROMISC_PHYS value in the dl_level field. Instead of <br>

     setting the NL_TIMESTAMP and NI_DROPS flags, you must push the buffer <br>

     module; timestamp and dropcounts are included in the default buffer module <br>

     chunk message headers, which also include the original and truncated <br>

     packet lengths. <br>

  <br>

  <br>

  <br>

** Attach and Bind <br>

  <br>

Use the DLPI primitives DL_ATTACH_REQ and DL_BIND_REQ to first associate the <br>

file descriptor with a particular physical interface (like NIOCBIND), and then <br>

label the attached file descriptor with a SAP address. The bundled SunOS 4.x <br>

Ethernet drivers implement the SAP as the Ethernet type. So if you wanted to <br>

receive IP (0x0800) type Ethernet packets only, you'd do this: <br>

  <br>

        ... <br>

  <br>

        /* Attach. <br>

         *  Arguments: file descriptor, ppa identifier. */ <br>

  <br>

        dlattachreq (fd, ppa); <br>

        dlokack (fd, buf); <br>

  <br>

        /* Bind. <br>

         *  Arguments: file descriptor, sap, max conind, <br>

         *             service mode, conn_mgmt, xidtest. */ <br>

  <br>

        dlbindreq (fd, 0x800, 0, DL_CLDLS, 0, 0); <br>



        dlbindack (fd, buf); <br>

  <br>

        ... <br>

  <br>

The complete example routines for attaching and binding are included in the <br>

first example in the previous section ("How to Use DLPI: Attaching and <br>

Binding"). <br>

  <br>

  <br>

** Filtering on Ethernet Type <br>

  <br>

After binding to a specific type, only packets of that ethertype will be <br>

received on that file descriptor. You don't need to push and configure the <br>

packet filter module to filter on ethertype, since you get that "for free." If <br>

you want to enable multiple Ethernet types on the same file descriptor, you'll <br>

have to enable promiscuous SAP-level service using the DL_PROMISCON_REQ <br>

primitive and setting the DL_PROMISC_SAP value in the dl_level field, and then <br>

push and configure the packet filter module to filter out the packets with <br>

ethertype you're not interested in receiving. <br>

  <br>

  <br>

** Raw Mode <br>

** Raw Mode <br>

  <br>

The standard connectionless DLPI primitives to send and receive datalink <br>

packets are DL_UNITDATA_REQ and DL_UNITDATA_IND. Each of these primitives is <br>

implemented as an M_PROTO STREAMS message type followed by one or more M_DATA <br>

message types. <br>

  <br>

If you just want to send and receive "raw" Ethernet frames including the <br>

Ethernet header, you can do this by enabling "raw mode" on the particular file <br>

descriptor. Issue the DLIOCRAW ioctl: <br>

  <br>

        ... <br>

  <br>

        /* Issue DLIOCRAW ioctl. */ <br>

  <br>

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

                syserr ("DLIOCRAW"); <br>

  <br>

        ... <br>

  <br>

  <br>

strioctl (fd, cmd, timout, len, dp) <br>

int     fd; <br>

int     fd; <br>

int     cmd; <br>

int     timout; <br>

int     len; <br>

char    *dp; <br>

{ <br>

        struct  strioctl  sioc; <br>

        int     rc; <br>

  <br>

        sioc.ic_cmd = cmd; <br>

        sioc.ic_timout = timout; <br>

        sioc.ic_len = len; <br>

        sioc.ic_dp = dp; <br>

        rc = ioctl (fd, I_STR, &sioc); <br>

  <br>

        if (rc < 0) <br>

                return (rc); <br>

        else <br>

                return (sioc.ic_len); <br>

} <br>

  <br>

Now all received frames will be passed up without changes within M_DATA <br>

messages, and you can send raw Ethernet frames downstream in M_DATA messages. <br>



  <br>

  <br>

** Enabling Promiscuous Mode <br>

  <br>

Use the DL_PROMISCON_REQ with the dl_level field set to DL_PROMISC_PHYS to <br>

enable physical-level promiscuous mode: <br>

  <br>

        ... <br>

  <br>

        /* Enable promiscuous mode. */ <br>

  <br>

        dlpromisconreq (fd, DL_PROMISCON_PHYS); <br>

        dlokack (fd, buf); <br>

  <br>

        ... <br>

  <br>

  <br>

dlpromisconreq (fd, level) <br>

int     fd; <br>

u_long  level; <br>

{ <br>

        dl_promiscon_req_t  promiscon_req; <br>



        struct  strbuf  ctl; <br>

        int     flags; <br>

  <br>

        promiscon_req.dl_primitive = DL_PROMISCON_REQ; <br>

        promiscon_req.dl_level = level; <br>

  <br>

        ctl.maxlen = 0; <br>

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

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

  <br>

        flags = 0; <br>

  <br>

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

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

} <br>

  <br>

  <br>

** Packet Filter Module <br>

  <br>

The packet filter module, now called "pfmod", is almost identical to the SunOS <br>

4.x version. You can push it and program it as before. <br>

  <br>

  <br>

  <br>

** Buffer Module <br>

  <br>

  <br>

The buffer module, now called "bufmod", has had a few additions and includes a <br>

few features that were a part of the SunOS 4.x nit_if pseudo-driver. In <br>

addition to the standard chunksize and timeout values for defining when the <br>

"chunk" is passed upstream, the SunOS 5.x bufmod also includes a snaplength <br>

parameter to truncate uninteresting parts of the packet; dropcount of number of <br>

received packets dropped due to read-side flow-control; and timestamp of each <br>

received packet. You push "bufmod" on any Stream in which you want one or more <br>

of these generic features. <br>

  <br>

The buffer module header data structure has changed slightly: <br>

  <br>

  struct sb_hdr { <br>

        u_int  sbh_origlen; <br>

        u_int  sbh_msglen; <br>

        u_int  sbh_totlen; <br>

        u_int  sbh_drops; <br>

        struct  timeval  sbh_timestamp; <br>

  }; <br>



  <br>

The names of the buffer module ioctl commands have all changed to take on the <br>

new prefix ("SB" stands for STREAMS Buffer Module): <br>

  <br>

    NIOCSTIME is now SBIOSCTIME <br>

    NIOCGTIME is now SBIOCGTIME <br>

    NIOCCTIME is now SBIOCCTIME <br>

    NIOCSCHUNK is now SBIOCSCHUNK <br>

    NIOCGCHUNK is now SBIOCGCHUNK <br>

  <br>

Additional ioctls are documented in the bufmod(1M) manual page. <br>

</small><hr>
<p align="center">[<a href="index.htm">回到开始</a>][<a href="133.htm">上一层</a>][<a href="139.htm">下一篇</a>]
<p align="center"><a href="http://cterm.163.net">欢迎访问Cterm主页</a></p>
</table>
</body>
</html>

⌨️ 快捷键说明

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