问一个原始套接字发包自动加上了ip头的问题

crystal_lz 2015-03-02 10:46:40
才接触原始套接字不久 我想要模拟tcp协议的连接建立
现在还在发送syn包 但是遇到一些问题

socket定义如下(伪代码):
sock = socket(AF_INET,SOCK_RAW,IPPROTO_IP);
setsockopt(sock, IPPROTO_IP, IP_HDRINCL, true);

//第一种发送方式
connect(sock,destAddr);
send(sockClient,sendBuf,dataSize);
//第二种-------------------------------------------------
sendto(sock, sendBuf, dataSize, destAddr);

抓包呈现效果如下:

灰色部分是自己加上的的ip头 而我红色框里面自己的ip头却被当成了数据 这是这么回事?
而且出去的数据抓包工具也没有解析出是syn数据包显示的就只是ipv4
不是setsockeopt里面设置了 自己定义头数据吗?为什么 他自己还加上了头而且我也试过把socket(AF_INET,SOCK_RAW,IPPROTO_IP);后面换成TCP但是 这样的话数据都发送失败 获取错误码是10075翻译过来好像是 发送数据前必须先调用connect建立好连接
我也对照了数据 没有发现什么问题 有问题也应该是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);
}

其他数据我都对比过了 没有错
然后我干脆直接 用正常方式连接一次 然后再把那个正常发送出去了的syn包数据 抓去下来自己用原始套接字再发送一次 还是不行:

//后来干脆抓去一个能正常发送的数据包自己在用原始套接字发送一次 效果一样
sendBuf =[]{
0x45,0x00,0x00,0x34,0x20,0x49,0x40,0x00,0x80,0x06,0x50,0x05,0xac,0x10,0x08,0x98,
0xb4,0x61,0x21,0x6c,0x56,0x11,0x00,0x15,0x98,0x47,0x67,0x6a,0x00,0x00,0x00,0x00,
0x80,0x02,0x20,0x00,0x6e,0xc8,0x00,0x00,0x02,0x04,0x05,0xb4,0x01,0x03,0x03,0x02,
0x01,0x01,0x04,0x02
};


所以就来求助了 开始我觉得 不就是socket发一个包出去嘛 感觉很简单的事情 结果搞了半天都没有自己想要的结果

求指教啊。。
...全文
340 8 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
crystal_lz 2015-03-03
  • 打赏
  • 举报
回复
引用 1 楼 wangzuxi 的回复:
试试socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP|ETH_P_ALL))
我不知道那几个常量值 在哪里申明的 百度出来的值 创建socket直接出错、、 然后我发现问题了 自所以自己带上了ip都是应为 setsocktopt的时候 没有成功 现在设置成功了 发送显示发送成功 但是抓不到数据包
zuxi 2015-03-03
  • 打赏
  • 举报
回复
试试socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP|ETH_P_ALL))
crystal_lz 2015-03-03
  • 打赏
  • 举报
回复
引用 4 楼 wangzuxi 的回复:
[quote=引用 3 楼 crystal_lz 的回复:] 现在的问题 socket发送成功 但是抓包没有数据啊 怎么回事 发送代码如下:

//SOCKET sock = socket(AF_INET,SOCK_RAW,IPPROTO_IP);
SOCKET sock=WSASocket(AF_INET,SOCK_RAW,IPPROTO_RAW/*IPPROTO_IP*/,NULL,0,WSA_FLAG_OVERLAPPED);
printf("sock:%d\r\n",sock);
BOOL set = TRUE;
printf("set:%d\r\n",setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&set, sizeof(set)));
connect(sock,(struct sockaddr*)&DestAddr,sizeof(DestAddr));
//printf("send:%d\r\n", sendto(sock, ch, 0x34, 0, (struct sockaddr*) &DestAddr, sizeof(DestAddr)));
printf("send:%d\r\n", send(sock,SendBuf,datasize,NULL));
printf("error:%d",WSAGetLastError());
一是你看看你发的数据包对不对,不对的话,wireshark也过滤不到;二是你可以在对端抓包看看包有没有发到对方。[/quote] 我对端随便找的百度的一个ip 同样的程序 在win7上包发送成功 但是抓不到包 xp sp3上发送失败 错误码 10004 2003上发包成功 抓取到syn包
crystal_lz 2015-03-03
  • 打赏
  • 举报
回复
引用 5 楼 zhao4zhong1 的回复:
Win7好象不支持SOCK_RAW了。
我换到2003上能正常运行 能抓到出去的syn包了 但是如果win7上要怎么做呢? 貌似xp sp2开始对原始套接字 有限制
crystal_lz 2015-03-03
  • 打赏
  • 举报
回复
引用 5 楼 zhao4zhong1 的回复:
Win7好象不支持SOCK_RAW了。
我在xp上面试了一下 出现10004 错误号 A blocking operation was interrupted by a call to WSACancelBlockingCall 在 win7上能发送成功 但是抓不到包
赵4老师 2015-03-03
  • 打赏
  • 举报
回复
Win7好象不支持SOCK_RAW了。
zuxi 2015-03-03
  • 打赏
  • 举报
回复
引用 3 楼 crystal_lz 的回复:
现在的问题 socket发送成功 但是抓包没有数据啊 怎么回事 发送代码如下:

//SOCKET sock = socket(AF_INET,SOCK_RAW,IPPROTO_IP);
SOCKET sock=WSASocket(AF_INET,SOCK_RAW,IPPROTO_RAW/*IPPROTO_IP*/,NULL,0,WSA_FLAG_OVERLAPPED);
printf("sock:%d\r\n",sock);
BOOL set = TRUE;
printf("set:%d\r\n",setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&set, sizeof(set)));
connect(sock,(struct sockaddr*)&DestAddr,sizeof(DestAddr));
//printf("send:%d\r\n", sendto(sock, ch, 0x34, 0, (struct sockaddr*) &DestAddr, sizeof(DestAddr)));
printf("send:%d\r\n", send(sock,SendBuf,datasize,NULL));
printf("error:%d",WSAGetLastError());
一是你看看你发的数据包对不对,不对的话,wireshark也过滤不到;二是你可以在对端抓包看看包有没有发到对方。
crystal_lz 2015-03-03
  • 打赏
  • 举报
回复
现在的问题 socket发送成功 但是抓包没有数据啊 怎么回事

发送代码如下:

//SOCKET sock = socket(AF_INET,SOCK_RAW,IPPROTO_IP);
SOCKET sock=WSASocket(AF_INET,SOCK_RAW,IPPROTO_RAW/*IPPROTO_IP*/,NULL,0,WSA_FLAG_OVERLAPPED);
printf("sock:%d\r\n",sock);
BOOL set = TRUE;
printf("set:%d\r\n",setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&set, sizeof(set)));
connect(sock,(struct sockaddr*)&DestAddr,sizeof(DestAddr));
//printf("send:%d\r\n", sendto(sock, ch, 0x34, 0, (struct sockaddr*) &DestAddr, sizeof(DestAddr)));
printf("send:%d\r\n", send(sock,SendBuf,datasize,NULL));
printf("error:%d",WSAGetLastError());
本文章将介绍如何使用RawSocket(原始套接字)开发网络嗅探器: 首先我们得了解什么是套接字,这个我就不多说,自己百度,百度百科比我说的好。 那么什么又是原始套接字呢,常用的套接字分为 SOCK_STREAM(流套接字) 用于TCPXY通讯。 SOCK_DGRAM(数据报套接字) 同于UDPXY通讯。 那么原始呢,他则是和名字一样原始套接字;举例:要想用流套接字进行一次TCP的发包,那么直接连接上对方服务器然后用Send就可以发送指定的内容,但其实发送的数据并不止你的那些内容,有一些东西是流套接字会给你自动补上的。TCP是属于IPXY的一个子XY,那么要发送一个TCP数据包就得加上(以太网XY报这个先不提),IPXY的报,和TCPXY报,这些东西流套接字都会帮你处理,而原始套接字则不会(当然也可以设置让原始套接字构造IP)。原始套接字他有更多的用途,但相对来说也比流套接字或数据报套接字麻烦。 原始套接字还可以设置成允许接收本地所有的套接字数据。那么我们就利用这个功能来做嗅探器! 首先:1.使用  WSAStartup (合并短整数 (2, 2), WSADATA)  来初始化Winsocket服务 其参数有2个  第一个 (短整数型/双字节型):wVersionRequired  这个参数表明使用的winsock版本号,高位指定修订版本号,低位指定主版本号。第二个参数 WSADATA类型 用于接收Winsocket细节东西,咱不用管它。 //下面就不说那么详细了,源码里面全是注释,自己看。 2.然后使用socket (#AF_INET, #SOCK_RAW, #IPPROTO_IP)  来创建一个套接字   第一个参数应该是表明Internet地址格式反正只能固定这个,仅仅支持这个  参数2:表明要创建的是一个原始套接字,参数3:指定IPXY  IPXY包括其子XY TCP UDP 等。成功返回套接字句柄 3.  bind (s, addr, sizeof (addr))  将套接字绑定至指定网卡,参数1=套接字句柄    参数2为一个addr结构的值,该值表明要绑定的网卡IP及端口号 4.  ioctlsocket (Socket, 2550136833, 1) 将套接字的模式改变为允许接收所有数据 顺利完成上面的操作后咱就可以用Recv来接收数据包了,只要不断的调用Recv就OK。

3,882

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 其它技术问题
社区管理员
  • 其它技术问题社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧