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

📄 140.htm

📁 unix高级编程原吗
💻 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="141.htm">下一篇</a>]
<hr><p align="left"><small>发信人: guru (好读书,不求甚解), 信区: UNP <br>

标  题: dlpi简介 <br>

发信站: UNIX编程 (2001年08月15日09:46:18 星期三), 站内信件 <br>

  <br>

dlpi简介 <br>

作者:pan8848  2000-05-24这篇稿件被阅读==170次 <br>

  <br>

  <br>

   unix中要想直接对数据链路层读写有三种方法:dlpi(data <br>

   link provider interface),bpf(bsd packet filter),还 <br>

  有linux中的sock_packet. <br>

   有关dlpi方面的资料很少,本文对dlpi作简要的介绍。 <br>

  对dlpi或网络编程感兴趣的大侠可与我联系:pan8848@263.net <br>

   OSI参考模型的每一层都有两种标准:1 定义该层提供的 <br>

  服务。2 定义可以提供该服务的协议。DLPI属于第一种标准, <br>

  即不提供实现方法。 <br>

  1 通信类型 <br>

   DLPI提供三种类型的通信方式:连接、无连接和公认无连接。 <br>

  1.1 连接方式 <br>

   连接方式是面向电路的,数据通过一个预先建立的连接进行 <br>

  传输。整个通信过程分为四个阶段:本地管理,连接建立,数据 <br>

  传输,连接释放。 <br>

   本地管理阶段,DLS用户初始化一个用于通信的流并为自己建 <br>



  立一个标识符。 <br>

   连接建立阶段,DLS主叫用户初始化连接建立过程,被叫用户 <br>

  等待连接请求。DLS被叫用户是通过一个与流相联系的地址来标 <br>

  识自己。被叫用户可以接收请求,也可以拒绝请求。如果接收, <br>

  双方就进入数据传输阶段。每个流上只能建立一个连接。被叫用 <br>

  户可以选择在收到连接请求的流上接收连接,也可以打开一个新 <br>

  流,在这个新流上接收连接。如果在一个独立的流上接收连接, <br>

  则初始化流可以被设计成一个侦听流以处理所有的连接请求。当 <br>

  一个请求到达时就打开一个新流以处理这个连接,随后到达的请 <br>

  求在侦听流排队等待接收处理。 <br>

   数据传输阶段,两个DLS用户被认为是对等的,可以全双工 <br>

  通信。数据按顺序可靠的到达对方。 <br>

   连接释放阶段,DLS用户和DLS提供者都可以释放连接。连接 <br>

  释放时,任何未到达目的地的数据都被DLS提供者丢弃。 <br>

  1.2 无连接方式 <br>

   无连接方式不需要连接建立和连接释放阶段。本地管理阶段仍需 <br>

  初始化流。之后,立即进入数据传输阶段。因为没有建立连接,每一 <br>

  个数据单元都必需标明目的地。目的的DLS是通过与用户相联系的地 <br>

  址来标识自己的。无连接方式不保证数据单元按顺序到达,也不保证 <br>

  数据会到达目的DLS用户。 <br>

   <br>

  1.3 公认无连接方式 <br>



   公认无连接方式与无连接方式类似,但是它保证数据按顺序 <br>

  到达目的地。 <br>

   <br>

   无连接方式是面向消息的,传输的数据单元之间没有逻辑的 <br>

  联系,这种方式在大多数情况下是不可靠的。公认无连接使用户 <br>

  可以同时发送数据和请求数据返回,数据单元的传输是点对点的。 <br>

   <br>

  2 DLPI 地址 <br>

   每一个DLPI用户都要建立一个标识符以与其它数据链路层用户 <br>

  通信。这个标识符包括两部分。首先,DLPI必须指明它通信的物 <br>

  理媒介。在一个与多个物理媒介相连的系统上,这一点更加明显 <br>

  。其次,DLS用户必须相DLS提供者登记。 <br>

   <br>

  2.1 物理层标识 <br>

   PPA(physical point of attachment)是系统与物理介质 <br>

  的连接点。该物理介质上的所有通信都要经过PPA。有的系统上, <br>

  DLS提供者支持多个物理介质,DLS用户必须指明它要与哪个物理 <br>

  介质通信。一个PPA由唯一的PPA标识符来标识。 <br>

  对于支持物理层复用的介质(如ISDN的B和D通道),PPA标识符 <br>

  必须指明通信的通道。 <br>

  2.2 数据链路层标识 <br>

   DLSAP(Data Link Service Access Point)是用户与DLS <br>



  提供者的连接点。DLSAP由唯一的DLSAP标识符来标识。 <br>

   通过Bind原语,DLS用户可以指定DLSAP地址来选择DLSAP,或 <br>

  重申被绑定的DLSAP地址来决定与流相联系的DLSAP。 <br>

   DLS提供者具有绑定多个DLSAP地址的能力。DLPI 支持对等绑 <br>

  定和等级绑定。对等绑定,在随后绑定中指定的DLSAP可用来替 <br>

  代在DL_BIND_REQ中绑定的DLSAP。例如,在DL_BIND_REQ指定 <br>

  ether-_type的值为IP,在随后绑定中可以指定ether-_type的 <br>

  值为ARP。则DLS提供者复用ether-_type域,允许IP或ARP数据发 <br>

  送到流上。若没有指明,则第一个被绑定的SAP被作为源SAP。等 <br>

  级绑定,随后绑定指定一个与在DL_BIND_REQ 中绑定的DLSAP不 <br>

  同的DLSAP。 <br>

   <br>

  3 dlpi编程的大体框架 <br>

   仅以捕捉数据包为例,其中设计一些函数,未给出,有兴趣者 <br>

  可向我索要。 <br>

  /* <br>

   * NAME <br>

   * dlrcv - read and display raw datalink packets <br>

   * SYNOPSIS: <br>

   * dlrcv [ -bp ] device ppa sap <br>

   * <br>

   * Open datalink provider. <br>



   * Attach to PPA. <br>

   * Bind to sap <br>

   * Issue DLIOCRAW ioctl. <br>

   * Read and print messages <br>

   */ <br>

   <br>

  /* <br>

  typedef unsigned long ulong; <br>

  */ <br>

   <br>

  #include "../h/conf.h" <br>

  #include "../h/kernel.h" <br>

  #include "../h/network.h" <br>

   <br>

   <br>

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

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

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

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

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

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

  #include <stdio.h> <br>



  #include "dltest.h" <br>

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

  #include <string.h> <br>

  long databuf[MAXDLBUF]; <br>

   <br>

   <br>

  extern char *optarg; <br>

  extern int optind; <br>

   <br>

  int promisc = 0; /* promiscuous mode "off" by default */ <br>

  int bufmod = 0; /* push buffer module, "off" by default */ <br>

   <br>

   <br>

  main() <br>

  { <br>

  dlrcv("/dev/le",0,2048); <br>

  } <br>

   <br>

  dlrcv(char *device, int ppa,int sap) <br>

  { <br>

   long buf[MAXDLBUF]; <br>

   int fd; <br>

   int fd; <br>

   struct strbuf data; <br>

   int flags; <br>

   int i,j,cnt=0; <br>

   int c; <br>

   int offset; <br>

   int len; <br>

   struct timeval t; <br>

   u_int chunksize = 16 * 1024; <br>

   struct sb_hdr *bp; <br>

   char *p, *limp; <br>

   u_char buf1[4*MAXDLBUF]; <br>

   struct udp *pudp; <br>

   char udata[]; <br>

   int idata; <br>

   char cdata; <br>

   struct ip *pip; <br>

   <br>

   int wfd,nwrite; <br>

   /* <br>

   * Validate arguments. <br>

   */ <br>

   if (ppa < 0) <br>



   err("ppa cannot be negative"); <br>

   if (sap < 0) <br>

   err("sap cannot be negative"); <br>

   <br>

   /* <br>

   * Open the device. <br>

   */ <br>

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

   syserr(device); <br>

   <br>

   /* <br>

   * Attach. <br>

   */ <br>

   dlattachreq(fd, ppa); <br>

   dlokack(fd, buf); <br>

   <br>

   /* <br>

   * Optionally enable promiscuous mode. <br>

   */ <br>

   if (promisc) { <br>

   dlpromisconreq(fd, DL_PROMISC_PHYS); <br>

   dlokack(fd, buf); <br>



   } <br>

   <br>

   /* <br>

   * Bind. <br>

   */ <br>

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

   dlbindack(fd, buf); <br>

   <br>

   /* <br>

   * Issue DLIOCRAW ioctl. <br>

   */ <br>

   <br>

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

   syserr("DLIOCRAW"); <br>

   <br>

   /* <br>

   * Push and configure buffer module. <br>

   */ <br>

   if (bufmod) { <br>

   if (ioctl(fd, I_PUSH, "bufmod") < 0) <br>

   syserr("push bufmod"); <br>

   <br>

   <br>

   t.tv_sec = 0; <br>

   t.tv_usec = 500000; /* 0.5s */ <br>

   if (strioctl(fd, SBIOCSTIME, -1, sizeof (struct timeval), <br>

   &t) < 0) <br>

   syserr("SBIOCSTIME"); <br>

   if (strioctl(fd, SBIOCSCHUNK, -1, sizeof (u_int), <br>

   &chunksize) < 0) <br>

   syserr("SBIOCSCHUNK"); <br>

   } <br>

   <br>

   /* <br>

   * Flush the read side of the Stream. <br>

   */ <br>

   if (ioctl(fd, I_FLUSH, FLUSHR) < 0) <br>

   syserr("I_FLUSH"); <br>

   <br>

   /* <br>

   * Read packets. <br>

   */ <br>

   <br>

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

   data.maxlen = MAXDLBUF; <br>



   data.len = 0; <br>

   printf("read "); <br>

   <br>

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

   <br>

   printf("getmsg "); <br>

   limp = p + data.len; <br>

   <br>

   if (data.len && bufmod) { <br>

   for (p = data.buf; p < limp; p += bp-> sbh_totlen) { <br>

   bp = (struct sb_hdr*) p; <br>

   for (i = 0; i < bp->sbh_msglen; i++) <br>

   printf("%02x ", *(p + <br>

   sizeof (struct sb_hdr) + i) <br>

   & 0xff); <br>

   printf(" "); <br>

   } <br>

   } else if (data.len) { <br>

   <br>

   memcpy(buf1,(u_char *)(data.buf+14),data.len-14); <br>

   pip = (struct ip *)buf1; <br>

   <br>

   <br>

   if(1){ <br>

   printf("source ip:%x ",pip->ip_src); <br>

   printf("dest ip:%x ",pip->ip_dst); <br>

   if (pip->ip_proto==IPT_UDP){ <br>

   <br>

   pudp=pip->ip_data; <br>

   <br>

   printf("datalen:%d ",pudp->u_len-U_HLEN); <br>

   printf("udp source port:%d ",pudp->u_src); <br>

   printf("udp dest port:%d ",pudp->u_dst); <br>

   printf("data: "); <br>

   <br>

   for (i= 14+20+8; i < data.len; i++){ <br>

   idata=data.buf[i]&0xff; <br>

   printf("%d:%c ", i-14-20-8,idata); <br>

   } <br>

   printf(" "); <br>

   <br>

   i=data.len-14-20-8; <br>

   <br>

   for (i= 14+20+8; i < data.len; i++) <br>

   printf("%d:%02x ", i-14-20-8,data.buf[i] & 0xff); <br>



   printf(" "); <br>

   <br>

   i=data.len-14-20-8; <br>

   } <br>

   <br>

   <br>

   } <br>

   <br>

   } <br>

   data.len = 0; <br>

   }/*while*/ <br>

  } <br>

  <br>

  <br>

-- <br>

Target Locked:Guru In Darkness. <br>

我只是一只静静卧着的狮子。。。 <br>

※ 来源:·UNIX编程 www.tiaozhan.com/unixbbs/·[FROM: 202.114.36.225] <br>

</small><hr>
<p align="center">[<a href="index.htm">回到开始</a>][<a href="133.htm">上一层</a>][<a href="141.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 + -