Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 将IPv4标头校验和插入虚拟IP标头_.net_C_Header_Checksum_Ipv4 - Fatal编程技术网

.net 将IPv4标头校验和插入虚拟IP标头

.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

我试图创建一个只提供有效负载内容的数据包。因此,我必须创建虚拟IPv4和UDP头。我在将IPv4校验和值插入虚拟IP报头时遇到问题。校验和值是使用Wireshark使用的算法计算的。我只是稍微修改了代码,以便可以将校验和值插入到IP头中

我的代码如下(使用Microsoft Visual Studio.NET 2003):

/*********************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
}