.net 将IPv4标头校验和插入虚拟IP标头
我试图创建一个只提供有效负载内容的数据包。因此,我必须创建虚拟IPv4和UDP头。我在将IPv4校验和值插入虚拟IP报头时遇到问题。校验和值是使用Wireshark使用的算法计算的。我只是稍微修改了代码,以便可以将校验和值插入到IP头中 我的代码如下(使用Microsoft Visual Studio.NET 2003):.net 将IPv4标头校验和插入虚拟IP标头,.net,c,header,checksum,ipv4,.net,C,Header,Checksum,Ipv4,我试图创建一个只提供有效负载内容的数据包。因此,我必须创建虚拟IPv4和UDP头。我在将IPv4校验和值插入虚拟IP报头时遇到问题。校验和值是使用Wireshark使用的算法计算的。我只是稍微修改了代码,以便可以将校验和值插入到IP头中 我的代码如下(使用Microsoft Visual Studio.NET 2003): /*********************main.c***********************/ #包括 #包括 #包括 #包括 #包括 #包括 #包括“in_cks
/*********************main.c***********************/
#包括
#包括
#包括
#包括
#包括
#包括
#包括“in_cksum.h”
#定义大小\u IP\u HDR 20
无符号字符ip_头[]={0x45、0x00、0x05、0x30、0x00、0x00、0x40、0x00、0x20、0x11、0x00、0x00、0x21、0x4f、0x02、0x7b、0xcc、0x5c、0x46、0x00};
int main(int argc,字符**argv)
{
ip校验和(ip头、大小ip HDR);
ip_头[12]=0x2d;
ip校验和(ip头、大小ip HDR);
返回0;
}
/**********************in_cksum.h***********************/
#如果不确定
#定义在\u CKSUM\u H中
typedef unsigned uu int8 uint8;
typedef unsigned\uu int16 uint16\u t;
typedef无符号输入32 uint32;
类型定义结构
{
const uint8_t*ptr;
内伦;
}向量;
整数单位和(常数向量,整数向量);
uint16计算校验和(常数向量*vec,整数向量);
无效ip校验和(常数8*ptr,整数长度);
#endif/*IN_CKSUM_H*/
/**********************in_cksum.c***********************/
#包括“in_cksum.h”
#定义ADDCARRY(x)(x>65535?x-=65535:x)
#定义REDUCE{l_util.l=sum;sum=l_util.s[0]+l_util.s[1];ADDCARRY(sum);}
整数单位和(常数向量,整数向量)
{
寄存器常量16_t*w;
寄存器int和=0;
寄存器int mlen=0;
int字节_交换=0;
联合{
uint8_t c[2];
uint16;
}s_util;
联合{
uint16_t s[2];
uint32_t l;
}l_util;
对于(;veclen!=0;vec++,veclen--){
如果(向量->长度==0)
继续;
w=(const uint16_t*)向量->ptr;
如果(mlen==-1){
/*
*该块的第一个字节是延续
*在这个词块和
*最后一块。
*
*扫描上一页时已保存s_util.c[0]
*大块。
*/
s_util.c[1]=*(const uint8_t*)w;
sum+=s_util.s;
w=(常数uint16_t*)((常数uint8_t*)w+1);
mlen=vec->len-1;
}否则
mlen=vec->len;
/*
*均匀边界的力。
*/
if((1&(无符号长)w)&&(mlen>0)){
减少
总和=0){
sum+=w[0];sum+=w[1];sum+=w[2];sum+=w[3];
w+=4;
}
mlen+=8;
if(mlen==0&&byte\u swapped==0)
继续;
减少
而((mlen-=2)>=0){
总和+=*w++;
}
如果(字节_交换){
减少
总ptr;
如果(mlen==-1){
/*
*该块的第一个字节是延续
*在这个词块和
*最后一块。
*
*扫描上一页时已保存s_util.c[0]
*大块。
*/
s_util.c[1]=*(const uint8_t*)w;
sum+=s_util.s;
w=(常数uint16_t*)((常数uint8_t*)w+1);
mlen=vec->len-1;
}否则
mlen=vec->len;
/*
*均匀边界的力。
*/
if((1&(无符号长)w)&&(mlen>0)){
减少
总和=0){
sum+=w[0];sum+=w[1];sum+=w[2];sum+=w[3];
w+=4;
}
mlen+=8;
if(mlen==0&&byte\u swapped==0)
继续;
减少
而((mlen-=2)>=0){
总和+=*w++;
}
如果(字节_交换){
减少
summemcpy行修改报头(通过在其中设置校验和),修改后的报头是第二个校验和的输入
在计算校验和之前,应将校验和字段设置为0,以获得正确的结果
/********************** main.c ***********************/
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <string.h>
#include <tchar.h>
#include <strsafe.h>
#include "in_cksum.h"
#define SIZE_IP_HDR 20
unsigned char ip_header[] = {0x45, 0x00, 0x05, 0x30, 0x00, 0x00, 0x40, 0x00, 0x20, 0x11, 0x00, 0x00, 0x21, 0x4f, 0x02, 0x7b, 0xcc, 0x5c, 0x46, 0x00};
int main(int argc, char **argv)
{
ip_cal_checksum(ip_header, SIZE_IP_HDR);
ip_header[12] = 0x2d;
ip_cal_checksum(ip_header, SIZE_IP_HDR);
return 0;
}
/********************** in_cksum.h ***********************/
#ifndef IN_CKSUM_H
#define IN_CKSUM_H
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
typedef struct
{
const uint8_t *ptr;
int len;
} vec_t;
int in_cksum(const vec_t *vec, int veclen);
uint16_t calculate_cksum(const vec_t *vec, int veclen);
void ip_cal_checksum(const uint8_t *ptr, int len);
#endif /* IN_CKSUM_H */
/********************** in_cksum.c ***********************/
#include "in_cksum.h"
#define ADDCARRY(x) (x > 65535 ? x -= 65535 : x)
#define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum);}
int in_cksum(const vec_t *vec, int veclen)
{
register const uint16_t *w;
register int sum = 0;
register int mlen = 0;
int byte_swapped = 0;
union {
uint8_t c[2];
uint16_t s;
} s_util;
union {
uint16_t s[2];
uint32_t l;
} l_util;
for (; veclen != 0; vec++, veclen--) {
if (vec->len == 0)
continue;
w = (const uint16_t *)vec->ptr;
if (mlen == -1) {
/*
* The first byte of this chunk is the continuation
* of a word spanning between this chunk and the
* last chunk.
*
* s_util.c[0] is already saved when scanning previous
* chunk.
*/
s_util.c[1] = *(const uint8_t *)w;
sum += s_util.s;
w = (const uint16_t *)((const uint8_t *)w + 1);
mlen = vec->len - 1;
} else
mlen = vec->len;
/*
* Force to even boundary.
*/
if ((1 & (unsigned long) w) && (mlen > 0)) {
REDUCE;
sum <<= 8;
s_util.c[0] = *(const uint8_t *)w;
w = (const uint16_t *)((const uint8_t *)w + 1);
mlen--;
byte_swapped = 1;
}
/*
* Unroll the loop to make overhead from
* branches &c small.
*/
while ((mlen -= 32) >= 0) {
sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7];
sum += w[8]; sum += w[9]; sum += w[10]; sum += w[11];
sum += w[12]; sum += w[13]; sum += w[14]; sum += w[15];
w += 16;
}
mlen += 32;
while ((mlen -= 8) >= 0) {
sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
w += 4;
}
mlen += 8;
if (mlen == 0 && byte_swapped == 0)
continue;
REDUCE;
while ((mlen -= 2) >= 0) {
sum += *w++;
}
if (byte_swapped) {
REDUCE;
sum <<= 8;
byte_swapped = 0;
if (mlen == -1) {
s_util.c[1] = *(const uint8_t *)w;
sum += s_util.s;
mlen = 0;
} else
mlen = -1;
} else if (mlen == -1)
s_util.c[0] = *(const uint8_t *)w;
}
if (mlen == -1) {
/* The last mbuf has odd # of bytes. Follow the
standard (the odd byte may be shifted left by 8 bits
or not as determined by endian-ness of the machine) */
s_util.c[1] = 0;
sum += s_util.s;
}
REDUCE;
return (~sum & 0xffff);
}
uint16_t calculate_cksum(const vec_t *vec, int veclen)
{
register const uint16_t *w;
register int sum = 0;
register int mlen = 0;
int byte_swapped = 0;
union {
uint8_t c[2];
uint16_t s;
} s_util;
union {
uint16_t s[2];
uint32_t l;
} l_util;
for (; veclen != 0; vec++, veclen--) {
if (vec->len == 0)
continue;
w = (const uint16_t *)vec->ptr;
if (mlen == -1) {
/*
* The first byte of this chunk is the continuation
* of a word spanning between this chunk and the
* last chunk.
*
* s_util.c[0] is already saved when scanning previous
* chunk.
*/
s_util.c[1] = *(const uint8_t *)w;
sum += s_util.s;
w = (const uint16_t *)((const uint8_t *)w + 1);
mlen = vec->len - 1;
} else
mlen = vec->len;
/*
* Force to even boundary.
*/
if ((1 & (unsigned long) w) && (mlen > 0)) {
REDUCE;
sum <<= 8;
s_util.c[0] = *(const uint8_t *)w;
w = (const uint16_t *)((const uint8_t *)w + 1);
mlen--;
byte_swapped = 1;
}
/*
* Unroll the loop to make overhead from
* branches &c small.
*/
while ((mlen -= 32) >= 0) {
sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7];
sum += w[8]; sum += w[9]; sum += w[10]; sum += w[11];
sum += w[12]; sum += w[13]; sum += w[14]; sum += w[15];
w += 16;
}
mlen += 32;
while ((mlen -= 8) >= 0) {
sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
w += 4;
}
mlen += 8;
if (mlen == 0 && byte_swapped == 0)
continue;
REDUCE;
while ((mlen -= 2) >= 0) {
sum += *w++;
}
if (byte_swapped) {
REDUCE;
sum <<= 8;
byte_swapped = 0;
if (mlen == -1) {
s_util.c[1] = *(const uint8_t *)w;
sum += s_util.s;
mlen = 0;
} else
mlen = -1;
} else if (mlen == -1)
s_util.c[0] = *(const uint8_t *)w;
}
if (mlen == -1) {
/* The last mbuf has odd # of bytes. Follow the
standard (the odd byte may be shifted left by 8 bits
or not as determined by endian-ness of the machine) */
s_util.c[1] = 0;
sum += s_util.s;
}
REDUCE;
return (~sum & 0xffff);
}
void ip_cal_checksum(const uint8_t *ptr, int len)
{
vec_t cksum_vec[1];
uint16_t ip_checksum = 0;
cksum_vec[0].ptr = ptr;
cksum_vec[0].len = len;
ip_checksum = calculate_cksum(&cksum_vec[0], 1);
printf("%x\n", ip_checksum);
memcpy((void *)&ptr[10], &ip_checksum, 2); // copy checksum value to IP header
}