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

📄 138.htm

📁 unix高级编程原吗
💻 HTM
📖 第 1 页 / 共 3 页
字号:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>CTerm非常精华下载</title>
</head>
<body bgcolor="#FFFFFF">
<table border="0" width="100%" cellspacing="0" cellpadding="0" height="577">
<tr><td width="32%" rowspan="3" height="123"><img src="DDl_back.jpg" width="300" height="129" alt="DDl_back.jpg"></td><td width="30%" background="DDl_back2.jpg" height="35"><p align="center"><a href="http://apue.dhs.org"><font face="黑体"><big><big>123</big></big></font></a></td></tr>
<tr>
<td width="68%" background="DDl_back2.jpg" height="44"><big><big><font face="黑体"><p align="center">               ● UNIX网络编程                       (BM: clown)                </font></big></big></td></tr>
<tr>
<td width="68%" height="44" bgcolor="#000000"><font face="黑体"><big><big><p   align="center"></big></big><a href="http://cterm.163.net"><img src="banner.gif" width="400" height="60" alt="banner.gif"border="0"></a></font></td>
</tr>
<tr><td width="100%" colspan="2" height="100" align="center" valign="top"><br><p align="center">[<a href="index.htm">回到开始</a>][<a href="133.htm">上一层</a>][<a href="139.htm">下一篇</a>]
<hr><p align="left"><small>发信人: cloudsky (小四), 信区: Security <br>

标  题: 一篇关于DLPI的文章(水木清华 microscat) <br>

发信站: 武汉白云黄鹤站 (Wed Apr 19 22:03:50 2000), 站内信件 <br>

  <br>

  <br>

发信人: microcat (microcat), 信区: Unix <br>

标  题: 一篇关于DLPI的文章 <br>

发信站: BBS 水木清华站 (Wed Apr 19 18:33:08 2000) <br>

  <br>

Year:   1992 <br>

Month:  September <br>

Title:  How to Use the STREAMS Data Link Provider Interface (DLPI) <br>

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

  <br>

How to Use the STREAMS Data Link Provider Interface (DLPI) <br>

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

By - Neal Nuckolls, Internet Engineering, SunSoft <br>

  <br>

  <br>

Introduction <br>

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

This article shows how user-level programs in SunOS 5.x can use the STREAMS <br>

Data Link Provider Interface (DLPI) to transmit and receive raw datalink-level <br>



frames. Examples are used to demonstrate the use of the interface. This article <br>

does *not* describe how to write DLPI device drivers. The purpose of this <br>

article is to provide the applications programmer with enough information to <br>

allow him/her to write programs which directly access the raw datalink drivers <br>

in the system to send and receive raw datalink frames. <br>

  <br>

Few programs need to access the raw datalink device drivers. Most networking <br>

applications should use the Transport Layer Interface (TLI), socket, or <br>

Transport-Independent RPC interface in SunOS 5.x. But a certain class of <br>

applications, such as network monitoring programs, require access to the <br>

underlying datalink interface, and must use DLPI for this. <br>

  <br>

Background <br>

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

The Data Link Provider Interface specifies a STREAMS kernel-level <br>

implementation of the ISO Data Link Service Definition (DLSD) [ISO 8886] and <br>

Logical Link Control (LLC) [ISO 8802/2]. <br>

  <br>

DLPI enables a datalink service user to access and use any of a variety of <br>

conforming datalink service providers without special knowledge of the <br>

provider's protocol. Specifically, the interface is intended to support X.25 <br>

LAPB, BX.25 level 2, SDLC, ISDN LAPD, Ethernet, FDDI, Token Ring, BISYNC, <br>



and other datalink-level protocols. <br>

  <br>

The interface specifies access to datalink service providers, and does not <br>

define a specific protocol or protocol implementation. <br>

  <br>

SunOS 5.0 (in Solaris 2.0) includes support for DLPI Version 2. Most networking <br>

datalink-level device drivers for SunOS 5.x support DLPI Version 2 as their <br>

primary interface. A user-level DLPI library interface (DLLI) is not currently <br>

available. Again, since the number of programs which should access the raw <br>

datalink layer is limited, supporting a formal user-level library seems <br>

unnecessary. This article and the sample demonstration programs contain more <br>

than sufficient code examples for most DLPI users. <br>

  <br>

The DLPI header file shipped with SunOS 5.x is <sys/dlpi.h> . <br>

  <br>

The DLPI Version 2 specification should be ordered from Sun: <br>

  <br>

    STREAMS DLPI Specification, Sun Microsystems, part number 800-6915-01 <br>

  <br>

DLPI defines a STREAMS message set, state table, and conventions to allow the <br>

interaction between a Data Link Service User (DLS user) and Data Link Service <br>

Provider (DLS provider). Within SunOS 5.x, the DLS users include the kernel IP <br>



and ARP protocols, and the DLS providers are the datalink drivers such as the <br>

le (LANCE Ethernet) driver. Other DLS users include in.rarpd (the user-level <br>

reverse ARP daemon program) and snoop (a network monitoring program which has <br>

replaced etherfind). Additionally, the ifconfig program is a DLS user when it <br>

reports or configures certain datalink-level values of the system networking <br>

interfaces. <br>

  <br>

DLPI Quick Tutorial <br>

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

The DLPI primitives are defined in terms of STREAMS messages. All DLPI messages <br>

are either M_PROTO or M_PCPROTO type and contain the appropriate DLPI message <br>

structure in the leading mblk. The DLPI primitives are generally issued in a <br>

request/acknowledge scenario, in which the user issues a request message and <br>

waits for an acknowledge or error response message from the provider. <br>

  <br>

DLPI provides support for connectionless and connection-oriented datalink <br>

protocols. This article will focus on providing examples of how to use <br>

connectionless datalink providers. <br>

  <br>

The DLPI Version 2 connectionless primitives allow the user to cause the <br>

provider to perform the following operations: <br>

  <br>

  <br>

  o  attach a Stream to a particular addressable physical device <br>

  o  bind a datalink-level service access point address to the Stream <br>

  o  transmit datalink frames <br>

  o  receive datalink frames <br>

  o  get/set physical address of attached device <br>

  o  enable reception of multicast group addresses <br>

  o  enable physical and datalink-level "promiscuous" reception <br>

  o  transmit/receive LLC XID/TEST messages <br>

  <br>

DLPI supports the concept of a DLSAP address which consists of a physical <br>

address plus a datalink service access point (SAP) address. For example, the <br>

DLSAP address format for a datalink provider for Ethernet is the 6-byte <br>

Ethernet physical address followed immediately by the 2-byte Ethernet type, to <br>

create an 8-byte Ethernet DLSAP address. The DLSAP address format differs from <br>

provider to provider. Information included in the DL_INFO_ACK primitive allows <br>

the user to compose and decompose the physical and datalink portions to/from a <br>

DLSAP address for that particular provider. There are examples of how to do <br>

this later. <br>

  <br>

Before transmitting and receiving datalink frames, the user must open the <br>

datalink provider, attach the file descriptor to a "Physical Point of <br>

Attachment" (PPA), and bind a service access point (SAP) address to the file <br>



descriptor. <br>

  <br>

Two styles of DLS provider (style1 and style2) are defined by DLPI, <br>

distinguished by the way they enable a DLS user to choose a particular PPA. <br>

Opening the datalink provider creates a new Stream to the device and returns <br>

a file descriptor. <br>

  <br>

The style1 provider assigns a PPA to the Stream based on the major/minor device <br>

numbers the user opened. Style1 providers "implicitly" attach the Stream to a <br>

device and do not require the user to explicity send a DL_ATTACH_REQ message <br>

downstream to the provider for this. An example of a style1 provider would <br>

probably be a serial line multiplexer driver which allowed the user to open the <br>

minor device which corresponded to the particular serial port number. Opening <br>

the special device /dev/serial000 would probably open minor device zero and <br>

associate this Stream with port zero of the device. <br>

  <br>

The style2 provider requires a DLS user to explicity identify the desired PPA <br>

using the attach service primitive DL_ATTACH_REQ. Most DLS providers which <br>

provide shared access for multiple Streams to a particular device port will be <br>

implemented as style2 providers. An example of a style2 provider is the le0 <br>

(LANCE Ethernet) device driver shipped with the SunOS 5.x system. Opening the <br>

special file /dev/le creates a new Stream but does not select a particular <br>



Ethernet interface. The user must then send a DL_ATTACH_REQ message downstream <br>

and receive a DL_OK_ACK response to associate the Stream with a particular le <br>

interface. <br>

  <br>

After the file descriptor has been attached to a PPA, the user must issue the <br>

DL_BIND_REQ primitive to associate the attached file descriptor with a full <br>

DLSAP address. <br>

  <br>

After the file descriptor has been attached and bound, the user can send and <br>

receive raw datalink frames or issue additional, optional DLPI primitives to <br>

access optional features of the DLS provider. <br>

  <br>

How to Use DLPI <br>

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

The examples below demonstrate the use of the connectionless DLPI Version 2 <br>

message set. <br>

  <br>

** Example DLPI Message <br>

  <br>

The typical DLPI Streams message consists of an M_PROTO or M_PCPROTO type <br>

mblk_t , followed by zero or more M_DATA type mblk_ts. Encapsulated within the <br>

leading M_PROTO/M_PCPROTO mblk_t will be a longword-aligned data structure <br>



defining one of the DLPI primitives. Here is the data structure for the <br>

DL_ATTACH_REQ primitive: <br>

  <br>

  /* <br>

   *  DL_ATTACH_REQ, M_PROTO type <br>

   */ <br>

  typedef struct { <br>

    ulong  dl_primitive;        /* set to DL_ATTACH_REQ */ <br>

    ulong  dl_ppa;              /* id of the PPA */ <br>

  } dl_attach_req_t; <br>

  <br>

  <br>

** Attaching and Binding <br>

  <br>

The program below demonstrates how to open, attach, and bind a datalink <br>

provider file descriptor, issue the inforeq primitive, and print some <br>

information about the provider. <br>

  <br>

The program takes three command line arguments. The 'device' argument <br>

specifies the full path of the device driver. The 'ppa' argument is the ID of <br>

the point of physical attachment interpreted by the driver. It identifies the <br>

unit number or port number of the physical device within the system. The third <br>



argument, 'sap', is an integer representing the datalink layer service access <br>

point and also interpreted by the driver. This tends to identify one of the <br>

protocol entities which will use this provider. <br>

  <br>

An example of the arguments and output of this program follows the source <br>

listing. <br>

  <br>

/* <br>

 * dlinfo - print information about the datalink provider <br>

 *   SYNOPSIS: dlinfo device ppa sap <br>

 * <br>

 * Open datalink provider. <br>

 * Attach to PPA. <br>

 * Bind to sap <br>

 * Get DL_INFO_ACK. <br>

 * Print DL_INFO_ACK information. <br>

 */ <br>

  <br>

#include <sys/types.h> <br>

#include <sys/stropts.h> <br>

#include <sys/dlpi.h> <br>

#include <sys/signal.h> <br>



#include <fcntl.h> <br>

  <br>

#include <stdio.h> <br>

#include "dltest.h" <br>

  <br>

main (ac, av) <br>

int     ac; <br>

char    *av[]; <br>

{ <br>

        long    buf[MAXDLBUF];                  /* aligned on long */ <br>

        union   DL_primitives*dlp; <br>

        char    *device; <br>

        int     ppa; <br>

        int     fd; <br>

        int     sap; <br>

  <br>

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

  <br>

        if (ac != 4) <br>

                usage(av[0]); <br>

  <br>

        device = av[1]; <br>



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

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

  <br>

        /* Open the device. */ <br>

  <br>

        if ((fd = open (device, O_RDWR)) < 0) <br>

                syserr (device); <br>

  <br>

        /* Attach. */ <br>

  <br>

        dlattachreq (fd, ppa); <br>

        dlokack (fd, buf); <br>

  <br>

        /* Bind. */ <br>

  <br>

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

        dlbindack (fd, buf); <br>

  <br>

        /* Issue DL_INFO_REQ. */ <br>

  <br>

        dlinforeq (fd); <br>

        dlinfoack (fd, buf); <br>



  <br>

        /* Print DL_INFO_ACK values. */ <br>

  <br>

        printdlprim (dlp); <br>

        return (0); <br>

} <br>

  <br>

usage (av0) <br>

char    *av0; <br>

{ <br>

        (void) fprintf (stderr, "%s: ", av0); <br>

        (void) fprintf (stderr, "Usage: %s device ppa sap\n", av0); <br>

        (void) exit (1); <br>

} <br>

  <br>

dlattachreq (fd, ppa) <br>

int     fd; <br>

u_long  ppa; <br>

{ <br>

        dl_attach_req_t  attach_req; <br>

        struct  strbuf  ctl; <br>

        int     flags; <br>



  <br>

        attach_req.dl_primitive = DL_ATTACH_REQ; <br>

        attach_req.dl_ppa = ppa; <br>

  <br>

        ctl.maxlen = 0; <br>

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

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

  <br>

        flags = 0; <br>

  <br>

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

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

} <br>

  <br>

dlbindreq (fd, sap, max_conind, service_mode, conn_mgmt, xidtest) <br>

int     fd; <br>

u_long  sap; <br>

u_long  max_conind; <br>

u_long  service_mode; <br>

u_long  conn_mgmt; <br>

u_long  xidtest; <br>

{ <br>

{ <br>

        dl_bind_req_t  bind_req; <br>

        struct  strbuf  ctl; <br>

        int     flags; <br>

  <br>

        bind_req.dl_primitive = DL_BIND_REQ; <br>

        bind_req.dl_sap = sap; <br>

        bind_req.dl_max_conind = max_conind; <br>

        bind_req.dl_service_mode = service_mode; <br>

        bind_req.dl_conn_mgmt = conn_mgmt; <br>

        bind_req.dl_xidtest_flg = xidtest; <br>

  <br>

        ctl.maxlen = 0; <br>

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

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

  <br>

        flags = 0; <br>

  <br>

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

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

} <br>

  <br>

dlbindack (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>

⌨️ 快捷键说明

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