数据包结构定义

1 数据包结构定义

1.1 数据包的结构

通信过程中数据包的传递如下:
在这里插入图片描述
我们改如何定义数据包结构呢?

  • 数据包长度不固定,可长可短。
  • 需支持头部的添加和移除。
  • 简单易于使用。

数据包结构如下:
在这里插入图片描述

1.2 代码实现

在这里插入图片描述
首先看下整个工程文件的组成:
在这里插入图片描述

xnet_tiny.h中添加如下内容:

#ifndef XNET_TINY_H
#define XNET_TINY_H

#include <stdint.h>

#define XNET_CFG_PACKET_MAX_SIZE        1516        // 收发数据包的最大大小

/**
 * 网络数据结构
 */
typedef struct _xnet_packet_t{
    uint16_t size;                              // 包中有效数据大小
    uint8_t * data;                             // 包的数据起始地址
    uint8_t payload[XNET_CFG_PACKET_MAX_SIZE];  // 最大负载数据量
}xnet_packet_t;

xnet_packet_t * xnet_alloc_for_send(uint16_t data_size);
xnet_packet_t * xnet_alloc_for_read(uint16_t data_size);

void xnet_init (void);
void xnet_poll(void);

#endif // XNET_TINY_H

xnet_tiny.c中添加如下内容:

#include "xnet_tiny.h"

#define min(a, b)               ((a) > (b) ? (b) : (a))

static xnet_packet_t tx_packet, rx_packet;                      // 接收与发送缓冲区

/**
 * 分配一个网络数据包用于发送数据
 * @param data_size 数据空间大小
 * @return 分配得到的包结构
 */
xnet_packet_t * xnet_alloc_for_send(uint16_t data_size) {
    // 从tx_packet的后端往前分配,因为前边要预留作为各种协议的头部数据存储空间
    tx_packet.data = tx_packet.payload + XNET_CFG_PACKET_MAX_SIZE - data_size;
    tx_packet.size = data_size;
    return &tx_packet;
}

/**
 * 分配一个网络数据包用于读取
 * @param data_size 数据空间大小
 * @return 分配得到的数据包
 */
xnet_packet_t * xnet_alloc_for_read(uint16_t data_size) {
    // 从最开始进行分配,用于最底层的网络数据帧读取
    rx_packet.data = rx_packet.payload;
    rx_packet.size = data_size;
    return &rx_packet;
}

/**
 * 为发包添加一个头部
 * @param packet 待处理的数据包
 * @param header_size 增加的头部大小
 */
static void add_header(xnet_packet_t *packet, uint16_t header_size) {
    packet->data -= header_size;
    packet->size += header_size;
}

/**
 * 为接收向上处理移去头部
 * @param packet 待处理的数据包
 * @param header_size 移去的头部大小
 */
static void remove_header(xnet_packet_t *packet, uint16_t header_size) {
    packet->data += header_size;
    packet->size -= header_size;
}

/**
 * 将包的长度截断为size大小
 * @param packet 待处理的数据包
 * @param size 最终大小
 */
static void truncate_packet(xnet_packet_t *packet, uint16_t size) {
    packet->size = min(packet->size, size);
}

/**
 * 协议栈的初始化
 */
void xnet_init (void) {
}

/**
 * 轮询处理数据包,并在协议栈中处理
 */
void xnet_poll(void) {
}

app.c:

#include <stdio.h>
#include "xnet_tiny.h"

int main (void) {
    xnet_init();

    printf("xnet running\n");
    while (1) {
        xnet_poll();
    }

    return 0;
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实验三 发送TCP数据包 实验目的: 设计一个发送TCP数据包的程序,并根据本设计说明TCP数据包结构以及TCP协议与 IP协议的关系,使大家对TCP协议的工作原理有更深入的认识。 实验要求: 本程序的功能是填充一个TCP数据包,并发送给目的主机。 以命令行形式运行:SendTCP source_ip source_port dest_ip dest_port 其SendTCP为程序名;source_ip为源IP地址; source_port为源端口; dest_ip为目的IP地址; dest_port为目的端口。 其他的TCP头部参数自行设定。 数据字段为"This is my homework of network!". 成功发送后在屏幕上输出"send OK"。 课程设计分析: 使用原始套接字 定义IP头部、TCP头部和伪头部的数据结构 填充数据包 发送数据包 设计思想: 本课程设计的目标是发送一个TCP数据包,可以利用原始套接字来完成这个工作。整个程 序由初始化原始套接字和发送TCP数据包两个部分组成。 创建一个原始套接字,并设置IP头选项 SOCKET sock; sock = socket(AF_INET,SOCK_RAW,IPPROTO_IP); 或者: sock=WSASoccket(AF_INET,SOCK_RAW,IPPROTO_IP,NULL,0,WSA_FLAG_OVERLAPPED); 设置SOCK_RAW标志,表示我们声明的是一个原始套接字类型。 为使用发送接收超时设置,必须将标志位置位置为WSA_FLAG_OVERLAPPED。在本课程设计 ,发送TCP包时隐藏了自己的IP地址,因此我们要自己填充IP头,设置IP头操作选项。 其flag设置为ture,并设定 IP_HDRINCL 选项,表明自己来构造IP头。注意,如果设置IP_HDRINCL 选项,那么必须具有 administrator权限,要不就必须修改注册表: HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Afd\Parameter\ 修改键:DisableRawSecurity(类型为DWORD),把值修改为 1。如果没有,就添加。 BOOL Flag=TRUE; setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&Flag, sizeof(Flag)); int timeout=1000; setsockopt(sock, SOL_SOCKET,SO_SNDTIMEO,(char*)&timeout, sizeof(timeout)); 在这里我们使用基本套接字SOL_SOCKET,设置SO_SNDTIMEO表示使用发送超时设置,超时 时间设置为1000ms。 构造IP头和TCP头 这里, IP头和TCP头以及TCP伪部的构造请参考下面它们的数据结构。 计算校验和的子函数 在填充数据包的过程,需要调用计算校验和的函数checksum两次,分别用于校验IP头 和TCP头部(加上伪头部),其实现代码如下: USHORT checksum(USHORT *buffer, int size) { unsigned long cksum=0; while(size >1) { cksum+=*buffer++; size -=sizeof(USHORT); } if(size ) { cksum += *(UCHAR*)buffer; } cksum = (cksum >> 16) + (cksum & 0xffff); cksum += (cksum >>16); return (USHORT)(~cksum); } 程序流程图: 源程序代码: #include <stdio.h> #include <winsock2.h> #include <ws2tcpip.h> #include <time.h> #include <windows.h> #include <string.h> #include <stdlib.h> #include <iostream.h> #pragma comment(lib,"ws2_32.lib") #define IPVER 4 //IP协议预定 #define MAX_BUFF_LEN 65500 //发送缓冲区最大值 typedef struct ip_hdr //定义IP首部 { UCHAR h_verlen; //4位首部长度,4位IP版本号 UCHAR tos; //8位服务类型TOS USHORT total_len; //16位总长度(字节) USHORT ident; //16
需要的开发包 -驱动:WinPcap_4_0_2 -开发包:WinPcap Developer's Packs v4.0.2 前段时间学习Winpcap在Linux下和Xp下的编程,Linux下用Gcc编的东西是基于控制台的,XP下直接加个MFC界面,都不是很稳定的。交流一下。 功能:截获流过网卡的数据包并重组成原始数据。 --------------------- 路径 名字 后缀 大小 用途 \ release 存放生成的exe文件 \ monitor 项目源代码目录 \monitor\ res 资源目录 \monitor\ user_fun 自定义类和函数 \ monitor sln 989 VS8解决方案 \monitor\ monitor cpp 1662 VS8解决方案 \monitor\ monitor h 447 VS8解决方案 \monitor\ monitor rc 6412 VS8解决方案 \monitor\ monitor vcproj 6412 VS8解决方案 \monitor\ monitorDlg cpp 21851 VS8解决方案 \monitor\ monitorDlg h 2842 VS8解决方案 \monitor\ ReadMe txt 2763 VS8解决方案 \monitor\ Resource h 1277 资源 \monitor\ stdafx cpp 138 VS8解决方案 \monitor\ stdafx h 2758 通用头文件 \monitor\res\ monitor ico 21630 图标资源 \monitor\res\ monitor rc2 363 界面资源 \monitor\user_fun\ big2small cpp 337 大小端转换定义 \monitor\user_fun\ big2small h 197 大小端转换头文件 \monitor\user_fun\ class cpp 13194 自定义存放捕获的包的数据结构和类定义 \monitor\user_fun\ class h 4242 自定义存放捕获的包的数据结构和类头文件 \monitor\user_fun\ commom_def h 2894 使用到的各种协议结构定义 \monitor\user_fun\ device cpp 3691 网卡相关函数定义 \monitor\user_fun\ device h 900 网卡相关函数头文件 \monitor\user_fun\ http_method cpp 17618 处理截获的包的函数定义 \monitor\user_fun\ http_method h 2865 处理截获的包的函数头文件 \release\ monitor exe 81920 主程序 \release\ monitor.exe manifest 650 VS8自动生成配置信息 \release\ monitor pdb 3075072 VS9自动生成程序数据

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值