#include "sysInclude.h"
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
/********************************************************************
* macros
********************************************************************/
#define TCP_STATE_CLOSED 0
#define TCP_STATE_SYN_SENT 1
#define TCP_STATE_ESTABLISHED 2
#define TCP_STATE_FIN_WAIT1 3
#define TCP_STATE_FIN_WAIT2 4
#define TCP_STATE_TIME_WAIT 5
#define TCP_HEADER_SIZE 20
#define MAX_TCB_NUMBER 20
#define MAX_TIMEOUT 5000
#define MAX_RETRY_NUMBER 100
#define MAX_WINDOW_SIZE 1
#define DEFAULT_TTL 64
#define MAX_DATA_SIZE 512
/********************************************************************
* interfaces implemented by system
********************************************************************/
extern void tcp_DiscardPkt(char *pBuffer, int type);
extern void tcp_sendReport(int type);
extern void tcp_sendIpPkt( unsigned char *pData,
UINT16 len,
unsigned int srcAddr,
unsigned int dstAddr,
UINT8 ttl);
extern int waitIpPacket(char *pBuffer, int timeout);
extern unsigned int getIpv4Address();
extern unsigned int getServerIpv4Address();
/********************************************************************
* 自定义函数和结构体
********************************************************************/
struct TCBStruct
{
bool used;
unsigned int srcAddr;
unsigned int dstAddr;
unsigned short srcPort;
unsigned short dstPort;
unsigned int seq;
unsigned int ack;
unsigned short state;
unsigned short window;
};
struct PseudoHeader
{
unsigned int srcAddr;
unsigned int dstAddr;
char mbz;
char proto;
unsigned short len;
};
struct TcpPacket
{
unsigned short source;
unsigned short dest;
unsigned int seq;
unsigned int ack;
unsigned char len;
unsigned char flag;
unsigned short window;
unsigned short check;
unsigned short urg_ptr;
char data[MAX_DATA_SIZE];
};
int gSrcPort = 2007;
int gDstPort = 2006;
int gSeqNum = 20180415;
int gAckNum = 0;
/* 分配全局TCB数组 */
struct TCBStruct TCB[MAX_TCB_NUMBER];
int activeSockfd = -1;
unsigned short checksum(unsigned short *addr, int count);
bool verifyTCB(int sockfd);
char *packTCPPacket(char *pData, unsigned int len, unsigned char flag);
void destoryTCB(int sockfd);
/********************************************************************
* 函数实现
********************************************************************/
/* stud_tcp_input()
* Parameters:
*** pBuff 指向接收缓冲区的指针,从TCP头开始
*** len 缓冲区数据长度
*** srcAddr 源IP地址
*** dstAddr 目的IP地址
* Return Value:
*** -1 失败
*** 0 成功
*/
int stud_tcp_input( char *pBuffer,
unsigned short len,
unsigned int srcAddr,
unsigned int dstAddr)
{
struct TcpPacket *head = (struct TcpPacket *)pBuffer;
/**Step1... 验证校验和。首先构造伪头部,然后调用 checksum() 算法 */
struct PseudoHeader pHead;
pHead.srcAddr = htonl(TCB[activeSockfd].srcAddr);
pHead.dstAddr = htonl(TCB[activeSockfd].dstAddr);
pHead.mbz = 0;
pHead.proto = IPPROTO_TCP;
pHead.len = htons(TCP_HEADER_SIZE);
char *temp = (char *)malloc(len + sizeof(struct PseudoHeader));
memcpy((void *)temp, (void *)pBuffer, len);
memcpy((void *)(temp + len), (void *)&pHead, sizeof(struct PseudoHeader));
unsigned int sum = checksum((unsigned short *)temp, len + sizeof(struct PseudoHeader));
if( sum != 0 )
return -1;
/**Step2... 检查序号 */
int ins = 1;
if(TCB[activeSockfd].state == TCP_STATE_FIN_WAIT2)
ins = 0;
if( ntohl(head->ack) != ( TCB[activeSockfd].seq + ins ) )
{
tcp_DiscardPkt(pBuffer, STUD_TCP_TEST_SEQNO_ERROR);
return -1;
}
/**Step3... 状态转换 */
TCB[activeSockfd].ack = ntohl(head->seq) + 1;
TCB[activeSockfd].seq = ntohl(head->ack);
if( TCB[activeSockfd].state == TCP_STATE_FIN_WAIT1 )
{
TCB[activeSockfd].state = TCP_STATE_FIN_WAIT2;
return 0;
}
else if( TCB[activeSockfd].state == TCP_STATE_SYN_SENT )
TCB[activeSockfd].state = TCP_STATE_ESTABLISHED;
else if( TCB[activeSockfd].state == TCP_STATE_FIN_WAIT2 )
TCB[activeSockfd].state = TCP_STATE_TIME_WAIT;
else
return -1;
/**Step4... 回应ACK报文 */
stud_tcp_output(NULL, 0, PACKET_TYPE_ACK,
gSrcPort,
gDstPort,
getIpv4Address(),
getServerIpv4Address());
return 0;
}
//TCP段输出函数,完成TCP协议的封装发送功能
/* stud_tcp_output()
* Parameters:
*** pData 数据指针
*** len 数据长度
*** flag 分组类型
*** srcPort 源端口
*** dstPort 目的端口
*** srcAddr 源IP地址
*** dstAddr 目的IP地址
* Return Value:
*** void
*/
void stud_tcp_output( char *pData,
unsigned short len,
unsigned char flag,
unsigned short srcPort,
unsigned short dstPort,
unsigned int srcAddr,
unsigned int dstAddr)
{
/**Step1... activeSockfd 是否有效?*/
if( !verifyTCB(activeSockfd) )
{
activeSockfd = 0;
TCB[activeSockfd].used = true;
TCB[activeSockfd].window = MAX_WINDOW_SIZE;
TCB[activeSockfd].seq = gSeqNum;
TCB[activeSockfd].ack = gAckNum;
TCB[activeSockfd].srcAddr = srcAddr;
TCB[activeSockfd].dstAddr = dstAddr;
TCB[activeSockfd].srcPort = srcPort;
TCB[activeSockfd].dstPort = dstPort;
TCB[activeSockfd].state = TCP_STATE_CLOSED;
}
/**Step2... 状态转换机 */
if( flag == PACKET_TYPE_SYN &&
TCB[activeSockfd].state == TCP_STATE_CLOSED )
TCB[activeSockfd].state = TCP_STATE_SYN_SENT;
if( flag == PACKET_TYPE_FIN_ACK &&
TCB[activeSockfd].state == TCP_STATE_ESTABLISHED)
TCB[activeSockfd].state = TCP_STATE_FIN_WAIT1;
/**Step3... 发送报文 */
char *pBuffer = packTCPPacket(pData, len, flag);
tcp_sendIpPkt((unsigned char *)pBuffer, 20 + len, srcAddr, dstAddr, DEFAULT_TTL);
}
/* stud_tcp_socket()创建新的TCB结构,并对成员变量进行初始化,
* 为每个TCB结构分配唯一的套接口描述符。
* Parameters:
*** domain 套接字域(默认为 AF_INET)
*** type 套接字类型(默认为SOCK_STREAM)
*** protocol 套接字协议类型(默认为IPPROTO_TCP)
* Return Value:
*** -1 函数分配socket id 失败
*** socket id 函数分配的全局唯一的socket id
*/
int stud_tcp_socket(int domain, int type, int protocol)
{
if (domain != AF_INET ||
type != SOCK_STREAM ||
protocol != IPPROTO_TCP )
return -1;
/**Attention!!! 由于 sockfd == 0, 已经默认分配给系统通信,所以此处从1开始分配*/
int i = 1;
for ( ; i < MAX_TCB_NUMBER; i ++)
if ( TCB[i].used == false )
break;
if ( i == MAX_TCB_NUMBER )
return -1;
TCB[i].used = true;
TCB[i].window = MAX_WINDOW_SIZE;
TCB[i].seq = gSeqNum;
TCB[i].ack = gAckNum;
TCB[i].srcAddr = getIpv4Address();
TCB[i].dstAddr = getServerIpv4Address();
TCB[i].srcPort = gSrcPort ++;
TCB[i].dstPort = gDstPort;
TCB[i].state = TCP_STATE_C
Quantum-Man
- 粉丝: 0
- 资源: 3
最新资源
- 基于Vue.js快速构建python桌面应用程序的模板项目源码+运行教程(支持打包为可执行文件).zip
- 防护具检测57-YOLO(v5至v9)、COCO、CreateML、Darknet、Paligemma、TFRecord、VOC数据集合集.rar
- 视频下载-b站视频下载器
- CSV数据操作的工具包-含合并CSV文件、Excel转CSV、CSV转XLSX、统计CSV行数、重命名表头、选择和重排CSV列等功能.zip
- App商店优化(ASO)权威指南:提高App可见度与转化率的技术策略
- Pangu-Agent: 强化学习与大型语言模型相结合的一般智能体框架
- TomVPN_3.0.7.apk
- AEC论文解读 - ACOUSTIC ECHO CANCELLATION WITH THE DUAL-SIGNAL TRANSFORMATION LSTM NETWORK
- Vegetation Studio 1.5.3
- 阀门检测49-YOLO(v5至v9)、COCO、CreateML、Darknet、Paligemma、TFRecord、VOC数据集合集.rar
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
- 1
- 2
- 3
前往页