关于运输层中TCP协议的三次握手连接和四次握手连接释放过程简述 下载本文

struct SNetIf DT_XDATA* NetIf,IP_ADDR DestIP) REENTRANT_SIG {

/* next host to receive the packet in rout */ DWORD NextIP;

// 以太网数据链路层首部结构体指针

struct SEtherHead DT_XDATA * pEtherHead; ETHERIF.C // 缓存控制块指针

struct SMemHead DT_XDATA *p;

// 缓存控制块中得到以太网数据链路层指针位置

// 入口时 MemHead 的.pStart 域指向 IP 数据报文位置 pEtherHead = (struct SEtherHead DT_XDATA *) (MemHead->pStart - sizeof(struct SEtherHead)); /* if DestIP in this subnet ... */ // ????????????????????????????

if ((NetIf->NetMask & NetIf->IPAddr) == (NetIf->NetMask & DestIP)) NextIP = DestIP; else

NextIP = NetIf->GateWay; /* find Ether addr of NextIP */

// 查找 NextIP 对应的网卡物理地址

if (ARPFind(pEtherHead->DestAddr,NextIP) == FALSE) {

/* send a arp query */

//---------------------------------------------------------------------

// 如果 ARP 高速缓存表中未找到 NextIP,则调用 ARPQuery 发送程序发送一条 // ARP 广播。其中在 ARPQuery 程序中已经填写好以太网数据链路层报文和 ARP // 报文。 ARPQuery 如果申请内存成功,则返回缓存控制块指针,否则返回 NULL。 //--------------------------------------------------------------------- if ((p = ARPQuery(NetIf,NextIP)) != NULL) { // 如果发送 ARP 广播时申请内存成功

// 调用网络接口设备队列的发送指针函数,发送 ARP 数据包 ((struct SEtherDevice DT_XDATA *)

(NetIf->Info))->send(p->pStart,sizeof(struct SARPPacket) + sizeof(struct SEtherHead));

MemFree(p); // 释放缓存控制块 } } else {

//---------------------------------------------------------------------

// 如果 ARP 高速缓存表中找到 NextIP,则 pEtherHead->DestAddr 中存储 // NextIP 对应的以太网物理地址。

//--------------------------------------------------------------------- /* fill ehter header, DestAddr already filled in ARPFind */

// 填写以太网数据链路层首部.ScrAddr 域=以太网源物理地址 // 网络接口设备队列指针中获取以太网源物理地址 MemCopy(pEtherHead->ScrAddr,

((struct SEtherDevice DT_XDATA *)(NetIf->Info))->Addr,ETHER_ADDR_LEN); // 填写以太网数据链路层首部.type 域=数据帧类型 // 以太网帧类型=IP 数据包 ETHERIF.C pEtherHead->type = htons(ETHER_TYPE_IP);

// 注:以太网目的物理地址已经在调用 ARPFind 程序时填写到 // pEtherHead->DestAddr 中。

/* send the packet. packet lenth is less than MemHead size */ // 调用网络接口设备队列的发送指针函数,发送 IP 数据包 return ((struct SEtherDevice DT_XDATA *)(NetIf->Info))->send(

pEtherHead,(WORD)(MemHead->pEnd - (BYTE DT_XDATA *)pEtherHead)); }

return FALSE;

/* free MemHead when it is acked in tcp model */ }

//===========================================================================

/* this function is called periodically.Get a packet from specific device. If there is a packet, call NetIf->Input to do more */ // 作 者:南开大学-李章林 // 注 释:李清林

// 日 期:2008 年3 月

// 声 明:英文注释由作者李章林添加,中文注释由■李清林添加。 // 转载时请保留上述信息。

// 成都理工学院/应用数字系/应用数字专业

//--------------------------------------------------------------------------- // 程序名称:EtherInput=以太网数据链路层接收子程序 // 入口参数:

// *NetIf=网络接口设备队列指针 // 出口参数: // 无

//=============================================================================

void EtherInput(struct SNetIf DT_XDATA * NetIf) REENTRANT_SIG {

struct SMemHead DT_XDATA *MemHead; // 缓存控制块指针

struct SEtherHead DT_XDATA *pEtherHead; // 以太网数据链路层指针 struct SMemHead DT_XDATA *p; // 临时缓存控制块指针

/* if there is a packet to deal with */

// 如果以太网网络接口设备接收到数据包

while ((MemHead = ((struct SEtherDevice DT_XDATA *)(NetIf->Info))->recv()) != NULL) {

/* Note, pStart point to EtherHead */

// 以太网数据链路层指针 EetherHead 指向数据包数据链路层位置 pEtherHead = (struct SEtherHead DT_XDATA *)(MemHead->pStart); /* which packet type */

switch(ntohs(pEtherHead->type)) // 分析数据包帧类型 ETHERIF.C {

case ETHER_TYPE_IP: // IP 数据包

/* before pass to IP layer, let MemHead->pStart point to IP header */

MemHead->pStart += sizeof(struct SEtherHead); /* pass to IP layer for more dealing */

// 将缓存控制块指针的 pStart 域指针指向IP 首部

IPInput(MemHead); // 调用 IP 数据包接收子程序, break;

case ETHER_TYPE_ARP: // ARP 数据包

//--------------------------------------------------------------------------

// ARPInput 程序中如果接收到 ARP 请求报文,填写以太网数据链路层首部信息,然后 // 填写 ARP 应答报文,并返回 MemHead;如果接收到 ARP 应答报文,填写 ARP 高速缓存表,

// 然后返回 NULL。据此通过返回值可确定是接收到 ARP 请求报文还是 ARP 应答报文。 //-------------------------------------------------------------------------- if ((p = ARPInput(MemHead,NetIf)) != NULL) {

/* a arp reply need to be send */

// 接收到 ARP 请求报文后,发送 ARP 应答报文

// 调用网络接口设备发送函数指针发送 ARP 应答报文 ((struct SEtherDevice DT_XDATA *)(NetIf->Info))->send( p->pStart,sizeof(struct SARPPacket) + sizeof(struct SEtherHead)); MemFree(p); }

/* 'MemHead' is freed in ARPInput() */ break;

//---------------------------------------------------------------------------

// 以太网数据链路层支持三种数据包。而一般嵌入式 TCP/IP 协议栈只支持IP 数据包和 // ARP 数据包,不支持 RARP 数据包(RARP 数据包针对无盘网络工作)。 //--------------------------------------------------------------------------- default:

/* unknown packet type free */ MemFree(MemHead);

} } }

//=============================================================================

/* ethernet device init */

// 作 者:南开大学-李章林 // 注 释:李清林

// 日 期:2008 年3 月

// 声 明:英文注释由作者李章林添加,中文注释由■李清林添加。 // 转载时请保留上述信息。 ETHERIF.C // 成都理工学院/应用数字系/应用数字专业

//---------------------------------------------------------------------------

// 程序名称:EtherDevInit=以太网数据链路层网络接口设备队列初始化子程序 // 入口参数:

// *pDevice=以太网数据链路层设备指针 // EtherAddr[]=网卡物理地址

// 以太网数据链路层发送指针函数

// BOOL (DT_CODE * send)(void DT_XDATA *buf, WORD size) // 以太网数据链路层接收指针函数

// struct SMemHead DT_XDATA *(DT_CODE * recv)() // 出口参数: // 无

//=============================================================================

void EtherDevInit(struct SEtherDevice DT_XDATA * pDevice, BYTE EtherAddr[],

BOOL (DT_CODE * send)(void DT_XDATA *buf, WORD size) REENTRANT_SIG,

struct SMemHead DT_XDATA *(DT_CODE * recv)() REENTRANT_SIG) REENTRANT_MUL {

// 网卡物理地址拷贝到以太网数据链路层设备驱动结构体指针.Addr 域 MemCopy(pDevice->Addr,EtherAddr,ETHER_ADDR_LEN); // 填写以太网数据链路层设备驱动结构体指针.recv 域 pDevice->recv = recv;

// 填写以太网数据链路层设备驱动结构体指针.send 域 pDevice->send = send; }