📄 138.htm
字号:
<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 + -