ip.c
来自「mcf5307实验源代码」· C语言 代码 · 共 827 行 · 第 1/3 页
C
827 行
if (p->i.protocol == PROTUDP)
{
/* If the destination is either of the broadcast addresses, then
pass it up to UDP.
*/
if (comparen(p->i.ipdest, (void *)nullip, 4) ||
comparen(p->i.ipdest, (void *)broadip, 4))
{
return (udpinterpret ((UDPKT *)p, iplen));
}
/* Compare the incoming packet with our subnet mask. If we are
on the same net then check if this is a UDP packet. If it is
then call udpinterpret. */
our_net = 1;
for(i=3; i>=0; i--)
if((nnmask[i] & p->i.ipdest[i])!=(nnmask[i] & nnipnum[i]))
our_net = 0;
if (our_net)
{
return (udpinterpret ((UDPKT *)p, iplen));
}
/* Finally, check to see if we have an IP address. If not this is
likely a BOOTP response that will provide us with one. */
if (comparen(nnipnum, (void *)nullip, 4))
{
return (udpinterpret ((UDPKT *)p, iplen));
}
}
/* SGJ, should log an error here. */
/* Drop the packet by placing it back on the buffer_freelist. */
dll_update_lists(&buffer_list, &buffer_freelist);
/* Increment the number of IP packets received with the wrong IP addr. */
SNMP_ipInAddrErrors_Inc;
return (1); /* drop packet */
} /* end if */
/* which protocol to handle this packet? */
switch (p->i.protocol)
{
case PROTUDP:
/* Increment the number of IP packets successfully delivered. */
SNMP_ipInDelivers_Inc;
return (udpinterpret((UDPKT *)p, iplen));
case PROTTCP:
/* Increment the number of IP packets successfully delivered. */
SNMP_ipInDelivers_Inc;
/* pass tcplen on to TCP */
return (TCP_Interpret((TCPKT *)p, iplen));
case PROTICMP:
/* Increment the number of IP packets successfully delivered. */
SNMP_ipInDelivers_Inc;
return (icmpinterpret((ICMPKT *)p, iplen));
default:
NU_Tcp_Log_Error (TCP_IP_HIGH_LAYER, TCP_RECOVERABLE,
__FILE__, __LINE__);
/* Drop the packet by placing it back on the buffer_freelist. */
dll_update_lists(&buffer_list, &buffer_freelist);
/* Increment the number of IP packets received with a invalid
protocol field. */
SNMP_ipInUnknownProtos_Inc;
return (1);
} /* end switch */
} /* end ipinterpret */
/******************************************************************************/
/* */
/* FUNCTION */
/* */
/* icmpinterpret */
/* */
/* DESCRIPTION */
/* */
/* Interpret the icmp message that just came off the wire */
/* */
/* CALLED BY */
/* ipinterpret */
/* */
/* CALLS */
/* */
/* ipcheck */
/* neticmpturn */
/* netputevent */
/* dll_update_lists */
/* */
/******************************************************************************/
static int16 icmpinterpret (ICMPKT *p, uint16 icmplen)
{
uint16 i;
IPLAYER *iptr;
/* Increment the total number of ICMP messages received. */
SNMP_icmpInMsgs_Inc;
i = p->c.type;
if (p->c.check)
{ /* ignore if chksum=0 */
if (ipchecklen ((int8 *)&p->c, (uint16)(icmplen >> 1)))
{
NU_Tcp_Log_Error (TCP_ICMP_CKSUM, TCP_RECOVERABLE,
__FILE__, __LINE__);
/* Drop the packet by placing it back on the buffer_freelist. */
dll_update_lists(&buffer_list, &buffer_freelist);
/* Increment the number of ICMP messages received with errors. */
SNMP_icmpInErrors_Inc;
return (-1);
} /* end if */
} /* end if */
switch(i)
{
case 8: /* ping request sent to me */
/* Increment the number of Echo requests received. */
SNMP_icmpInEchos_Inc;
p->c.type = 0; /* echo reply type */
/* Increment the number of Echo replies sent. */
SNMP_icmpOutEchoReps_Inc;
neticmpturn (p, icmplen); /* send back */
break;
case 5: /* ICMP redirect */
iptr = (IPLAYER *)p->data;
netputevent (ICMPCLASS, IREDIR, 0); /* event to be picked up */
memcpy ((void *)nnicmpnew, (const void *)&p->c.part1, 4); /* new gateway */
memcpy ((void *)nnicmpsave, (const void *)iptr->ipdest, 4); /* dest address */
/* Increment the number of Redirect messages received. */
SNMP_icmpInRedirects_Inc;
break;
case 4: /* ICMP source quench */
OKpackets = 0;
SQwait += 100;
/* Increment the number of Source Quench messages received. */
SNMP_icmpInSrcQuenchs_Inc;
break;
default:
/* Increment the number of ICMP messages received with errors. */
SNMP_icmpInErrors_Inc;
break;
} /* end switch */
/* Drop the packet by placing it back on the buffer_freelist. */
dll_update_lists(&buffer_list, &buffer_freelist);
return (0);
} /* end icmpinterpret() */
/******************************************************************************/
/* */
/* FUNCTION */
/* */
/* neticmpturn */
/* */
/* DESCRIPTION */
/* */
/* send out an icmp packet, probably in response to a ping operation */
/* interchanges the source and destination addresses of the packet, */
/* puts in my addresses for the source and sends it */
/* */
/* does not change any of the ICMP fields, just the IP and dlayers */
/* returns 0 on okay send, nonzero on error */
/* */
/* CALLED BY */
/* icmpinterpret */
/* */
/* CALLS */
/* */
/* intswap */
/* ipcheck */
/* */
/* NAME DATE REMARKS */
/* */
/* Glen Johnson 05/01/96 Fixed a bug in the transmission of the ICMP */
/* packet. */
/* */
/******************************************************************************/
static int16 neticmpturn (ICMPKT *p, uint16 ilen)
{
ICMPKT *icmp_pkt;
struct pqueue HUGE *buf_ptr;
if (comparen (p->d.me, (VOID *)broadaddr, DADDLEN))
return(0);
/* Allocate a buffer to place the packet in. */
buf_ptr = (struct pqueue HUGE *)dll_dequeue((tqe_t *)&buffer_freelist);
if(buf_ptr == NU_NULL)
return (NU_NO_BUFFERS);
/* Overlay the packet so that individual fields can be accessed. */
icmp_pkt = (ICMPKT *)buf_ptr->packet;
/* Copy the received packet into the outgoing packet. The received packet
can be used almost as is. Only a few fields need to be swapped. */
memcpy (icmp_pkt, p, sizeof (DLAYER) + sizeof (IPLAYER) + ilen);
/* Swap the destination and source addresses. */
memcpy ((void *)icmp_pkt->d.dest, (const void *)icmp_pkt->d.me,
DADDLEN);
memcpy ((void *)icmp_pkt->i.ipdest, (const void *)icmp_pkt->i.ipsource,
4);
memcpy ((void *)icmp_pkt->d.me, (const void *)nnmyaddr, DADDLEN);
memcpy ((void *)icmp_pkt->i.ipsource, (const void *)nnipnum, 4);
/* Prepare ICMP checksum */
icmp_pkt->c.check = 0;
icmp_pkt->c.check = ipchecklen ((int8 *) &icmp_pkt->c,
(uint16)(ilen >> 1));
/* Prepare iplayer for send */
icmp_pkt->i.ident = intswap ((uint16)nnipident++);
icmp_pkt->i.check = 0;
icmp_pkt->i.check = ipchecklen ((int8 *) &icmp_pkt->i, 10);
/* Increment the number of IP packets transmitted. */
SNMP_ipOutRequests_Inc;
/* Increment the number of ICMP messages sent. */
SNMP_icmpOutMsgs_Inc;
/* Send the packet. */
return (NET_Send(buf_ptr, (int16)(sizeof(DLAYER) + sizeof(IPLAYER) + ilen),
OTHER_PKT));
} /* end neticmpturn */
#ifdef IP_FRAG
/*************************************************************************/
/* */
/* FUNCTION */
/* */
/* ip_reassembly */
/* */
/* DESCRIPTION */
/* */
/* This function takes an IP fragment, checks to see if other fragments */
/* from the same packet has arrived, and then calls the appropriate */
/* routine to handle the fragment. */
/* */
/* CALLED BY */
/* ipinterpret */
/* */
/* CALLS */
/* first_frag */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?