接上文https://blog.csdn.net/zhang1806618/article/details/107856736
2.3 网络层
NETWORK_ReceivePacketFromMacLayer函数区分网络层协议调用相应协议处理。对IPv4协议,调用NetworkIpReceivePacketFromMacLayer()函数,该函数又直接调用NetworkIpReceivePacket()函数。在NetworkIpReceivePacket()函数中,判断是否是发送给本节点的包,如果不是,直接转发;如果是,经由背板处理,另外判断是否多播包,多播包还需转发。
void NetworkIpReceivePacket(
Node *node,
Message *msg,
NodeAddress previousHopAddress,
int incomingInterface)
{
NetworkType netType = NETWORK_IPV4;
//是发送给本节点的包
if (IsMyPacket(node, ipHeader->ip_dst) || IsIgmpPacket(node, ipHeader->ip_p))
{
BOOL isMulticast = NetworkIpIsMulticastAddress(node, ipHeader->ip_dst);
Message* sendMessage = msg;
if (isMulticast)
{
sendMessage = MESSAGE_Duplicate(node, msg);
}
//经由背板处理
NetworkIpSendOnBackplane(node,
sendMessage,
incomingInterface,
CPU_INTERFACE,
previousHopAddress);
//多播包,背板处理之余还要转发
if (isMulticast)
{
ForwardPacket(node, msg, incomingInterface, ANY_IP);
}
}
//不是发给本节点的包,直接转发
else
{
ForwardPacket(node, msg, incomingInterface, previousHopAddress);
}
}
ForwardPacket()函数用于转发,会进入到发送程序,此处不赘述。NetworkIpSendOnBackplane()函数在介绍发送端过程时已介绍,在无容量限制时,调用DeliverPacket()函数将数据上传至传输层;在容量限制时,调用NetworkIpUseBackplaneIfPossible()再调用DeliverPacket()函数。在DeliverPacket()函数中去除IP首部,然后根据传输层协议分别调用相应协议函数处置。
void //inline//
DeliverPacket(Node *node, Message *msg,
int interfaceIndex, NodeAddress previousHopAddress)
{
NetworkIpRemoveIpHeader(node, msg, &sourceAddress, &destinationAddress,
&priority, &ipProtocolNumber, &ttl);
switch (ipProtocolNumber)
{
//上传的传输层协议
case IPPROTO_UDP:
{
SendToUdp(node, msg, priority, sourceAddress, destinationAddress,
interfaceIndex);
break;
}
case IPPROTO_TCP:
{
SendToTcp(node, msg, priority, sourceAddress, destinationAddress,
aCongestionExperienced);
break;
}
}
}
以UDP协议为例,SendToUdp()函数调度传输层协议UDP事件 MSG_TRANSPORT_FromNetwork,由传输层事件处理函数处理。
void
SendToUdp(
Node *node,
Message *msg,
TosType priority,
NodeAddress sourceAddress,
NodeAddress destinationAddress,
int incomingInterfaceIndex)
{
NetworkToTransportInfo *infoPtr;
MESSAGE_SetEvent(msg, MSG_TRANSPORT_FromNetwork);
MESSAGE_SetLayer(msg, TRANSPORT_LAYER, TransportProtocol_UDP);
MESSAGE_SetInstanceId(msg, 0);
MESSAGE_InfoAlloc(node, msg, sizeof(NetworkToTransportInfo));
infoPtr = (NetworkToTransportInfo *) MESSAGE_ReturnInfo(msg);
SetIPv4AddressInfo(&infoPtr->sourceAddr, sourceAddress);
SetIPv4AddressInfo(&infoPtr->destinationAddr, destinationAddress);
infoPtr->priority = priority;
infoPtr->incomingInterfaceIndex = incomingInterfaceIndex;
MESSAGE_Send(node, msg, PROCESS_IMMEDIATELY);
}
2.4 传输层
传输层事件处理函数TRANSPORT_ProcessEvent()根据协议UDP调用函数TransportUdpLayer(),进而根据事件 MSG_TRANSPORT_FromNetwork调用函数TransportUdpSendToApp()。在该函数中,去除UDP首部,将事件层更改为应用层,将事件更改为MSG_APP_FromTransport,进而让应用层事件处理函数处理该数据包。
void
TransportUdpSendToApp(Node *node, Message *msg)
{
MESSAGE_SetLayer(msg, APP_LAYER, udpHdr->destPort);
MESSAGE_SetEvent(msg, MSG_APP_FromTransport);
MESSAGE_SetInstanceId(msg, 0);
MESSAGE_RemoveHeader(node, msg, sizeof(TransportUdpHeader), TRACE_UDP);
MESSAGE_Send(node, msg, TRANSPORT_DELAY);
}
2.5 应用层
应用层事件处理函数APP_ProcessEvent根据应用层协议选择相应的协议处理函数,在协议处理函数中再根据事件类型MSG_APP_FromTransport进行相应的处理。