#include "sysInclude.h"
extern void ip_DiscardPkt(char* pBuffer,inttype);
extern void ip_SendtoLower(char*pBuffer,int length);
extern void ip_SendtoUp(char *pBuffer,int length);
extern unsigned int getIpv4Address();
// implemented by students
int stud_ip_recv(char *pBuffer,unsigned short length)
{
intVersion=(int)pBuffer[0]>>4;
intIHL=(int)pBuffer[0]&0xf;
int TTL=(int)pBuffer[8];
int Head_Checksum=ntohs(*(short unsignedint*)(pBuffer+10));
int Dst_IP=ntohl(*(intunsigned*)(pBuffer+16));
if(Version!=4)
{
ip_DiscardPkt(pBuffer,STUD_IP_TEST_VERSION_ERROR);
return 1;
}
if(IHL<5)
{
ip_DiscardPkt(pBuffer,STUD_IP_TEST_HEADLEN_ERROR);
return 1;
}
if(TTL==0)
{
ip_DiscardPkt(pBuffer,STUD_IP_TEST_TTL_ERROR);
return 1;
}
if(Dst_IP!=getIpv4Address()&&Dst_IP!=0xffffffff)
{
ip_DiscardPkt(pBuffer,STUD_IP_TEST_DESTINATION_ERROR);
return1;
}
int sum =0;
unsignedshort int localCheckSum = 0;
unsignedshort int field;
intoffset;
for(int i =1;i <=10;i++)//计算校验和
{
offset = (i-1)*2;
if(i != 6)
{
field =(pBuffer[offset])<<8;
field += pBuffer[offset+1];
sum += field;
sum %= 65535;
}
}
localCheckSum = 0xffff - (unsigned shortint)sum;
if(localCheckSum!=Head_Checksum)//检验校验和
{
ip_DiscardPkt(pBuffer,STUD_IP_TEST_CHECKSUM_ERROR);
return 1;
}
ip_SendtoUp(pBuffer,length);
return 0;
}
int stud_ip_Upsend(char *pBuffer,unsigned short len,unsigned intsrcAddr,//unsigned short len最大2^16=64k字节;
unsigned int dstAddr,byte protocol,bytettl)//地址刚好为32位;byte类型为一个字节,是通过网络传输信息的单位
{
char* DstBuffer=new char(len+20);
memset(DstBuffer,0,len+20);
DstBuffer[0]=0x45;
unsigned short Total_len=htons(len+20);
memcpy(DstBuffer+2,&Total_len,16);
DstBuffer[8]=ttl;
DstBuffer[9]=protocol;
unsigned int Scr_IP=htonl(srcAddr);
unsigned int Dst_IP=htonl(dstAddr);
memcpy(DstBuffer+12,&Scr_IP,32);
memcpy(DstBuffer+16,&Dst_IP,32);
intsum=0;
unsignedshort int localCheckSum = 0;
for(inti=0;i<10;i++)
{
sum=sum+(DstBuffer[i*2]<<8)+(DstBuffer[i*2+1]);
sum%=65535;
}
localCheckSum=htons(0xffff-(unsigned shortint)sum);
memcpy(DstBuffer+10,&localCheckSum,sizeof(unsignedshort int));
memcpy(DstBuffer+20,pBuffer,len);
ip_SendtoLower(DstBuffer,len+20);
return 0;
}