免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1378 | 回复: 3
打印 上一主题 下一主题

求助raw socket编程问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2004-04-07 11:40 |只看该作者 |倒序浏览
#include <stdio.h>;
#include <winsock2.h>;
#include <ws2tcpip.h>;

#define SOURCE_PORT 12345
#define MAX_RECEIVEBYTE 255

typedef struct ip_hdr          //定义IP首部
{
unsigned char h_verlen;        //4位首部长度,4位IP版本号
unsigned char tos;             //8位服务类型TOS
unsigned short total_len;      //16位总长度(字节)
unsigned short ident;          //16位标识
unsigned short frag_and_flags; //3位标志位
unsigned char ttl;             //8位生存时间 TTL
unsigned char proto;           //8位协议 (TCP, UDP 或其他)
unsigned short checksum;       //16位IP首部校验和
unsigned int sourceIP;         //32位源IP地址
unsigned int destIP;           //32位目的IP地址
}IPHEADER;

typedef struct tsd_hdr         //定义TCP伪首部
{
unsigned long src_addr;        //源地址
unsigned long dst_addr;        //目的地址
char mbz;
char protocol;                 //协议类型
unsigned short tcpl;           //TCP长度
}PSDHEADER;

typedef struct tcp_hdr         //定义TCP首部
{
USHORT th_sport;               //16位源端口
USHORT th_dport;               //16位目的端口
unsigned int th_seq;           //32位序列号
unsigned int th_ack;           //32位确认号
unsigned char th_lenres;       //4位首部长度/6位保留字
unsigned char th_flag;         //6位标志位
USHORT th_win;                 //16位窗口大小
USHORT th_sum;                 //16位校验和
USHORT th_urp;                 //16位紧急数据偏移量
}TCPHEADER;

//CheckSum:计算校验和的子函数
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);
}

int main(int argc, char* argv[])
{
WSADATA WSAData;
SOCKET sock;
SOCKADDR_IN addr_in;
IPHEADER ipHeader;
TCPHEADER tcpHeader;
PSDHEADER psdHeader;

char szSendBuf[60]={0};
BOOL flag;
int rect,nTimeOver;

if (argc!= 3)
{ return FALSE; }

if (WSAStartup(MAKEWORD(2,2), &WSAData)!=0)   //检查 Winsock 版本号
{
printf("WSAStartup Error!\n";
return FALSE;
}

//初始化 Raw Socket
if ((sock=socket(AF_INET,SOCK_RAW,IPPROTO_RAW))==INVALID_SOCKET)
{
printf("Socket Setup Error!\n";
return FALSE;
}

flag=TRUE;  //亲自处理 IP 头

//设置IP头操作选项
if (setsockopt(sock,IPPROTO_IP, IP_HDRINCL,(char *)&flag,sizeof(flag))==SOCKET_ERROR)
{
printf("setsockopt IP_HDRINCL error!\n";
return FALSE;
}

nTimeOver=1000;
if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char*)&nTimeOver,
sizeof(nTimeOver))==SOCKET_ERROR)
{
printf("setsockopt SO_SNDTIMEO error!\n";
return FALSE;
}
addr_in.sin_family=AF_INET;
addr_in.sin_port=htons(atoi(argv[2]));
addr_in.sin_addr.S_un.S_addr=inet_addr(argv[1]);

//把 sock 绑定到本地地址上
if (bind(sock, (PSOCKADDR)&addr_in, sizeof(addr_in)) == SOCKET_ERROR)
{
printf("socket bind eror!";
return FALSE;
}
//
//
//填充IP首部
ipHeader.h_verlen=(4<<4 | sizeof(ipHeader)/sizeof(unsigned long));
// ipHeader.tos=0;
ipHeader.total_len=htons(sizeof(ipHeader)+sizeof(tcpHeader));
ipHeader.ident=1;
ipHeader.frag_and_flags=0;
ipHeader.ttl=128;
ipHeader.proto=IPPROTO_TCP;
ipHeader.checksum=0;
ipHeader.sourceIP=inet_addr("192.168.1.222";
ipHeader.destIP=inet_addr(argv[1]);

//填充TCP首部
tcpHeader.th_dport=htons(atoi(argv[2]));
tcpHeader.th_sport=htons(SOURCE_PORT); //源端口号
tcpHeader.th_seq=htonl(0x1234567;
tcpHeader.th_ack=0;
tcpHeader.th_lenres=(sizeof(tcpHeader)/4<<4|0);
tcpHeader.th_flag=2; //修改这里来实现不同的标志位探测,2是SYN,1是FIN,16是ACK探测 等等
tcpHeader.th_win=htons(512);
tcpHeader.th_urp=0;
tcpHeader.th_sum=0;

psdHeader.src_addr=ipHeader.sourceIP;
psdHeader.dst_addr=ipHeader.destIP;
psdHeader.mbz=0;
psdHeader.protocol=IPPROTO_TCP;
psdHeader.tcpl=htons(sizeof(tcpHeader));

//计算校验和
memcpy(szSendBuf, &psdHeader, sizeof(psdHeader));
memcpy(szSendBuf+sizeof(psdHeader), &tcpHeader, sizeof(tcpHeader));
tcpHeader.th_sum=checksum((USHORT *)szSendBuf,sizeof(psdHeader)+sizeof(tcpHeader));

memcpy(szSendBuf, &ipHeader, sizeof(ipHeader));
memcpy(szSendBuf+sizeof(ipHeader), &tcpHeader, sizeof(tcpHeader));
memset(szSendBuf+sizeof(ipHeader)+sizeof(tcpHeader), 0, 4);
ipHeader.checksum=checksum((USHORT *)szSendBuf, sizeof(ipHeader)+sizeof(tcpHeader));

memcpy(szSendBuf, &ipHeader, sizeof(ipHeader));

rect=sendto(sock, szSendBuf, sizeof(ipHeader)+sizeof(tcpHeader),
0, (struct sockaddr*)&addr_in, sizeof(addr_in));
if (rect==SOCKET_ERROR)
{
printf("send error!:%d\n",WSAGetLastError());
return FALSE;
}
else
printf("send ok!\n";

closesocket(sock);
WSACleanup();

return 0;
}

编译通过,但执行时“bind socket error!”,请问谁知道为什么会绑定错误?

论坛徽章:
0
2 [报告]
发表于 2004-04-07 19:19 |只看该作者

求助raw socket编程问题

是不是端口被占用了?

论坛徽章:
0
3 [报告]
发表于 2004-04-08 09:22 |只看该作者

求助raw socket编程问题

肯定没有被占用

论坛徽章:
0
4 [报告]
发表于 2004-04-08 09:23 |只看该作者

求助raw socket编程问题

查查bind的返回值吧
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP