flyhobo
驱动小牛
驱动小牛
  • 注册日期2004-03-05
  • 最后登录2005-05-18
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:3154回复:23

关于修改packet数据上传到协议栈被丢掉的问题,急(可以加分)

楼主#
更多 发布于:2004-04-21 21:25
具体如下:
    我在miniport(虚拟的)中的miniportsend例程中把收到的packet数据取到自己的缓冲区,然后修改目的和源MAC,ip地址信息,端口,校验和等信息,再回传到上层协议,用sniffer可以抓到发送和接收到的包,察看数据也没发现有啥情况,但应用程序增收不到包(应用程序没问题)。
  
   再详细点,具体方案如下:我实现的是虚拟网卡,就是没有硬件的,现在再测试收发功能,本来收发要靠irp请求的。
  安装两个网卡(为同样的虚拟网卡),设置通网段ip地址,简称a和b.现在通过a发udp包到一个不存在的c地址(之前做好arp欺骗,这样做是因为直接发到b会通过协议栈就转发了不经过miniport),然后在miniportsend中包packet中数据取出为(MAC头+IP头+UDP头+data)然后修改其相应地址信息,改为 c 到 b 的包,组建packet,上传到NDIS,sniffer能得到包,但应用程序的不到

  请问,我这样实现测试其send和receive例程可行吗?可行的话,我哪里错了?不行的话,我该怎样测试阿!其各位多费心,帮帮忙,分少还可以在加?

最新喜欢:

lierlierlierli...
好好过日子
flyhobo
驱动小牛
驱动小牛
  • 注册日期2004-03-05
  • 最后登录2005-05-18
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-04-22 08:40
怎么没人回答啊!帮帮我吧

其实就是ARP包收发正常,而udp数据包再修改了mac头和ip头后应用层就收不到了,不知道是ip还udp协议给扔掉了,有没有什么方法可以查是什么原因,怎么解决啊?

救救我吧!!!!!!
好好过日子
asmsys
驱动老牛
驱动老牛
  • 注册日期2002-03-29
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望17点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-04-22 09:07
WINDOWS系统对UDP是检查校验的,修改IP地址后,IP头和UDP的校验和都要重新计算,不知道你做了吗,如果没有,肯定被仍掉。
flyhobo
驱动小牛
驱动小牛
  • 注册日期2004-03-05
  • 最后登录2005-05-18
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-04-22 09:15
WINDOWS系统对UDP是检查校验的,修改IP地址后,IP头和UDP的校验和都要重新计算,不知道你做了吗,如果没有,肯定被仍掉。


    我计算更新校验和,ip校验和只计算ip头部字节(一般是20字节吧),udp校验和为udp头加数据,对吧。
    并且我只修改了MAC地址和ip地址,而mac头不需要校验,udp头和data我都没修改,所以之计算更新了ip校验和(我这里就是那20个字节),现把部分代码贴出:

//校验和算法
unsigned short cal_chksum(unsigned short *addr,int len)
{
int nleft=len;
int sum=0;
unsigned short *w=addr;
unsigned short answer=0;

//把报头二进制数据以2字节为单位累加起来
while(nleft>1)
{
sum+=*w++;
nleft-=2;
}

//若报头为奇数个字节,会剩下最后一字节。把最后一个字节视为一个2字节数据的高字节,这个2字节数据的低字节为0,继续累加*
if( nleft==1)
{
*(unsigned char *)(&answer)=*(unsigned char *)w;
sum+=answer;
}
sum=(sum>>16)+(sum&0xffff);
sum+=(sum>>16);
answer=~sum;

return answer;
}


//计算IP包头的校验和
*((unsigned short *)(pChar + 24)) = 0;
*((unsigned short *)(pChar + 24)) = cal_chksum((unsigned short *)(pChar + 14),20);

有什么问题吗?
好好过日子
asmsys
驱动老牛
驱动老牛
  • 注册日期2002-03-29
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望17点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-04-22 09:20
TCP和UDP的校验和都要加伪头,我看你没有的。
flyhobo
驱动小牛
驱动小牛
  • 注册日期2004-03-05
  • 最后登录2005-05-18
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2004-04-22 09:23
TCP和UDP的校验和都要加伪头,我看你没有的。


我没有修改udp头和数据啊!
还要重新校验吗?伪头是什么,怎么校验?
能否详细指教一下,或者网上那里有资料介绍

非常感谢asmsys!
好好过日子
zxcasd
驱动牛犊
驱动牛犊
  • 注册日期2001-06-14
  • 最后登录2007-08-09
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2004-04-22 09:36
[quote]TCP和UDP的校验和都要加伪头,我看你没有的。


我没有修改udp头和数据啊!
还要重新校验吗?伪头是什么,怎么校验?
能否详细指教一下,或者网上那里有资料介绍

非常感谢asmsys! [/quote]

udp,tcp包头进行校验和计算时,输入CheckSum的参数addr应该是udp(tcp)伪头部+udp(tcp)包头内容+数据,而且将其中
的checksum两个字节置0;
以下是伪头部的结构,tcp,udp是一样的
typedef struct pseudo_udp_hdr {
ULONG pth_src;
ULONG pth_dst;
UCHAR pth_zero;
UCHAR pth_protocol;
USHORT pth_length;
}pseudo_udp_hdr, * Ppseudo_udp_hdr;
死了都要爱......
flyhobo
驱动小牛
驱动小牛
  • 注册日期2004-03-05
  • 最后登录2005-05-18
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2004-04-22 09:44

udp,tcp包头进行校验和计算时,输入CheckSum的参数addr应该是udp(tcp)伪头部+udp(tcp)包头内容+数据,而且将其中
的checksum两个字节置0;
以下是伪头部的结构,tcp,udp是一样的
typedef struct pseudo_udp_hdr {
ULONG pth_src;
ULONG pth_dst;
UCHAR pth_zero;
UCHAR pth_protocol;
USHORT pth_length;
}pseudo_udp_hdr, * Ppseudo_udp_hdr;


请问伪头部在mac包的那里啊!
我把包抓下来后只看到
MAC头(14) + ip头(20) + udp头(8) + data(n)
不清楚伪头在那里啊!
长度参数好说啊!加上sizeof(pseudo_udp_hdr)就行了吧
那地址怎样计算啊!
好好过日子
asmsys
驱动老牛
驱动老牛
  • 注册日期2002-03-29
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望17点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2004-04-22 09:49
伪头是虚的,你必须够找一个然后把他加进去,楼上说的那个结构就对,可以用。
asmsys
驱动老牛
驱动老牛
  • 注册日期2002-03-29
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望17点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2004-04-22 09:52
void UdpCheckSum(PIP_HEADER buffer)
{
__ASM
{
pushad
xor eax,eax
xor edx,edx
mov esi,buffer
add esi,12 ;srcip
mov ecx,4
lable1:
lodsw
add edx,eax
loop lable1
add edx,1100h ;udp type

mov [esi+6],cx ;clear old checksum to 0

mov cx,[esi+4]
add edx,ecx ;udp length

xchg cl,ch

mov edi,esi
mov ebx,ecx
shr ecx,1
lable2:
lodsw
add edx,eax
loop lable2
and ebx,1
jz lable3
xor eax,eax
lodsb
add edx,eax
lable3:
mov eax,edx
shr eax,16
and edx,0ffffh
add edx,eax
mov eax,edx
shr eax,16
add edx,eax

not edx
mov [edi+6],dx
popad
}

}
zxcasd
驱动牛犊
驱动牛犊
  • 注册日期2001-06-14
  • 最后登录2007-08-09
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2004-04-22 09:56
[quote]
udp,tcp包头进行校验和计算时,输入CheckSum的参数addr应该是udp(tcp)伪头部+udp(tcp)包头内容+数据,而且将其中
的checksum两个字节置0;
以下是伪头部的结构,tcp,udp是一样的
typedef struct pseudo_udp_hdr {
ULONG pth_src;
ULONG pth_dst;
UCHAR pth_zero;
UCHAR pth_protocol;
USHORT pth_length;
}pseudo_udp_hdr, * Ppseudo_udp_hdr;


请问伪头部在mac包的那里啊!
我把包抓下来后只看到
MAC头(14) + ip头(20) + udp头(8) + data(n)
不清楚伪头在那里啊!
长度参数好说啊!加上sizeof(pseudo_udp_hdr)就行了吧
那地址怎样计算啊! [/quote]

伪头部是要自己构造的!不在包里!构造好udp伪头部再加上udp包头内容再加上数据就可以用来计算udp的checksum了
死了都要爱......
flyhobo
驱动小牛
驱动小牛
  • 注册日期2004-03-05
  • 最后登录2005-05-18
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2004-04-22 09:57
void UdpCheckSum(PIP_HEADER buffer)
{
__ASM
{
     …………
}

}

汇编啊!我的妈呀,忘完了,我直接调用就行吗?
PIP_HEADER buffer 是否mac包中指向ip头的指针对吗?

谢了,两位

我试验一下先 :)
好好过日子
zxcasd
驱动牛犊
驱动牛犊
  • 注册日期2001-06-14
  • 最后登录2007-08-09
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2004-04-22 09:58
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);

}
死了都要爱......
flyhobo
驱动小牛
驱动小牛
  • 注册日期2004-03-05
  • 最后登录2005-05-18
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2004-04-22 10:10
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);

}

我的算法也对吧?下面是我对伪头的理解(注释),你看对吗?
typedef struct pseudo_udp_hdr {
ULONG pth_src;//源ip地址
ULONG pth_dst;//目的ip地址
UCHAR pth_zero;//赋值为 0
UCHAR pth_protocol;//协议类型,这里为17
USHORT pth_length;//这儿不清楚了,***还得zxcasd
老大指教***!
}pseudo_udp_hdr, * Ppseudo_udp_hdr;

那加上伪头是不又要开缓冲区把伪头和udp包复制到一起,在计算,那然后那?是把udp部分复制回去,还是只赋值校验和就好了?
好好过日子
asmsys
驱动老牛
驱动老牛
  • 注册日期2002-03-29
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望17点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2004-04-22 10:19
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);

}

你这没有处理伪头,我那代码是久经考验的,速度飞快,使用简单,只要把IP包的起使地址传进去就好了,你就只等着发送吧。
asmsys
驱动老牛
驱动老牛
  • 注册日期2002-03-29
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望17点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2004-04-22 10:22
算了,发一个C版的吧,今天心情不好,发泄一下。
void UdpCheckSum(PIP_HEADER buffer)
{
//有可选数据时要做改动
//buffer是IP头的指针
unsigned short size;
unsigned char * pSize;
unsigned char tempchar;
unsigned long cksum = 0;
unsigned short * TempAddr;
unsigned short * TempAddr1;
int i = 0;
//加伪首
TempAddr = (unsigned short *)(&(buffer->SrcIP));
for(i=0;i<4;i++)
{
cksum += *TempAddr;
TempAddr++;
}
cksum += 0x1100; //类型
size = *(TempAddr + 2); //udp包长度
cksum += size;
//转换网络字节
pSize = (unsigned char *)(&size);
tempchar = pSize[0];
pSize[0] = pSize[1];
pSize[1] = tempchar;
//校验和位置清0
*(TempAddr + 3) = 0;

//size = udp size
//buffer = udp packet addr
TempAddr1 = TempAddr;
    while (size > 1)
    {
        cksum += *TempAddr++;
        size -= sizeof(unsigned short);
    }
    if (size)
    {
        cksum += *(unsigned char*)TempAddr;
    }
    cksum = (cksum >> 16) + (cksum & 0xffff);
    cksum += (cksum >>16);
*(TempAddr1 + 3) = (unsigned short)(~cksum);
}
flyhobo
驱动小牛
驱动小牛
  • 注册日期2004-03-05
  • 最后登录2005-05-18
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2004-04-22 10:22
[quote]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);

}

你这没有处理伪头,我那代码是久经考验的,速度飞快,使用简单,只要把IP包的起使地址传进去就好了,你就只等着发送吧。 [/quote]

asmsys老大,你的汇编代码我编译不通过啊!
我是笨了点哈,这都搞不定了,还望你多加指教
2000ddk识别不了__ASM,pushad.xor等指令,要怎样设置啊!
好好过日子
flyhobo
驱动小牛
驱动小牛
  • 注册日期2004-03-05
  • 最后登录2005-05-18
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
17楼#
发布于:2004-04-22 10:25
算了,发一个C版的吧,今天心情不好,发泄一下。
 


谢了!!!! :P
好好过日子
zxcasd
驱动牛犊
驱动牛犊
  • 注册日期2001-06-14
  • 最后登录2007-08-09
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
18楼#
发布于:2004-04-22 10:26
[quote]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);

}

我的算法也对吧?下面是我对伪头的理解(注释),你看对吗?
typedef struct pseudo_udp_hdr {
ULONG pth_src;//源ip地址
ULONG pth_dst;//目的ip地址
UCHAR pth_zero;//赋值为 0
UCHAR pth_protocol;//协议类型,这里为17
USHORT pth_length;//这儿不清楚了,***还得zxcasd
老大指教***!
}pseudo_udp_hdr, * Ppseudo_udp_hdr;

那加上伪头是不又要开缓冲区把伪头和udp包复制到一起,在计算,那然后那?是把udp部分复制回去,还是只赋值校验和就好了? [/quote]

pth_length是包的总长度去掉以太网头长度和ip头长度,做法就差不多是那样了。感觉asmsys的代码很不错啊一次搞定
死了都要爱......
asmsys
驱动老牛
驱动老牛
  • 注册日期2002-03-29
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望17点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
19楼#
发布于:2004-04-22 10:28
#define __ASM __asm
要不你就用C版的,一样,但我觉得太臃肿。
上一页
游客

返回顶部