网络协议栈设计(二)---类型定义及变量声明

网络协议栈设计(二)

通过上一篇的介绍,相信大家对我们网络协议栈的设计已经有了初步的认识和了解。最初的编程环境也都建立了起来。
在本篇中,我们对于协议栈的设计在进行一些说明以及对需要用到的全局变量的作一些定义。
注:下边所有的类型定义和全局变量的定义都是在开发的过程中慢慢完善起来的,在此一次性给大家展示出来只是让大家先作一了解,知道有这些变量的定义,所以大家对于不是很懂的变量定义不要着急,后边的开发中如果用到会再次给大家说明需要定义的全局变量有哪些,大家可以在开发的过程中慢慢体会。

再注:首先在此说明,因为我们时间有限,所以只实现网络协议栈的主体功能,从而达到对网络协议栈更深层次的了解和学习的目的。协议栈的设计分小组完成,我负责发送方代码编写。而且,为了简化设计,我们默认发送方只发送数据,接受方只接受数据并且发送确认。所以,在接下的设计中,我们只需要关心发送方对于数据发送的需求和对接收方发送的确认数据包的接收和处理。(如果我将我的发送方介绍完有时间可以将小伙伴写的接收方代码更新给大家)

一、数据类型的定义

首先要介绍的是类型定义,大家知道,网络数据的处理大多数时候是以字节为单位的,而且我们并不关心数据的真正含义,所以在winpcap packet的bittypes.h文件中为我们定义了一系列的字节为单位的数据类型,如下:

u_int8_t 1字节
u_int16_t 2字节
u_int32_t 4字节
u_int64_t 8字节

头文件中采用条件编译,所以无论哪种编译环境均可直接使用此类型定义相应字节长度的变量。在此以1字节类型的定义为大家展示一下,方便大家理解:

#ifndef HAVE_U_INT8_T

#if SIZEOF_CHAR == 1
typedef unsigned char u_int8_t;
typedef signed char int8_t;
#elif SIZEOF_INT == 1
typedef unsigned int u_int8_t;
typedef signed int int8_t;
#else  /* XXX */
#error "there's no appropriate type for u_int8_t"
#endif
#define HAVE_U_INT8_T 1
#define HAVE_INT8_T 1

#endif /* HAVE_U_INT8_T */

二、头文件打包

1、我们将一些会经常用到的头文件打包到Header_Include.h中,在每个源文件中只需要包含此头文件就好了。

//Header_Include.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<time.h>

//这两个是winpcap的头文件,其包含了所有winpcap中头文件的声明
#include<pcap.h>
#include<WinSock2.h>

#define HAVE_REMOTE     
#define WPCAP


#pragma warning(disable:4996)  
//将4996报警置为默认  warning C4996: strcpy was declared deprecated

2、我们还在一个头文件Resource.h中定义了一些将要用的数据包类型

//Resource.h

#pragma once
#define MAX_SIZE 2048            //加载数据包的数组长度,我们设置的长度比以太网最长1518稍大一些
#define ETHERNET_IP 0X0800       //IP数据包类型
#define ETHERNET_ARP 0X0806      //ARP数据包类型
#define ETHERNET_RARP 0X8035     //RARP数据包类型

#define ARP_HARDWARE 0X0001      //ARP数据包硬件类型
#define ARP_REQUEST 0X0001       //ARP请求数据包
#define ARP_REPLY 0X0002         //ARP回复数据包
#define MAX_IP_PACKET_SIZE 1400  //IP数据包最大长度

//ARP表中表项的状态
#define STATIC_STATE 0
#define DYNAMIC_STATE 1
#define LOGGING_STATE 2

三、3、全局变量的定义

我们在Global_Variable.cpp中定义了我们需要用到的全局变量。

//Global_Variable.cpp
u_int8_t local_mac[6] = { 0xf0, 0xde, 0xf1, 0xff, 0x34, 0xda };     //6字节的本地MAC地址
u_int8_t local_ip[4] = { 10, 20, 2, 1 };                            //4字节的本地IP地址
u_int8_t gateway_ip[4] = { 10, 20, 2, 1 };                          //4字节的本地IP地址
u_int8_t netmask[4] = { 255, 255, 255, 0 };                         //4字节的网关IP地址
u_int8_t dns_server_ip[4] = { 61, 134, 1, 4 };                      //4字节的DNS服务器IP地址
u_int8_t dhcp_server_ip[4] = { 222, 24, 192, 2 };                   //4字节的DHCP服务器IP地址
u_int8_t broadcast_mac[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; //局域网广播的MAC地址
//以上变量的值根据所处网络环境的不同填上符合自己网络环境的值即可

u_int8_t ip_buffer[MAX_SIZE];  //装载IP数据报的数组
pcap_t *handle;                //网卡句柄
int ethernet_upper_len;        //以太网上层交付的数据包长度

u_int8_t target_ip[4] = { 10, 20, 2, 242 };   //4字节的目标IP
u_int8_t sever_ip[4] = { 10,20, 2, 242 };     //4字节的服务器IP
//这两个本质上是相同的,只是在传输层的时候我们起名叫服务器IP地址,网路层的时候起名叫目标IP地址


//下边这边变量是进行各层交互使用的的一些标记以及TCP层的变量定义
u_int8_t * dest_mac;          //MAC地址指针,保存ARP请求解析后返回的MAC地址
int ipv4_icmp_flag=0;         //收到ICMP报文的标记
char *device;                 //驱动句柄
u_int16_t source_port=htons(6000);  //源端头
u_int16_t sever_port=htons(6000);   //服务器端口    关于htons()我们后边再说
int tcp_ack;                 //TCP确认
int c_seq;                   //客户端当前发送的字节序号
int s_seq;                   //服务器端当前发送的字节序号
int window;                  //TCP协商的窗口大小
int tcp_recv_type;           //接受到的TCP数据包的类型    这个我们后边再讨论
int ack_num;                 //当前已经确认的序号 
int Mss=200;                 //最大报文段
u_int16_t local_port;        //本地端口号

大家看了以上的定义也许是一脸懵逼,但不要紧。下一篇就开始给大家带来数据链路层以太网设计,慢慢在应用中体会它们的用处。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值