#include <iostream>
#include <stdio.h>
#include <string>
#include <stdlib.h>
#include <math.h>
#define DataSize 5000
#define MTU 60
using namespace std;
// IP头部结构
typedef struct header
{
unsigned char VIHL; // Version and IHL
unsigned char ToS; // Type of Service
unsigned short TotalLen; // Total Length
unsigned short ID; // Identfication
unsigned short FlagOff; // Flags and Fragment Offset
unsigned char TTL; // Time to Live
unsigned char Protocol; // Protocol
unsigned short Checksum; // Checksum
unsigned long SrcAddr; // Source Address
unsigned long DstAddr; // Destination Address
char *Data; // data
}IPHeader,*pIPHeader;
// 重组资源结构
typedef struct buf
{
char *Data; // 数据缓冲
IPHeader ipHeader; // 头部缓冲
unsigned char *RCVBT; // 分片块位表
unsigned int TDL; // 总数据长度头部
unsigned short TIMER; // 定时器
unsigned int BUFID; // BUFID
}BUFFER, *pBUFFER;
/*****************************************************************
函数聲明
*****************************************************************/
short CheckSum(IPHeader ipHeader); // 校验和计算函数
void bit_set(void *buf, int offset); // 置1函数
int bit_isset(void *buf, int offset); // 置1判断函数
void Fragment(IPHeader ipHeader); // 分片函数
void Reassembly(IPHeader ipHeader); // 重组函数
void read(); // 读取分片函数
/*****************************************************************
函数名:CheckSum
描述:校验和计算
参数:IPHeader ipHeader
return:unsigned short checkSum
*****************************************************************/
short CheckSum(IPHeader ipHeader)
{
unsigned short checkSum;
int sum;
sum = ((ipHeader.VIHL<<8)+ipHeader.ToS)
+ipHeader.TotalLen
+ ipHeader.ID
+ ipHeader.FlagOff
+ ((ipHeader.TTL<<8)+ipHeader.Protocol)
+ (ipHeader.SrcAddr>>16)
+(ipHeader.SrcAddr&65535)
+(ipHeader.DstAddr>>16)
+ (ipHeader.DstAddr&65535);
while (sum>65535)
{
sum = (sum>>16) + (sum&65535);
}
checkSum = (unsigned short)~sum;
return checkSum;
}
/*****************************************************************
函数名:bit_set
描述:位置1函数
参数:void *buf, int offset
return:NULL
*****************************************************************/
void bit_set(void *buf, int offset)
{
((char*)buf)[offset >> 3] |= 1 << (offset & 7);
}
/*****************************************************************
函数名:bit_isset
描述:位置判断函数
参数:void *buf, int offset
return: 1
0
*****************************************************************/
int bit_isset(void *buf, int offset)
{
if(((char*)buf)[offset >> 3] & 1 << (offset & 7))
return 1;
else
return 0;
}
/*****************************************************************
函数名:Fragment
描述:分片函数
参数:IPHeader ipHeader
return:NULL
*****************************************************************/
void Fragment(IPHeader ipHeader)
{
FILE *fb;
int NFB;
unsigned short checkSum;
IPHeader first_fragment; // 第一个分片
IPHeader second_fragment; // 第二个分片
checkSum = CheckSum(ipHeader);
printf("Fragment GO!!!\n");
if(checkSum != ipHeader.Checksum) // 验证校验和
{
printf("%x,,,,%x",checkSum, ipHeader.Checksum);
//free(ipHeader); // 如果数据出错丢弃数据
//ipHeader = NULL;
printf("Header Error!!!\n");
return;
}
if(ipHeader.TotalLen <= MTU) // 如果不需要分片交给下一步处理
{
fb = fopen("fragment", "ab");
if(NULL==fb)
{
printf("Open File Error!!!\n");
return;
}
else
{
printf("%s\t\tstrlen = %d\n", ipHeader.Data, strlen(ipHeader.Data));
printf("FO = %d,MF = %d\n", ipHeader.FlagOff&8191, (ipHeader.FlagOff>>13));
printf("Fragment OK!!!\n++++++++++++++++++++++++++++++++++++++\n");
fwrite(&ipHeader, sizeof(ipHeader), 1, fb);
fclose(fb);
return;
}
}
else if((ipHeader.FlagOff>>14) == 1) // if > MTU and DF
{
//free(ipHeader); // 丢弃数据
//ipHeader = NULL;
printf("discard the datagram!!!\n");
return;
}
else
{
/*To produce the first fragment:*/
first_fragment = ipHeader; // 拷贝头部
first_fragment.Data = NULL;
NFB = (MTU-(ipHeader.VIHL&15)*4)/8; // 计算块数量
first_fragment.Data = new char[NFB*8+1]; // 开辟数据空间
memcpy(first_fragment.Data, ipHeader.Data, NFB*8); // 拷贝分片数据
first_fragment.Data[NFB*8] = '\0';
if((first_fragment.FlagOff>>13) != 1)
{
first_fragment.FlagOff += 8192; // MF set 1
}
printf("FO = %d,MF = %d\n", first_fragment.FlagOff&8191, (first_fragment.FlagOff>>13));
first_fragment.TotalLen = (ipHeader.VIHL&15)*4 + strlen(first_fragment.Data); // 计算第一个分片总长
printf("Data = %s\nfirst_fragment.TotalLen= %d\n", first_fragment.Data, first_fragment.TotalLen);
first_fragment.TTL--;
first_fragment.Checksum = CheckSum(first_fragment); // 重新计算校验和
fb = fopen("fragment", "ab");
if(NULL==fb)
{
printf("Open File Error!!!\n");
return;
}
else
{
fwrite(&first_fragment, sizeof(first_fragment), 1, fb);
fclose(fb);
}
/*To produce the second fragment:*/
second_fragment = ipHeader;
second_fragment.Data = ipHeader.Data+NFB*8; // Append the remaining data
second_fragment.VIHL = ((ipHeader.VIHL*4-(0))+3)