1。对于同一个对话框内的两个控件来说,永远不需要全局变量,一个成员变量搞定。
2。多县城太烦,其实这只是一个逻辑游戏。//发消息通知循环开始
void CMyDlg::OnButton1()
{
m_flag = 1;
PostMessage(WM_JASON,0,0);
return;
}//设置标志,让循环结束,不需要发消息
void CMyDlg::OnButton2()
{
m_flag = 0;
return;
}
void CMyDlg::Jason()
{
while(m_flag)
{
//todo
}
return;
}
2。多县城太烦,其实这只是一个逻辑游戏。//发消息通知循环开始
void CMyDlg::OnButton1()
{
m_flag = 1;
PostMessage(WM_JASON,0,0);
return;
}//设置标志,让循环结束,不需要发消息
void CMyDlg::OnButton2()
{
m_flag = 0;
return;
}
void CMyDlg::Jason()
{
while(m_flag)
{
//todo
}
return;
}
设定一个变量,不能思维定势根据这个变量是0或者1来判断,而是这两个按纽都让这个变量加1,然后根据这个变量的奇偶来判断。之所以说这个方法烂是因为如果其中一个按纽连续按了两下,这两个按纽的作用就反过来了。
主 题:巨分相送!!回答出来者另开帖子送500分!
作 者:glooby
所属论坛:Visual C++
问题点数:59
回复次数:18
发表时间:2001-11-18 13:12:31
问题1, 如何写程序给某块网卡IP设置地址,当然不能重起
问题2, 如何写一个嗅探器,介绍关键步骤就行了
问题3, 如何发送一个数据链路层报文, 类型由我设定,比如1234。:)
当然, 要用windows编程!
回复贴子:
回复人: glooby(怪物点心) (2001-11-18 13:25:53) 得0分
连个UP的人都没有??
回复人: glooby(怪物点心) (2001-11-18 13:29:57) 得0分
问题1改为, 给一台机子分一个IP,该机子拿到IP后不需要重起就可以使用就行了!
回复人: glooby(怪物点心) (2001-11-18 13:31:13) 得0分
第一个问题用IP伪装行吗?? 该如何做呢??
回复人: pitchstar(一站) (2001-11-18 13:40:05) 得0分
问题 1:用这个 api GetAdaptersInfo(),他返回好象是一个链表,每个节点代表一个卡。
问题 2:需要 ndis 驱动,不懂
问题 3:ip 伪装是比较复杂的技术,而且有运气的成分,给一篇文章:http://www.csdn.net/develop/read_article.asp?id=9343
回复人: glooby(怪物点心) (2001-11-18 20:04:59) 得0分
我是要设置IP, 不是得到适配器的信息。
回复人: pitchstar(一站) (2001-11-19 9:54:35) 得0分
设置 ip 不知道,但你用原始套接字可以以任何地址给人发包,但却收不到,如果在局域网可以通过监听以太网帧收到回复的包,但基本没多大意义,自己维护协议是很复杂的UDP 还好说点
回复人: whz_time(时间) (2001-11-19 10:09:44) 得0分
对于问题 2:我这有一段代码,但还有问题,我们可以一起研究一下:// tcp.cpp : Defines the entry point for the console application.
//
#include "stdlib.h"
#include <stdio.h>
#include "winsock2.h"
#include "IPHlpApi.h"
#include "mstcpip.h"
#include "errno.h"
#include "conio.h"//#include "rcv_.h"void init(void);
void GetProtocol(int num, char *str);
void recv_icmp(char *host, int sockfd);
void handle_icmp(char *buf);
void getippak(int SockRaw);/////////////////////////////////////////////////////////typedef struct _PROTN2T
{
int proto ;
char *pprototext ;
}PROTN2T ; /////////////////////////////////////////////////////////
typedef struct _IPHEADER {
unsigned char header_len:4;
unsigned char version:4;
unsigned char tos; // type of service
unsigned short total_len; // length of the packet
unsigned short ident; // unique identifier
unsigned short flags;
unsigned char ttl;
unsigned char proto; // protocol ( IP , TCP, UDP etc)
unsigned short checksum;
unsigned int sourceIP;
unsigned int destIP;}IPHEADER;//////////////////////////////////////////////////////////////int main(int argc, char* argv[])//
{
char *host_="localhost";
int sockfd;
init();
sockfd=socket(AF_INET,SOCK_RAW,IPPROTO_IP);//IPPROTO_IP);
if(sockfd<0)
{
printf("socket error->%s\n",strerror(errno));
exit(1);
}
getippak(sockfd);recv_icmp(host_,sockfd);return(0);
}///////////////////////////////////////////////////////
void init(void)
{
WORD wVersion;
WSADATA wsaData;
int err;
wVersion=MAKEWORD(2,0);
err=WSAStartup(wVersion,&wsaData);
if(err!=0)
exit(1);}
///////////////////////////////////////////////////////
void GetProtocol(int num_, char *str_)
{switch(num_)
{
case 0: str_="IP";
break;
case 1: str_="ICMP";
break;
case 2: str_="IGMP";
break;
case 3: str_="GGP";
break;
case 6: str_="TCP";
break;
case 12: str_="PUP";
break;
case 17: str_="UDP";
break;
case 22: str_="IDP";
break;
case 77: str_="ND";
break;
case 255: str_="RAW";
break;
default: str_="MAX";
break;
}
}///////////////////////////////////////////////////////
void recv_icmp(char *host, int sockfd)
{
char recvbuf[1024],*bufwork;
char *pSource,*pDest;
IPHEADER *pIpHeader;
in_addr ina;
char szSource [16] , szDest[16];// szErr [ 50 ];
char *pLastBuf = NULL ;char *str,*temp;
// int len;
int n;
//long count=0;
for(;;)
{
memset(szSource,0,sizeof(szSource));
memset(szDest,0,sizeof(szDest));
memset(recvbuf,0,sizeof(recvbuf));
n=recvfrom(sockfd,recvbuf,sizeof(recvbuf),0,NULL,NULL);
// GetLastError();
// MessageBox(NULL,(char *)GetLastError(),"",0);
if(n<0)
{
if(errno==EINTR)
continue;
else
{
printf("Recvfrom Error n=%d\n",n);
printf("%s\n",recvbuf);
Sleep(1000);
continue;
}//else
continue;} //if
// iRet = recv(pDlg->m_s, buf , sizeof( buf ) , 0 ) ;
// putch('x');
// getch();
if(*recvbuf)
{
bufwork = recvbuf ;
pIpHeader = (IPHEADER *)bufwork ;
WORD iLen = ntohs(pIpHeader->total_len) ;
ina.S_un.S_addr = pIpHeader->sourceIP ;
pSource =inet_ntoa( ina ) ;
strcpy( szSource , pSource ) ;
// str.Format("Source IP: %s, ",szSource);
sprintf(str,"Source IP: %s, ",szSource);ina.S_un.S_addr = pIpHeader->destIP ;
pDest = inet_ntoa( ina ) ;
strcpy( szDest , pDest ) ;
// temp.Format("Dest IP: %s, Protocol: ",szDest);
sprintf(temp,"Dest IP: %s, Protocol: ",szDest);
// str+=temp;
strcat(str,temp);
int test=pIpHeader->total_len;int num=pIpHeader->proto;
GetProtocol(num, temp);
// str+=temp;
strcat(str,temp);// temp.Format (",%d,%d",buf[20]*256+buf[21],buf[22]*256+buf[23]);
sprintf(temp,",%d,%d",recvbuf[20]*256+recvbuf[21],recvbuf[22]*256+recvbuf[23]);// str+=temp;
strcat(str,temp);
printf("getippak is:%s",str);
// pDlg->m_ctlPort.InsertItem(0,str);
// handle_icmp(recvbuf);
}//if
}//for}
/////////////////////////////////////////////////////////void recv_icmp(char *host, int sockfd)
//{
//char recvbuf[512];
// int len;
//int n;
//long count=0;
//for(;;)
//{
//memset(recvbuf,0,sizeof(recvbuf));
//n=recvfrom(sockfd,recvbuf,sizeof(recvbuf),0,NULL,NULL);
////GetLastError();
///MessageBox(NULL,(char *)GetLastError(),"",0);
//if(n<0)
// {
// if(errno==EINTR) continue;
// else
// {
// printf("Recvfrom Error n=%d\n",n);
// printf("%s\n",recvbuf);
// Sleep(1000);
// continue;
// }
// }
//handle_icmp(recvbuf);
//}
//} /////////////////////////////////////////////////////////void handle_icmp(char *buf)
//{
//// struct ip *ip;
//// ip=(struct ip*)buf;
//// printf("IP:%ld\n",ip->ip_src.s_addr);
//printf("Get--->%s",buf);
//}///////////////////////////////////////////////////////////////void getippak(int SockRaw)
{
#define SIO_RCVALL _WSAIOW(IOC_VENDOR,1) //初始化SOCKET
#define MAX_HOSTNAME_LAN 256// WSADATA wsaData;
int iErrorCode;//iErrorCode = WSAStartup(MAKEWORD(2,1),&wsaData);
//CheckSockError(iErrorCode, "WSAStartup");
//SockRaw = socket(AF_INET , SOCK_RAW , IPPROTO_IP);
//CheckSockError(SockRaw, "socket");
//获取本机IP地址
char FAR name[MAX_HOSTNAME_LAN];
iErrorCode = gethostname(name, MAX_HOSTNAME_LAN);
//CheckSockError(iErrorCode, "gethostname");
struct hostent FAR * pHostent;
pHostent = gethostbyname(name);
SOCKADDR_IN sa;
sa.sin_family = AF_INET;
sa.sin_port = htons(80);//6000);
memcpy(&sa.sin_addr.S_un.S_addr, pHostent->h_addr_list[0], pHostent->h_length);
iErrorCode = bind(SockRaw, (PSOCKADDR)&sa, sizeof(sa));//设置SOCK_RAW为SIO_RCVALL,以便接收所有的IP包DWORD dwBufferLen[10] ;
DWORD dwBufferInLen = 1 ;
DWORD dwBytesReturned = 0 ;
iErrorCode=WSAIoctl(SockRaw, SIO_RCVALL,&dwBufferInLen, sizeof(dwBufferInLen),&dwBufferLen, sizeof(dwBufferLen),&dwBytesReturned , NULL , NULL );}/////////////////////////////////////////////////////////////////////////////
回复人: pitchstar(一站) (2001-11-19 10:18:45) 得0分
老兄,我先问你个问题:已经发出去的帖子还可以改吗?我看你好象把第一帖改过了?怎么做到的?
回复人: cntiger(硕虎) (2001-11-19 10:31:23) 得0分
windows中设置ip需要重起,涉及到windows的最底层调用,还涉及到ip协议的上下层的三层。
成功的可能性较小。
回复人: whz_time(时间) (2001-11-19 10:32:32) 得0分
大伙都一起来讨论讨论嘛,我想听听各位高手的意见。
回复人: glooby(怪物点心) (2001-11-19 14:18:52) 得0分
to pitchstar(一站): 我没有改过呀,我已经在unix上实现了一个链路层协议,现在是要作一个windows的客户端,又不会作内核编程,所以才想出用嗅探的方法,(可以有机子作arp代理的)
to whz_time(时间): 我是要发送数据链路层包,用rawsocket不行的:)
to cntiger(硕虎): 改动windows98以下系统的注册表或是系统信息都要重起的,2k就好了:), 可是我想问有没有不用重起的办法,比如ip alias, 直接修改内核数据结构,或者有没有什么后门:), 好像真的是有的:)我知道可以用DDK实现嗅探和发包, 可是如何做呢?? 我很少作windows编程的,情各位高手多帮帮忙:)
回复人: pitchstar(一站) (2001-11-19 14:57:20) 得0分
windows 下要抓以太帧,可能需要做 ndis 驱动,你看这里有没有资料
http://www.driverdevelop.com
回复人: glooby(怪物点心) (2001-11-20 12:47:53) 得0分
那个winpcap如何呢?? 有没有人用过??
回复人: glooby(怪物点心) (2001-11-20 15:53:51) 得0分
各位高手帮帮忙了!!:)
回复人: DeadWolf(死狼) (2001-11-20 16:04:09) 得0分
旁听
回复人: jetlan(不百) (2001-11-20 16:19:23) 得0分
对于问题1:可用IpRenewAddress 函数。
问题2:本人用c写了一个rcvall的程序,可以得到网络中的ip数据包。还解了tcp 和udp报。
原代码:
rcvall.h //**************************************************************************************
// filename: rcvall.h
// author : lan bin
// company : smaple
// E_mail : [email protected]
// description: Tcp Ip ICMP 头定义
//*****************************************************************************************
typedef struct _iphdr
{
unsigned short ver, //4位IP版本号
len, //4位首部长度
tos, //8位服务类型TOS
total_len, //16位总长度(字节)
ident, //16位标识
flags, //3位标志位
fragment,//13偏远量
ttl, //8位生存时间 TTL
proto, //8位协议 (TCP, UDP 或其他)
checksum;//16位IP首部校验和
unsigned int sourceIP; //32位源IP地址
unsigned int destIP; //32位目的IP地址
}IP_HEADER;typedef struct _tcphdr //定义TCP首部
{
unsigned short sport; //16位源端口
unsigned short dport; //16位目的端口
unsigned int seq; //32位序列号
unsigned int ackseq; //32位确认号
unsigned short offsetlen; //4位首部长度
unsigned short reserve;//6位保留字
unsigned short flag; //6位标志位
unsigned short win; //16位窗口大小
unsigned short checksum; //16位校验和
unsigned short urp; //16位紧急数据偏移量
}TCP_HEADER;typedef struct _udphdr //定义UDP首部
{
unsigned short sport; //16位源端口
unsigned short dport;//16位目的端口
unsigned short len; //16位长度
unsigned short checksum;//16位校验和
} UDP_HEADER;typedef struct _icmphdr //定义ICMP首部
{
BYTE type;//8位类型
BYTE code; //8位代码
unsigned short checksum; //16位校验和
unsigned short id; //识别号(一般用进程号作为识别号)
unsigned short seq; //报文序列号
ULONG timestamp; //时间戳
}ICMP_HEADER;
typedef struct _ipoptionhdr
{
unsigned char code; // Option type
unsigned char len; // Length of option hdr
unsigned char ptr; // Offset into options
unsigned long addr[9]; // List of IP addrs
} IPOPTIONHEADER;
#define MAX_ADDR_LEN 15 //点分制的最大长度
#define MAX_IP_SIZE 65535
#define MIN_IP_HDR_SIZE 20
rcvall.c
//**************************************************************************************
// filename: rcvall.c
// author : lan bin
// company : smaple
// E_mail : [email protected]
// description: Tcp Ip ICMP 实现
//*****************************************************************************************#include <winsock2.h>
#include <stdio.h>
#include "mstcpip.h"
#include "rcvall.h"
#pragma comment(lib,"ws2_32.lib")
//********* 全局变量定义********************
BOOL gParamTcp=FALSE;//关心TCP
BOOL gParamUdp=FALSE;//关心UDP
BOOL gParamIcmp=FALSE;//关心Icmp
char gSourceIp[MAX_ADDR_LEN+1]={0};//过滤源ip
char gDestIP[MAX_ADDR_LEN+1]={0}; //过滤目的ip
unsigned short gParamPort=0;
//************************************************
// usage
void usage()
{
printf("Example :\n");
printf(" usage: rcvall -t -u -i -s:192.202.35.26 -d:192.202.35.37 -p:80 \n ");
printf(" -t attation Tcp Pack.\n");
printf(" -u attation Udp Pack.\n");
printf(" -i attation Icmp Pack.\n");
printf(" -s source ip address.\n");
printf(" -d dest ip address.\n");
printf(" -p: port");
ExitProcess (0);
}
/////////************************************************
// Validate arguments
void ValidateArgs(int argc, char **argv)
{
int i;
if(argc<2)
usage();
for( i=1;i<argc;i++)
{
if ((argv[i][0] == '-') ¦¦ (argv[i][0] == '/'))
{
switch(tolower(argv[i][1]))
{
case 't':
gParamTcp=TRUE;
break;
case 'u':
gParamUdp=TRUE;
break;
case 'i':
gParamIcmp=TRUE;
break;
case 's':
strcpy(gSourceIp,&argv[i][3]);
break;
case 'd':
strcpy(gDestIP,&argv[i][3]);
break;
case 'p':
gParamPort=atoi(&argv[i][3]);
break;
default:
usage();
}
}
else
{
usage();
}
}
}
//*****************************
// print some info
void printInfo()
{
printf("Created by lanbin .\n");
printf("E_mail:[email protected].\n");}
//**********************************
// GetHostIpadd
BOOL GetHostAddr(SOCKET s,SOCKADDR_IN *ifx,int num)
{
SOCKET_ADDRESS_LIST *slist=NULL;
char buf[2048];
DWORD dwBytesRet;
int ret; ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buf, 2048,
&dwBytesRet, NULL, NULL);
if (ret == SOCKET_ERROR)
{
printf("WSAIoctl(SIO_ADDRESS_LIST_QUERY) failed: %d\n",
WSAGetLastError());
return FALSE;
}
slist = (SOCKET_ADDRESS_LIST *)buf;
if (num >= slist->iAddressCount)
return FALSE;
ifx->sin_addr.s_addr = ((SOCKADDR_IN *)slist->Address[num].lpSockaddr)->sin_addr.s_addr;
return TRUE;
}
BOOL DecodeUdpPack(WSABUF *wsa,int offset)
{
BYTE *hdr=(BYTE*)(wsa->buf +offset);
struct _udphdr udphdr;
unsigned short shortval=0;
memcpy(&shortval,hdr,2);
udphdr.sport =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
udphdr.dport =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
udphdr.len =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
udphdr.checksum =ntohs(shortval);
//printf info
printf(" UDP HEADER \n");
printf("源端口 %-6d目的端口 %-6d\n",udphdr.sport ,udphdr.dport );
printf("长度 %-6d校验和 0x%-6d\n",udphdr.len ,udphdr.checksum );return TRUE;
}
//*****************************************
// Decode TCP Pack
BOOL DecodeTcpPack(WSABUF *wsa,int offset)
{
BYTE *hdr=(BYTE*)(wsa->buf +offset);
unsigned short shortval=0;
unsigned int longval=0;
struct _tcphdr tcphdr;
char *data=0;
memcpy(&shortval,hdr,2);
tcphdr.sport =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
tcphdr.dport =ntohs(shortval);
hdr+=2;
memcpy(&longval,hdr,4);
tcphdr.seq =ntohl(longval);
hdr+=4;
memcpy(&longval,hdr,4);
tcphdr.ackseq =ntohl(longval);
hdr+=4;
tcphdr.offsetlen =((*hdr)>>4 &0x0f)*4;
memcpy(&shortval,hdr,2);
shortval=ntohs(shortval);
tcphdr.flag =(shortval & 0x3f);
hdr+=2;
memcpy(&shortval,hdr,2);
tcphdr.win =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
tcphdr.checksum =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
tcphdr.urp =ntohs(shortval);
// printf tcp header
printf(" Tcp Header \n");
printf("源端口 %-6d 目的端口 %-6d\n",tcphdr.sport ,tcphdr.dport );
printf("序列号 0x%-6x 确认号 0x%-6x\n",tcphdr.seq ,tcphdr.ackseq );
printf("数据偏移量(Bytes) %-3d 标志位 %-6d 窗口 %-6d\n",tcphdr.offsetlen ,tcphdr.flag ,tcphdr.win );
printf("校验和 0x%-6x 紧急指针 %-6d\n",tcphdr.checksum ,tcphdr.urp );
//print tcp data
data=wsa->buf +offset+tcphdr.offsetlen ;
printf(data);
return TRUE;
}
//*******************************************************
//DECODE IP PACK
BOOL DecodeIpPacket(WSABUF *wsa)
{
SOCKADDR_IN srcaddr,
destaddr;
BYTE *hdr=(BYTE*)wsa->buf ;
BYTE *nexthdr=0;
unsigned short shortval=0;
unsigned short usSPort=0;
unsigned short usDPort=0;
IP_HEADER iphdr;
char szSource[16]={0};
char szDest[16]={0};
//获得ip header
iphdr.ver =(((*hdr)>>4) & 0x0f) ;
iphdr.len =((*hdr) & 0x0f)*4;
nexthdr=(BYTE*)(wsa->buf +iphdr.len);
hdr++;
iphdr.tos =*hdr;
hdr++;
memcpy(&shortval,hdr,2);
iphdr.total_len =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
iphdr.ident =ntohs(shortval);
hdr+=2;
iphdr.flags =(((*hdr)>>5) & 0x07);
memcpy(&shortval,hdr,2);
iphdr.fragment=(ntohs(shortval) & 0x1fff);
hdr+=2;
iphdr.ttl =*hdr;
hdr++;
iphdr.proto =*hdr;
hdr++;
memcpy(&shortval,hdr,2);
iphdr.checksum =ntohs(shortval);
hdr+=2;
memcpy(&srcaddr.sin_addr.s_addr, hdr, 4);
iphdr.sourceIP =ntohl(srcaddr.sin_addr.s_addr);
hdr+=4;
memcpy(&destaddr.sin_addr.s_addr, hdr, 4);
iphdr.destIP =ntohl(destaddr.sin_addr.s_addr);
//Filter ip
if(strlen(gSourceIp)>0 )
{
if(strcmp(gSourceIp,inet_ntoa(srcaddr.sin_addr))!=0)
return FALSE;
}
if(strlen(gDestIP)>0)
{
if(strcmp(gDestIP,inet_ntoa(destaddr.sin_addr ))!=0)
return FALSE;
}
/// filter port
if(gParamPort>0)
if(iphdr.proto ==2 ¦¦ iphdr.proto ==6 ¦¦ iphdr.proto ==17)
{
memcpy(&usSPort,nexthdr,2);
usSPort=ntohs(usSPort);
nexthdr+=2;
memcpy(&usDPort,nexthdr,2);
usDPort=ntohs(usDPort);
if(gParamPort!=usSPort && gParamPort!=usDPort)
return FALSE;
}
strcpy(szSource,inet_ntoa(srcaddr.sin_addr ));
strcpy(szDest,inet_ntoa(destaddr.sin_addr ));
//输出 ip header
printf("\n");
printf(" IP HEADER \n");
printf("版本号 %-6d报头长度(Bytes) %-6d服务类型 %-6d\n",iphdr.ver ,iphdr.len ,iphdr.tos );
printf("总长度 %-6d标知符 0x%-6x标志 %-6d\n",iphdr.total_len ,iphdr.ident,iphdr.flags );
printf("分段偏移量 %-6d生存时间 %-6d协议 %-6d\n",iphdr.fragment ,iphdr.ttl ,iphdr.proto );
printf("报头校验和 0x%-6x源地址 %s 目的地址 %s\n",iphdr.checksum ,szSource,szDest);
// 获得 协议
switch(iphdr.proto)
{
case 2://iGmp
break;
case 6://tcp
if(gParamTcp)
DecodeTcpPack(wsa,iphdr.len);
break;
case 17://udp
if(gParamUdp)
DecodeUdpPack(wsa,iphdr.len );
break;
default:
printf("No proto");
}
return TRUE;
}
//*************************************************]]
// MAIN
int main(int argc,char **argv)
{
WSADATA wsd;
SOCKET SocketRaw;
SOCKADDR_IN addr;
unsigned int optval=0;
DWORD dwBytesRet=0;
DWORD dwFlags=0;
WSABUF wsa={0,0};
char buffer[MAX_IP_SIZE]={0};
//Usage
ValidateArgs(argc,argv);
//init winsocket
if(WSAStartup(0x0202,&wsd)==SOCKET_ERROR)
{
printf("Init winsocket Error %d\n",WSAGetLastError());
return FALSE;
}
//printf user selection
printInfo();
//create socket
if((SocketRaw=WSASocket(AF_INET,SOCK_RAW,IPPROTO_IP,NULL,0,WSA_FLAG_OVERLAPPED))
==INVALID_SOCKET)
{
printf("create socket error %d.",WSAGetLastError());
return FALSE;
}
//得到本机的ip 地址
if(!GetHostAddr(SocketRaw,&addr,0))
{
return FALSE;
}
addr.sin_family =AF_INET;
addr.sin_port =htons(0);
if(bind(SocketRaw,(SOCKADDR*)&addr,sizeof(addr))==SOCKET_ERROR)
{
printf("bind socket Error %d.\n",WSAGetLastError());
return FALSE;
}
//set socket SIO_RCVALL
optval=1;
if(WSAIoctl (SocketRaw,SIO_RCVALL,&optval,sizeof(optval),
NULL,0,&dwBytesRet,0,0)==SOCKET_ERROR)
{
printf("WSAIoctl Error %d.\n",WSAGetLastError);
}
//recv ip pack
while(1)
{
memset(buffer,0,sizeof(buffer));
wsa.buf =buffer;
wsa.len =MAX_IP_SIZE;
dwFlags=0;
if(WSARecv(SocketRaw,&wsa,1,&dwBytesRet,&dwFlags,0,0)==SOCKET_ERROR)
{
printf("WSARecv Error %d \n",WSAGetLastError);
return FALSE;
}
DecodeIpPacket(&wsa);
}
closesocket(SocketRaw);
WSACleanup ();
return TRUE;
}
回复人: jetlan(不百) (2001-11-20 16:19:47) 得0分
对于问题1:可用IpRenewAddress 函数。
问题2:本人用c写了一个rcvall的程序,可以得到网络中的ip数据包。还解了tcp 和udp报。
原代码:
rcvall.h //**************************************************************************************
// filename: rcvall.h
// author : lan bin
// company : smaple
// E_mail : [email protected]
// description: Tcp Ip ICMP 头定义
//*****************************************************************************************
typedef struct _iphdr
{
unsigned short ver, //4位IP版本号
len, //4位首部长度
tos, //8位服务类型TOS
total_len, //16位总长度(字节)
ident, //16位标识
flags, //3位标志位
fragment,//13偏远量
ttl, //8位生存时间 TTL
proto, //8位协议 (TCP, UDP 或其他)
checksum;//16位IP首部校验和
unsigned int sourceIP; //32位源IP地址
unsigned int destIP; //32位目的IP地址
}IP_HEADER;typedef struct _tcphdr //定义TCP首部
{
unsigned short sport; //16位源端口
unsigned short dport; //16位目的端口
unsigned int seq; //32位序列号
unsigned int ackseq; //32位确认号
unsigned short offsetlen; //4位首部长度
unsigned short reserve;//6位保留字
unsigned short flag; //6位标志位
unsigned short win; //16位窗口大小
unsigned short checksum; //16位校验和
unsigned short urp; //16位紧急数据偏移量
}TCP_HEADER;typedef struct _udphdr //定义UDP首部
{
unsigned short sport; //16位源端口
unsigned short dport;//16位目的端口
unsigned short len; //16位长度
unsigned short checksum;//16位校验和
} UDP_HEADER;typedef struct _icmphdr //定义ICMP首部
{
BYTE type;//8位类型
BYTE code; //8位代码
unsigned short checksum; //16位校验和
unsigned short id; //识别号(一般用进程号作为识别号)
unsigned short seq; //报文序列号
ULONG timestamp; //时间戳
}ICMP_HEADER;
typedef struct _ipoptionhdr
{
unsigned char code; // Option type
unsigned char len; // Length of option hdr
unsigned char ptr; // Offset into options
unsigned long addr[9]; // List of IP addrs
} IPOPTIONHEADER;
#define MAX_ADDR_LEN 15 //点分制的最大长度
#define MAX_IP_SIZE 65535
#define MIN_IP_HDR_SIZE 20
rcvall.c
//**************************************************************************************
// filename: rcvall.c
// author : lan bin
// company : smaple
// E_mail : [email protected]
// description: Tcp Ip ICMP 实现
//*****************************************************************************************#include <winsock2.h>
#include <stdio.h>
#include "mstcpip.h"
#include "rcvall.h"
#pragma comment(lib,"ws2_32.lib")
//********* 全局变量定义********************
BOOL gParamTcp=FALSE;//关心TCP
BOOL gParamUdp=FALSE;//关心UDP
BOOL gParamIcmp=FALSE;//关心Icmp
char gSourceIp[MAX_ADDR_LEN+1]={0};//过滤源ip
char gDestIP[MAX_ADDR_LEN+1]={0}; //过滤目的ip
unsigned short gParamPort=0;
//************************************************
// usage
void usage()
{
printf("Example :\n");
printf(" usage: rcvall -t -u -i -s:192.202.35.26 -d:192.202.35.37 -p:80 \n ");
printf(" -t attation Tcp Pack.\n");
printf(" -u attation Udp Pack.\n");
printf(" -i attation Icmp Pack.\n");
printf(" -s source ip address.\n");
printf(" -d dest ip address.\n");
printf(" -p: port");
ExitProcess (0);
}
/////////************************************************
// Validate arguments
void ValidateArgs(int argc, char **argv)
{
int i;
if(argc<2)
usage();
for( i=1;i<argc;i++)
{
if ((argv[i][0] == '-') ¦¦ (argv[i][0] == '/'))
{
switch(tolower(argv[i][1]))
{
case 't':
gParamTcp=TRUE;
break;
case 'u':
gParamUdp=TRUE;
break;
case 'i':
gParamIcmp=TRUE;
break;
case 's':
strcpy(gSourceIp,&argv[i][3]);
break;
case 'd':
strcpy(gDestIP,&argv[i][3]);
break;
case 'p':
gParamPort=atoi(&argv[i][3]);
break;
default:
usage();
}
}
else
{
usage();
}
}
}
//*****************************
// print some info
void printInfo()
{
printf("Created by lanbin .\n");
printf("E_mail:[email protected].\n");}
//**********************************
// GetHostIpadd
BOOL GetHostAddr(SOCKET s,SOCKADDR_IN *ifx,int num)
{
SOCKET_ADDRESS_LIST *slist=NULL;
char buf[2048];
DWORD dwBytesRet;
int ret; ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buf, 2048,
&dwBytesRet, NULL, NULL);
if (ret == SOCKET_ERROR)
{
printf("WSAIoctl(SIO_ADDRESS_LIST_QUERY) failed: %d\n",
WSAGetLastError());
return FALSE;
}
slist = (SOCKET_ADDRESS_LIST *)buf;
if (num >= slist->iAddressCount)
return FALSE;
ifx->sin_addr.s_addr = ((SOCKADDR_IN *)slist->Address[num].lpSockaddr)->sin_addr.s_addr;
return TRUE;
}
BOOL DecodeUdpPack(WSABUF *wsa,int offset)
{
BYTE *hdr=(BYTE*)(wsa->buf +offset);
struct _udphdr udphdr;
unsigned short shortval=0;
memcpy(&shortval,hdr,2);
udphdr.sport =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
udphdr.dport =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
udphdr.len =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
udphdr.checksum =ntohs(shortval);
//printf info
printf(" UDP HEADER \n");
printf("源端口 %-6d目的端口 %-6d\n",udphdr.sport ,udphdr.dport );
printf("长度 %-6d校验和 0x%-6d\n",udphdr.len ,udphdr.checksum );return TRUE;
}
//*****************************************
// Decode TCP Pack
BOOL DecodeTcpPack(WSABUF *wsa,int offset)
{
BYTE *hdr=(BYTE*)(wsa->buf +offset);
unsigned short shortval=0;
unsigned int longval=0;
struct _tcphdr tcphdr;
char *data=0;
memcpy(&shortval,hdr,2);
tcphdr.sport =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
tcphdr.dport =ntohs(shortval);
hdr+=2;
memcpy(&longval,hdr,4);
tcphdr.seq =ntohl(longval);
hdr+=4;
memcpy(&longval,hdr,4);
tcphdr.ackseq =ntohl(longval);
hdr+=4;
tcphdr.offsetlen =((*hdr)>>4 &0x0f)*4;
memcpy(&shortval,hdr,2);
shortval=ntohs(shortval);
tcphdr.flag =(shortval & 0x3f);
hdr+=2;
memcpy(&shortval,hdr,2);
tcphdr.win =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
tcphdr.checksum =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
tcphdr.urp =ntohs(shortval);
// printf tcp header
printf(" Tcp Header \n");
printf("源端口 %-6d 目的端口 %-6d\n",tcphdr.sport ,tcphdr.dport );
printf("序列号 0x%-6x 确认号 0x%-6x\n",tcphdr.seq ,tcphdr.ackseq );
printf("数据偏移量(Bytes) %-3d 标志位 %-6d 窗口 %-6d\n",tcphdr.offsetlen ,tcphdr.flag ,tcphdr.win );
printf("校验和 0x%-6x 紧急指针 %-6d\n",tcphdr.checksum ,tcphdr.urp );
//print tcp data
data=wsa->buf +offset+tcphdr.offsetlen ;
printf(data);
return TRUE;
}
//*******************************************************
//DECODE IP PACK
BOOL DecodeIpPacket(WSABUF *wsa)
{
SOCKADDR_IN srcaddr,
destaddr;
BYTE *hdr=(BYTE*)wsa->buf ;
BYTE *nexthdr=0;
unsigned short shortval=0;
unsigned short usSPort=0;
unsigned short usDPort=0;
IP_HEADER iphdr;
char szSource[16]={0};
char szDest[16]={0};
//获得ip header
iphdr.ver =(((*hdr)>>4) & 0x0f) ;
iphdr.len =((*hdr) & 0x0f)*4;
nexthdr=(BYTE*)(wsa->buf +iphdr.len);
hdr++;
iphdr.tos =*hdr;
hdr++;
memcpy(&shortval,hdr,2);
iphdr.total_len =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
iphdr.ident =ntohs(shortval);
hdr+=2;
iphdr.flags =(((*hdr)>>5) & 0x07);
memcpy(&shortval,hdr,2);
iphdr.fragment=(ntohs(shortval) & 0x1fff);
hdr+=2;
iphdr.ttl =*hdr;
hdr++;
iphdr.proto =*hdr;
hdr++;
memcpy(&shortval,hdr,2);
iphdr.checksum =ntohs(shortval);
hdr+=2;
memcpy(&srcaddr.sin_addr.s_addr, hdr, 4);
iphdr.sourceIP =ntohl(srcaddr.sin_addr.s_addr);
hdr+=4;
memcpy(&destaddr.sin_addr.s_addr, hdr, 4);
iphdr.destIP =ntohl(destaddr.sin_addr.s_addr);
//Filter ip
if(strlen(gSourceIp)>0 )
{
if(strcmp(gSourceIp,inet_ntoa(srcaddr.sin_addr))!=0)
return FALSE;
}
if(strlen(gDestIP)>0)
{
if(strcmp(gDestIP,inet_ntoa(destaddr.sin_addr ))!=0)
return FALSE;
}
/// filter port
if(gParamPort>0)
if(iphdr.proto ==2 ¦¦ iphdr.proto ==6 ¦¦ iphdr.proto ==17)
{
memcpy(&usSPort,nexthdr,2);
usSPort=ntohs(usSPort);
nexthdr+=2;
memcpy(&usDPort,nexthdr,2);
usDPort=ntohs(usDPort);
if(gParamPort!=usSPort && gParamPort!=usDPort)
return FALSE;
}
strcpy(szSource,inet_ntoa(srcaddr.sin_addr ));
strcpy(szDest,inet_ntoa(destaddr.sin_addr ));
//输出 ip header
printf("\n");
printf(" IP HEADER \n");
printf("版本号 %-6d报头长度(Bytes) %-6d服务类型 %-6d\n",iphdr.ver ,iphdr.len ,iphdr.tos );
printf("总长度 %-6d标知符 0x%-6x标志 %-6d\n",iphdr.total_len ,iphdr.ident,iphdr.flags );
printf("分段偏移量 %-6d生存时间 %-6d协议 %-6d\n",iphdr.fragment ,iphdr.ttl ,iphdr.proto );
printf("报头校验和 0x%-6x源地址 %s 目的地址 %s\n",iphdr.checksum ,szSource,szDest);
// 获得 协议
switch(iphdr.proto)
{
case 2://iGmp
break;
case 6://tcp
if(gParamTcp)
DecodeTcpPack(wsa,iphdr.len);
break;
case 17://udp
if(gParamUdp)
DecodeUdpPack(wsa,iphdr.len );
break;
default:
printf("No proto");
}
return TRUE;
}
//*************************************************]]
// MAIN
int main(int argc,char **argv)
{
WSADATA wsd;
SOCKET SocketRaw;
SOCKADDR_IN addr;
unsigned int optval=0;
DWORD dwBytesRet=0;
DWORD dwFlags=0;
WSABUF wsa={0,0};
char buffer[MAX_IP_SIZE]={0};
//Usage
ValidateArgs(argc,argv);
//init winsocket
if(WSAStartup(0x0202,&wsd)==SOCKET_ERROR)
{
printf("Init winsocket Error %d\n",WSAGetLastError());
return FALSE;
}
//printf user selection
printInfo();
//create socket
if((SocketRaw=WSASocket(AF_INET,SOCK_RAW,IPPROTO_IP,NULL,0,WSA_FLAG_OVERLAPPED))
==INVALID_SOCKET)
{
printf("create socket error %d.",WSAGetLastError());
return FALSE;
}
//得到本机的ip 地址
if(!GetHostAddr(SocketRaw,&addr,0))
{
return FALSE;
}
addr.sin_family =AF_INET;
addr.sin_port =htons(0);
if(bind(SocketRaw,(SOCKADDR*)&addr,sizeof(addr))==SOCKET_ERROR)
{
printf("bind socket Error %d.\n",WSAGetLastError());
return FALSE;
}
//set socket SIO_RCVALL
optval=1;
if(WSAIoctl (SocketRaw,SIO_RCVALL,&optval,sizeof(optval),
NULL,0,&dwBytesRet,0,0)==SOCKET_ERROR)
{
printf("WSAIoctl Error %d.\n",WSAGetLastError);
}
//recv ip pack
while(1)
{
memset(buffer,0,sizeof(buffer));
wsa.buf =buffer;
wsa.len =MAX_IP_SIZE;
dwFlags=0;
if(WSARecv(SocketRaw,&wsa,1,&dwBytesRet,&dwFlags,0,0)==SOCKET_ERROR)
{
printf("WSARecv Error %d \n",WSAGetLastError);
return FALSE;
}
DecodeIpPacket(&wsa);
}
closesocket(SocketRaw);
WSACleanup ();
return TRUE;
}
回复人: jetlan(不百) (2001-11-20 16:20:49) 得0分
要记的给分阿。:
CSDN首页 | 新闻聚焦 | 共享软件 | 俱乐部 | 开发文档 | 专家门诊 | 招聘求职 | Linux园地 | 程序员杂志
--------------------------------------------------------------------------------
我要回复 | 我感兴趣 | 打印贴子 | 推荐给朋友 | 关闭窗口
主 题:有趣的问题!
作 者:nccpu
所属论坛:Visual C++
问题点数:30
回复次数:7
发表时间:2001-11-21 22:24:43
对话框中有两个按钮控件,其中一个控制一个循环的开始,另一个控制它的结束,该如何处理?
回复贴子:
回复人: Flysnow(飞雪) (2001-11-21 22:34:51) 得0分
最简单的方法,不用多线程设一个全局变量来决定循环,另一个按钮来控制全局变量的值好像就可以了不过这个循环可不要太快了,不然的话,可能系统都不能响应另一个按钮了咯
回复人: forrest9910(liaomaomao) (2001-11-22 8:17:12) 得0分
好像得用两个线程,用一个线程的话,循环内要读消息,比较费事。
回复人: jason802(小糊涂仙) (2001-11-22 8:42:12) 得0分
1。对于同一个对话框内的两个控件来说,永远不需要全局变量,一个成员变量搞定。
2。多县城太烦,其实这只是一个逻辑游戏。//发消息通知循环开始
void CMyDlg::OnButton1()
{
m_flag = 1;
PostMessage(WM_JASON,0,0);
return;
}//设置标志,让循环结束,不需要发消息
void CMyDlg::OnButton2()
{
m_flag = 0;
return;
}
void CMyDlg::Jason()
{
while(m_flag)
{
//todo
}
return;
}
回复人: dog_dog(狗狗) (2001-11-22 8:43:14) 得0分
study
回复人: jason802(小糊涂仙) (2001-11-22 8:49:35) 得0分
如果你思维定势,认定循环在OnButton1中进行,那么就很难得到答案,除非用一种很烂的方法:
设定一个变量,不能思维定势根据这个变量是0或者1来判断,而是这两个按纽都让这个变量加1,然后根据这个变量的奇偶来判断。之所以说这个方法烂是因为如果其中一个按纽连续按了两下,这两个按纽的作用就反过来了。
回复人: dongfa(阿东) (2001-11-22 9:01:17) 得0分
如果要循环的话,至少要开一个线程的,否则程序会无响应。
主 题:巨分相送!!回答出来者另开帖子送500分!
作 者:glooby
所属论坛:Visual C++
问题点数:59
回复次数:18
发表时间:2001-11-18 13:12:31
问题1, 如何写程序给某块网卡IP设置地址,当然不能重起
问题2, 如何写一个嗅探器,介绍关键步骤就行了
问题3, 如何发送一个数据链路层报文, 类型由我设定,比如1234。:)
当然, 要用windows编程!
回复贴子:
回复人: glooby(怪物点心) (2001-11-18 13:25:53) 得0分
连个UP的人都没有??
回复人: glooby(怪物点心) (2001-11-18 13:29:57) 得0分
问题1改为, 给一台机子分一个IP,该机子拿到IP后不需要重起就可以使用就行了!
回复人: glooby(怪物点心) (2001-11-18 13:31:13) 得0分
第一个问题用IP伪装行吗?? 该如何做呢??
回复人: pitchstar(一站) (2001-11-18 13:40:05) 得0分
问题 1:用这个 api GetAdaptersInfo(),他返回好象是一个链表,每个节点代表一个卡。
问题 2:需要 ndis 驱动,不懂
问题 3:ip 伪装是比较复杂的技术,而且有运气的成分,给一篇文章:http://www.csdn.net/develop/read_article.asp?id=9343回复人: glooby(怪物点心) (2001-11-18 20:04:59) 得0分
我是要设置IP, 不是得到适配器的信息。
回复人: pitchstar(一站) (2001-11-19 9:54:35) 得0分
设置 ip 不知道,但你用原始套接字可以以任何地址给人发包,但却收不到,如果在局域网可以通过监听以太网帧收到回复的包,但基本没多大意义,自己维护协议是很复杂的UDP 还好说点
回复人: whz_time(时间) (2001-11-19 10:09:44) 得0分
对于问题 2:我这有一段代码,但还有问题,我们可以一起研究一下:// tcp.cpp : Defines the entry point for the console application.
//
#include "stdlib.h"
#include <stdio.h>
#include "winsock2.h"
#include "IPHlpApi.h"
#include "mstcpip.h"
#include "errno.h"
#include "conio.h"//#include "rcv_.h"void init(void);
void GetProtocol(int num, char *str);
void recv_icmp(char *host, int sockfd);
void handle_icmp(char *buf);
void getippak(int SockRaw);/////////////////////////////////////////////////////////typedef struct _PROTN2T
{
int proto ;
char *pprototext ;
}PROTN2T ; /////////////////////////////////////////////////////////
typedef struct _IPHEADER {
unsigned char header_len:4;
unsigned char version:4;
unsigned char tos; // type of service
unsigned short total_len; // length of the packet
unsigned short ident; // unique identifier
unsigned short flags;
unsigned char ttl;
unsigned char proto; // protocol ( IP , TCP, UDP etc)
unsigned short checksum;
unsigned int sourceIP;
unsigned int destIP;}IPHEADER;//////////////////////////////////////////////////////////////int main(int argc, char* argv[])//
{
char *host_="localhost";
int sockfd;
init();
sockfd=socket(AF_INET,SOCK_RAW,IPPROTO_IP);//IPPROTO_IP);
if(sockfd<0)
{
printf("socket error->%s\n",strerror(errno));
exit(1);
}
getippak(sockfd);recv_icmp(host_,sockfd);return(0);
}///////////////////////////////////////////////////////
void init(void)
{
WORD wVersion;
WSADATA wsaData;
int err;
wVersion=MAKEWORD(2,0);
err=WSAStartup(wVersion,&wsaData);
if(err!=0)
exit(1);}
///////////////////////////////////////////////////////
void GetProtocol(int num_, char *str_)
{switch(num_)
{
case 0: str_="IP";
break;
case 1: str_="ICMP";
break;
case 2: str_="IGMP";
break;
case 3: str_="GGP";
break;
case 6: str_="TCP";
break;
case 12: str_="PUP";
break;
case 17: str_="UDP";
break;
case 22: str_="IDP";
break;
case 77: str_="ND";
break;
case 255: str_="RAW";
break;
default: str_="MAX";
break;
}
}///////////////////////////////////////////////////////
void recv_icmp(char *host, int sockfd)
{
char recvbuf[1024],*bufwork;
char *pSource,*pDest;
IPHEADER *pIpHeader;
in_addr ina;
char szSource [16] , szDest[16];// szErr [ 50 ];
char *pLastBuf = NULL ;char *str,*temp;
// int len;
int n;
//long count=0;
for(;;)
{
memset(szSource,0,sizeof(szSource));
memset(szDest,0,sizeof(szDest));
memset(recvbuf,0,sizeof(recvbuf));
n=recvfrom(sockfd,recvbuf,sizeof(recvbuf),0,NULL,NULL);
// GetLastError();
// MessageBox(NULL,(char *)GetLastError(),"",0);
if(n<0)
{
if(errno==EINTR)
continue;
else
{
printf("Recvfrom Error n=%d\n",n);
printf("%s\n",recvbuf);
Sleep(1000);
continue;
}//else
continue;} //if
// iRet = recv(pDlg->m_s, buf , sizeof( buf ) , 0 ) ;
// putch('x');
// getch();
if(*recvbuf)
{
bufwork = recvbuf ;
pIpHeader = (IPHEADER *)bufwork ;
WORD iLen = ntohs(pIpHeader->total_len) ;
ina.S_un.S_addr = pIpHeader->sourceIP ;
pSource =inet_ntoa( ina ) ;
strcpy( szSource , pSource ) ;
// str.Format("Source IP: %s, ",szSource);
sprintf(str,"Source IP: %s, ",szSource);ina.S_un.S_addr = pIpHeader->destIP ;
pDest = inet_ntoa( ina ) ;
strcpy( szDest , pDest ) ;
// temp.Format("Dest IP: %s, Protocol: ",szDest);
sprintf(temp,"Dest IP: %s, Protocol: ",szDest);
// str+=temp;
strcat(str,temp);
int test=pIpHeader->total_len;int num=pIpHeader->proto;
GetProtocol(num, temp);
// str+=temp;
strcat(str,temp);// temp.Format (",%d,%d",buf[20]*256+buf[21],buf[22]*256+buf[23]);
sprintf(temp,",%d,%d",recvbuf[20]*256+recvbuf[21],recvbuf[22]*256+recvbuf[23]);// str+=temp;
strcat(str,temp);
printf("getippak is:%s",str);
// pDlg->m_ctlPort.InsertItem(0,str);
// handle_icmp(recvbuf);
}//if
}//for}
/////////////////////////////////////////////////////////void recv_icmp(char *host, int sockfd)
//{
//char recvbuf[512];
// int len;
//int n;
//long count=0;
//for(;;)
//{
//memset(recvbuf,0,sizeof(recvbuf));
//n=recvfrom(sockfd,recvbuf,sizeof(recvbuf),0,NULL,NULL);
////GetLastError();
///MessageBox(NULL,(char *)GetLastError(),"",0);
//if(n<0)
// {
// if(errno==EINTR) continue;
// else
// {
// printf("Recvfrom Error n=%d\n",n);
// printf("%s\n",recvbuf);
// Sleep(1000);
// continue;
// }
// }
//handle_icmp(recvbuf);
//}
//} /////////////////////////////////////////////////////////void handle_icmp(char *buf)
//{
//// struct ip *ip;
//// ip=(struct ip*)buf;
//// printf("IP:%ld\n",ip->ip_src.s_addr);
//printf("Get--->%s",buf);
//}///////////////////////////////////////////////////////////////void getippak(int SockRaw)
{
#define SIO_RCVALL _WSAIOW(IOC_VENDOR,1) //初始化SOCKET
#define MAX_HOSTNAME_LAN 256// WSADATA wsaData;
int iErrorCode;//iErrorCode = WSAStartup(MAKEWORD(2,1),&wsaData);
//CheckSockError(iErrorCode, "WSAStartup");
//SockRaw = socket(AF_INET , SOCK_RAW , IPPROTO_IP);
//CheckSockError(SockRaw, "socket");
//获取本机IP地址
char FAR name[MAX_HOSTNAME_LAN];
iErrorCode = gethostname(name, MAX_HOSTNAME_LAN);
//CheckSockError(iErrorCode, "gethostname");
struct hostent FAR * pHostent;
pHostent = gethostbyname(name);
SOCKADDR_IN sa;
sa.sin_family = AF_INET;
sa.sin_port = htons(80);//6000);
memcpy(&sa.sin_addr.S_un.S_addr, pHostent->h_addr_list[0], pHostent->h_length);
iErrorCode = bind(SockRaw, (PSOCKADDR)&sa, sizeof(sa));//设置SOCK_RAW为SIO_RCVALL,以便接收所有的IP包DWORD dwBufferLen[10] ;
DWORD dwBufferInLen = 1 ;
DWORD dwBytesReturned = 0 ;
iErrorCode=WSAIoctl(SockRaw, SIO_RCVALL,&dwBufferInLen, sizeof(dwBufferInLen),&dwBufferLen, sizeof(dwBufferLen),&dwBytesReturned , NULL , NULL );}/////////////////////////////////////////////////////////////////////////////回复人: pitchstar(一站) (2001-11-19 10:18:45) 得0分
老兄,我先问你个问题:已经发出去的帖子还可以改吗?我看你好象把第一帖改过了?怎么做到的?
回复人: cntiger(硕虎) (2001-11-19 10:31:23) 得0分
windows中设置ip需要重起,涉及到windows的最底层调用,还涉及到ip协议的上下层的三层。
成功的可能性较小。
回复人: whz_time(时间) (2001-11-19 10:32:32) 得0分
大伙都一起来讨论讨论嘛,我想听听各位高手的意见。回复人: glooby(怪物点心) (2001-11-19 14:18:52) 得0分
to pitchstar(一站): 我没有改过呀,我已经在unix上实现了一个链路层协议,现在是要作一个windows的客户端,又不会作内核编程,所以才想出用嗅探的方法,(可以有机子作arp代理的)
to whz_time(时间): 我是要发送数据链路层包,用rawsocket不行的:)
to cntiger(硕虎): 改动windows98以下系统的注册表或是系统信息都要重起的,2k就好了:), 可是我想问有没有不用重起的办法,比如ip alias, 直接修改内核数据结构,或者有没有什么后门:), 好像真的是有的:)我知道可以用DDK实现嗅探和发包, 可是如何做呢?? 我很少作windows编程的,情各位高手多帮帮忙:)
回复人: pitchstar(一站) (2001-11-19 14:57:20) 得0分
windows 下要抓以太帧,可能需要做 ndis 驱动,你看这里有没有资料
http://www.driverdevelop.com
回复人: glooby(怪物点心) (2001-11-20 12:47:53) 得0分
那个winpcap如何呢?? 有没有人用过??
回复人: glooby(怪物点心) (2001-11-20 15:53:51) 得0分
各位高手帮帮忙了!!:)
回复人: DeadWolf(死狼) (2001-11-20 16:04:09) 得0分
旁听
回复人: jetlan(不百) (2001-11-20 16:19:23) 得0分
对于问题1:可用IpRenewAddress 函数。
问题2:本人用c写了一个rcvall的程序,可以得到网络中的ip数据包。还解了tcp 和udp报。
原代码:
rcvall.h //**************************************************************************************
// filename: rcvall.h
// author : lan bin
// company : smaple
// E_mail : [email protected]
// description: Tcp Ip ICMP 头定义
//*****************************************************************************************
typedef struct _iphdr
{
unsigned short ver, //4位IP版本号
len, //4位首部长度
tos, //8位服务类型TOS
total_len, //16位总长度(字节)
ident, //16位标识
flags, //3位标志位
fragment,//13偏远量
ttl, //8位生存时间 TTL
proto, //8位协议 (TCP, UDP 或其他)
checksum;//16位IP首部校验和
unsigned int sourceIP; //32位源IP地址
unsigned int destIP; //32位目的IP地址
}IP_HEADER;typedef struct _tcphdr //定义TCP首部
{
unsigned short sport; //16位源端口
unsigned short dport; //16位目的端口
unsigned int seq; //32位序列号
unsigned int ackseq; //32位确认号
unsigned short offsetlen; //4位首部长度
unsigned short reserve;//6位保留字
unsigned short flag; //6位标志位
unsigned short win; //16位窗口大小
unsigned short checksum; //16位校验和
unsigned short urp; //16位紧急数据偏移量
}TCP_HEADER;typedef struct _udphdr //定义UDP首部
{
unsigned short sport; //16位源端口
unsigned short dport;//16位目的端口
unsigned short len; //16位长度
unsigned short checksum;//16位校验和
} UDP_HEADER;typedef struct _icmphdr //定义ICMP首部
{
BYTE type;//8位类型
BYTE code; //8位代码
unsigned short checksum; //16位校验和
unsigned short id; //识别号(一般用进程号作为识别号)
unsigned short seq; //报文序列号
ULONG timestamp; //时间戳
}ICMP_HEADER;
typedef struct _ipoptionhdr
{
unsigned char code; // Option type
unsigned char len; // Length of option hdr
unsigned char ptr; // Offset into options
unsigned long addr[9]; // List of IP addrs
} IPOPTIONHEADER;
#define MAX_ADDR_LEN 15 //点分制的最大长度
#define MAX_IP_SIZE 65535
#define MIN_IP_HDR_SIZE 20
rcvall.c
//**************************************************************************************
// filename: rcvall.c
// author : lan bin
// company : smaple
// E_mail : [email protected]
// description: Tcp Ip ICMP 实现
//*****************************************************************************************#include <winsock2.h>
#include <stdio.h>
#include "mstcpip.h"
#include "rcvall.h"
#pragma comment(lib,"ws2_32.lib")
//********* 全局变量定义********************
BOOL gParamTcp=FALSE;//关心TCP
BOOL gParamUdp=FALSE;//关心UDP
BOOL gParamIcmp=FALSE;//关心Icmp
char gSourceIp[MAX_ADDR_LEN+1]={0};//过滤源ip
char gDestIP[MAX_ADDR_LEN+1]={0}; //过滤目的ip
unsigned short gParamPort=0;
//************************************************
// usage
void usage()
{
printf("Example :\n");
printf(" usage: rcvall -t -u -i -s:192.202.35.26 -d:192.202.35.37 -p:80 \n ");
printf(" -t attation Tcp Pack.\n");
printf(" -u attation Udp Pack.\n");
printf(" -i attation Icmp Pack.\n");
printf(" -s source ip address.\n");
printf(" -d dest ip address.\n");
printf(" -p: port");
ExitProcess (0);
}
/////////************************************************
// Validate arguments
void ValidateArgs(int argc, char **argv)
{
int i;
if(argc<2)
usage();
for( i=1;i<argc;i++)
{
if ((argv[i][0] == '-') ¦¦ (argv[i][0] == '/'))
{
switch(tolower(argv[i][1]))
{
case 't':
gParamTcp=TRUE;
break;
case 'u':
gParamUdp=TRUE;
break;
case 'i':
gParamIcmp=TRUE;
break;
case 's':
strcpy(gSourceIp,&argv[i][3]);
break;
case 'd':
strcpy(gDestIP,&argv[i][3]);
break;
case 'p':
gParamPort=atoi(&argv[i][3]);
break;
default:
usage();
}
}
else
{
usage();
}
}
}
//*****************************
// print some info
void printInfo()
{
printf("Created by lanbin .\n");
printf("E_mail:[email protected].\n");}
//**********************************
// GetHostIpadd
BOOL GetHostAddr(SOCKET s,SOCKADDR_IN *ifx,int num)
{
SOCKET_ADDRESS_LIST *slist=NULL;
char buf[2048];
DWORD dwBytesRet;
int ret; ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buf, 2048,
&dwBytesRet, NULL, NULL);
if (ret == SOCKET_ERROR)
{
printf("WSAIoctl(SIO_ADDRESS_LIST_QUERY) failed: %d\n",
WSAGetLastError());
return FALSE;
}
slist = (SOCKET_ADDRESS_LIST *)buf;
if (num >= slist->iAddressCount)
return FALSE;
ifx->sin_addr.s_addr = ((SOCKADDR_IN *)slist->Address[num].lpSockaddr)->sin_addr.s_addr;
return TRUE;
}
BOOL DecodeUdpPack(WSABUF *wsa,int offset)
{
BYTE *hdr=(BYTE*)(wsa->buf +offset);
struct _udphdr udphdr;
unsigned short shortval=0;
memcpy(&shortval,hdr,2);
udphdr.sport =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
udphdr.dport =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
udphdr.len =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
udphdr.checksum =ntohs(shortval);
//printf info
printf(" UDP HEADER \n");
printf("源端口 %-6d目的端口 %-6d\n",udphdr.sport ,udphdr.dport );
printf("长度 %-6d校验和 0x%-6d\n",udphdr.len ,udphdr.checksum );return TRUE;
}
//*****************************************
// Decode TCP Pack
BOOL DecodeTcpPack(WSABUF *wsa,int offset)
{
BYTE *hdr=(BYTE*)(wsa->buf +offset);
unsigned short shortval=0;
unsigned int longval=0;
struct _tcphdr tcphdr;
char *data=0;
memcpy(&shortval,hdr,2);
tcphdr.sport =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
tcphdr.dport =ntohs(shortval);
hdr+=2;
memcpy(&longval,hdr,4);
tcphdr.seq =ntohl(longval);
hdr+=4;
memcpy(&longval,hdr,4);
tcphdr.ackseq =ntohl(longval);
hdr+=4;
tcphdr.offsetlen =((*hdr)>>4 &0x0f)*4;
memcpy(&shortval,hdr,2);
shortval=ntohs(shortval);
tcphdr.flag =(shortval & 0x3f);
hdr+=2;
memcpy(&shortval,hdr,2);
tcphdr.win =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
tcphdr.checksum =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
tcphdr.urp =ntohs(shortval);
// printf tcp header
printf(" Tcp Header \n");
printf("源端口 %-6d 目的端口 %-6d\n",tcphdr.sport ,tcphdr.dport );
printf("序列号 0x%-6x 确认号 0x%-6x\n",tcphdr.seq ,tcphdr.ackseq );
printf("数据偏移量(Bytes) %-3d 标志位 %-6d 窗口 %-6d\n",tcphdr.offsetlen ,tcphdr.flag ,tcphdr.win );
printf("校验和 0x%-6x 紧急指针 %-6d\n",tcphdr.checksum ,tcphdr.urp );
//print tcp data
data=wsa->buf +offset+tcphdr.offsetlen ;
printf(data);
return TRUE;
}
//*******************************************************
//DECODE IP PACK
BOOL DecodeIpPacket(WSABUF *wsa)
{
SOCKADDR_IN srcaddr,
destaddr;
BYTE *hdr=(BYTE*)wsa->buf ;
BYTE *nexthdr=0;
unsigned short shortval=0;
unsigned short usSPort=0;
unsigned short usDPort=0;
IP_HEADER iphdr;
char szSource[16]={0};
char szDest[16]={0};
//获得ip header
iphdr.ver =(((*hdr)>>4) & 0x0f) ;
iphdr.len =((*hdr) & 0x0f)*4;
nexthdr=(BYTE*)(wsa->buf +iphdr.len);
hdr++;
iphdr.tos =*hdr;
hdr++;
memcpy(&shortval,hdr,2);
iphdr.total_len =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
iphdr.ident =ntohs(shortval);
hdr+=2;
iphdr.flags =(((*hdr)>>5) & 0x07);
memcpy(&shortval,hdr,2);
iphdr.fragment=(ntohs(shortval) & 0x1fff);
hdr+=2;
iphdr.ttl =*hdr;
hdr++;
iphdr.proto =*hdr;
hdr++;
memcpy(&shortval,hdr,2);
iphdr.checksum =ntohs(shortval);
hdr+=2;
memcpy(&srcaddr.sin_addr.s_addr, hdr, 4);
iphdr.sourceIP =ntohl(srcaddr.sin_addr.s_addr);
hdr+=4;
memcpy(&destaddr.sin_addr.s_addr, hdr, 4);
iphdr.destIP =ntohl(destaddr.sin_addr.s_addr);
//Filter ip
if(strlen(gSourceIp)>0 )
{
if(strcmp(gSourceIp,inet_ntoa(srcaddr.sin_addr))!=0)
return FALSE;
}
if(strlen(gDestIP)>0)
{
if(strcmp(gDestIP,inet_ntoa(destaddr.sin_addr ))!=0)
return FALSE;
}
/// filter port
if(gParamPort>0)
if(iphdr.proto ==2 ¦¦ iphdr.proto ==6 ¦¦ iphdr.proto ==17)
{
memcpy(&usSPort,nexthdr,2);
usSPort=ntohs(usSPort);
nexthdr+=2;
memcpy(&usDPort,nexthdr,2);
usDPort=ntohs(usDPort);
if(gParamPort!=usSPort && gParamPort!=usDPort)
return FALSE;
}
strcpy(szSource,inet_ntoa(srcaddr.sin_addr ));
strcpy(szDest,inet_ntoa(destaddr.sin_addr ));
//输出 ip header
printf("\n");
printf(" IP HEADER \n");
printf("版本号 %-6d报头长度(Bytes) %-6d服务类型 %-6d\n",iphdr.ver ,iphdr.len ,iphdr.tos );
printf("总长度 %-6d标知符 0x%-6x标志 %-6d\n",iphdr.total_len ,iphdr.ident,iphdr.flags );
printf("分段偏移量 %-6d生存时间 %-6d协议 %-6d\n",iphdr.fragment ,iphdr.ttl ,iphdr.proto );
printf("报头校验和 0x%-6x源地址 %s 目的地址 %s\n",iphdr.checksum ,szSource,szDest);
// 获得 协议
switch(iphdr.proto)
{
case 2://iGmp
break;
case 6://tcp
if(gParamTcp)
DecodeTcpPack(wsa,iphdr.len);
break;
case 17://udp
if(gParamUdp)
DecodeUdpPack(wsa,iphdr.len );
break;
default:
printf("No proto");
}
return TRUE;
}
//*************************************************]]
// MAIN
int main(int argc,char **argv)
{
WSADATA wsd;
SOCKET SocketRaw;
SOCKADDR_IN addr;
unsigned int optval=0;
DWORD dwBytesRet=0;
DWORD dwFlags=0;
WSABUF wsa={0,0};
char buffer[MAX_IP_SIZE]={0};
//Usage
ValidateArgs(argc,argv);
//init winsocket
if(WSAStartup(0x0202,&wsd)==SOCKET_ERROR)
{
printf("Init winsocket Error %d\n",WSAGetLastError());
return FALSE;
}
//printf user selection
printInfo();
//create socket
if((SocketRaw=WSASocket(AF_INET,SOCK_RAW,IPPROTO_IP,NULL,0,WSA_FLAG_OVERLAPPED))
==INVALID_SOCKET)
{
printf("create socket error %d.",WSAGetLastError());
return FALSE;
}
//得到本机的ip 地址
if(!GetHostAddr(SocketRaw,&addr,0))
{
return FALSE;
}
addr.sin_family =AF_INET;
addr.sin_port =htons(0);
if(bind(SocketRaw,(SOCKADDR*)&addr,sizeof(addr))==SOCKET_ERROR)
{
printf("bind socket Error %d.\n",WSAGetLastError());
return FALSE;
}
//set socket SIO_RCVALL
optval=1;
if(WSAIoctl (SocketRaw,SIO_RCVALL,&optval,sizeof(optval),
NULL,0,&dwBytesRet,0,0)==SOCKET_ERROR)
{
printf("WSAIoctl Error %d.\n",WSAGetLastError);
}
//recv ip pack
while(1)
{
memset(buffer,0,sizeof(buffer));
wsa.buf =buffer;
wsa.len =MAX_IP_SIZE;
dwFlags=0;
if(WSARecv(SocketRaw,&wsa,1,&dwBytesRet,&dwFlags,0,0)==SOCKET_ERROR)
{
printf("WSARecv Error %d \n",WSAGetLastError);
return FALSE;
}
DecodeIpPacket(&wsa);
}
closesocket(SocketRaw);
WSACleanup ();
return TRUE;
}
回复人: jetlan(不百) (2001-11-20 16:19:47) 得0分
对于问题1:可用IpRenewAddress 函数。
问题2:本人用c写了一个rcvall的程序,可以得到网络中的ip数据包。还解了tcp 和udp报。
原代码:
rcvall.h //**************************************************************************************
// filename: rcvall.h
// author : lan bin
// company : smaple
// E_mail : [email protected]
// description: Tcp Ip ICMP 头定义
//*****************************************************************************************
typedef struct _iphdr
{
unsigned short ver, //4位IP版本号
len, //4位首部长度
tos, //8位服务类型TOS
total_len, //16位总长度(字节)
ident, //16位标识
flags, //3位标志位
fragment,//13偏远量
ttl, //8位生存时间 TTL
proto, //8位协议 (TCP, UDP 或其他)
checksum;//16位IP首部校验和
unsigned int sourceIP; //32位源IP地址
unsigned int destIP; //32位目的IP地址
}IP_HEADER;typedef struct _tcphdr //定义TCP首部
{
unsigned short sport; //16位源端口
unsigned short dport; //16位目的端口
unsigned int seq; //32位序列号
unsigned int ackseq; //32位确认号
unsigned short offsetlen; //4位首部长度
unsigned short reserve;//6位保留字
unsigned short flag; //6位标志位
unsigned short win; //16位窗口大小
unsigned short checksum; //16位校验和
unsigned short urp; //16位紧急数据偏移量
}TCP_HEADER;typedef struct _udphdr //定义UDP首部
{
unsigned short sport; //16位源端口
unsigned short dport;//16位目的端口
unsigned short len; //16位长度
unsigned short checksum;//16位校验和
} UDP_HEADER;typedef struct _icmphdr //定义ICMP首部
{
BYTE type;//8位类型
BYTE code; //8位代码
unsigned short checksum; //16位校验和
unsigned short id; //识别号(一般用进程号作为识别号)
unsigned short seq; //报文序列号
ULONG timestamp; //时间戳
}ICMP_HEADER;
typedef struct _ipoptionhdr
{
unsigned char code; // Option type
unsigned char len; // Length of option hdr
unsigned char ptr; // Offset into options
unsigned long addr[9]; // List of IP addrs
} IPOPTIONHEADER;
#define MAX_ADDR_LEN 15 //点分制的最大长度
#define MAX_IP_SIZE 65535
#define MIN_IP_HDR_SIZE 20
rcvall.c
//**************************************************************************************
// filename: rcvall.c
// author : lan bin
// company : smaple
// E_mail : [email protected]
// description: Tcp Ip ICMP 实现
//*****************************************************************************************#include <winsock2.h>
#include <stdio.h>
#include "mstcpip.h"
#include "rcvall.h"
#pragma comment(lib,"ws2_32.lib")
//********* 全局变量定义********************
BOOL gParamTcp=FALSE;//关心TCP
BOOL gParamUdp=FALSE;//关心UDP
BOOL gParamIcmp=FALSE;//关心Icmp
char gSourceIp[MAX_ADDR_LEN+1]={0};//过滤源ip
char gDestIP[MAX_ADDR_LEN+1]={0}; //过滤目的ip
unsigned short gParamPort=0;
//************************************************
// usage
void usage()
{
printf("Example :\n");
printf(" usage: rcvall -t -u -i -s:192.202.35.26 -d:192.202.35.37 -p:80 \n ");
printf(" -t attation Tcp Pack.\n");
printf(" -u attation Udp Pack.\n");
printf(" -i attation Icmp Pack.\n");
printf(" -s source ip address.\n");
printf(" -d dest ip address.\n");
printf(" -p: port");
ExitProcess (0);
}
/////////************************************************
// Validate arguments
void ValidateArgs(int argc, char **argv)
{
int i;
if(argc<2)
usage();
for( i=1;i<argc;i++)
{
if ((argv[i][0] == '-') ¦¦ (argv[i][0] == '/'))
{
switch(tolower(argv[i][1]))
{
case 't':
gParamTcp=TRUE;
break;
case 'u':
gParamUdp=TRUE;
break;
case 'i':
gParamIcmp=TRUE;
break;
case 's':
strcpy(gSourceIp,&argv[i][3]);
break;
case 'd':
strcpy(gDestIP,&argv[i][3]);
break;
case 'p':
gParamPort=atoi(&argv[i][3]);
break;
default:
usage();
}
}
else
{
usage();
}
}
}
//*****************************
// print some info
void printInfo()
{
printf("Created by lanbin .\n");
printf("E_mail:[email protected].\n");}
//**********************************
// GetHostIpadd
BOOL GetHostAddr(SOCKET s,SOCKADDR_IN *ifx,int num)
{
SOCKET_ADDRESS_LIST *slist=NULL;
char buf[2048];
DWORD dwBytesRet;
int ret; ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buf, 2048,
&dwBytesRet, NULL, NULL);
if (ret == SOCKET_ERROR)
{
printf("WSAIoctl(SIO_ADDRESS_LIST_QUERY) failed: %d\n",
WSAGetLastError());
return FALSE;
}
slist = (SOCKET_ADDRESS_LIST *)buf;
if (num >= slist->iAddressCount)
return FALSE;
ifx->sin_addr.s_addr = ((SOCKADDR_IN *)slist->Address[num].lpSockaddr)->sin_addr.s_addr;
return TRUE;
}
BOOL DecodeUdpPack(WSABUF *wsa,int offset)
{
BYTE *hdr=(BYTE*)(wsa->buf +offset);
struct _udphdr udphdr;
unsigned short shortval=0;
memcpy(&shortval,hdr,2);
udphdr.sport =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
udphdr.dport =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
udphdr.len =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
udphdr.checksum =ntohs(shortval);
//printf info
printf(" UDP HEADER \n");
printf("源端口 %-6d目的端口 %-6d\n",udphdr.sport ,udphdr.dport );
printf("长度 %-6d校验和 0x%-6d\n",udphdr.len ,udphdr.checksum );return TRUE;
}
//*****************************************
// Decode TCP Pack
BOOL DecodeTcpPack(WSABUF *wsa,int offset)
{
BYTE *hdr=(BYTE*)(wsa->buf +offset);
unsigned short shortval=0;
unsigned int longval=0;
struct _tcphdr tcphdr;
char *data=0;
memcpy(&shortval,hdr,2);
tcphdr.sport =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
tcphdr.dport =ntohs(shortval);
hdr+=2;
memcpy(&longval,hdr,4);
tcphdr.seq =ntohl(longval);
hdr+=4;
memcpy(&longval,hdr,4);
tcphdr.ackseq =ntohl(longval);
hdr+=4;
tcphdr.offsetlen =((*hdr)>>4 &0x0f)*4;
memcpy(&shortval,hdr,2);
shortval=ntohs(shortval);
tcphdr.flag =(shortval & 0x3f);
hdr+=2;
memcpy(&shortval,hdr,2);
tcphdr.win =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
tcphdr.checksum =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
tcphdr.urp =ntohs(shortval);
// printf tcp header
printf(" Tcp Header \n");
printf("源端口 %-6d 目的端口 %-6d\n",tcphdr.sport ,tcphdr.dport );
printf("序列号 0x%-6x 确认号 0x%-6x\n",tcphdr.seq ,tcphdr.ackseq );
printf("数据偏移量(Bytes) %-3d 标志位 %-6d 窗口 %-6d\n",tcphdr.offsetlen ,tcphdr.flag ,tcphdr.win );
printf("校验和 0x%-6x 紧急指针 %-6d\n",tcphdr.checksum ,tcphdr.urp );
//print tcp data
data=wsa->buf +offset+tcphdr.offsetlen ;
printf(data);
return TRUE;
}
//*******************************************************
//DECODE IP PACK
BOOL DecodeIpPacket(WSABUF *wsa)
{
SOCKADDR_IN srcaddr,
destaddr;
BYTE *hdr=(BYTE*)wsa->buf ;
BYTE *nexthdr=0;
unsigned short shortval=0;
unsigned short usSPort=0;
unsigned short usDPort=0;
IP_HEADER iphdr;
char szSource[16]={0};
char szDest[16]={0};
//获得ip header
iphdr.ver =(((*hdr)>>4) & 0x0f) ;
iphdr.len =((*hdr) & 0x0f)*4;
nexthdr=(BYTE*)(wsa->buf +iphdr.len);
hdr++;
iphdr.tos =*hdr;
hdr++;
memcpy(&shortval,hdr,2);
iphdr.total_len =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
iphdr.ident =ntohs(shortval);
hdr+=2;
iphdr.flags =(((*hdr)>>5) & 0x07);
memcpy(&shortval,hdr,2);
iphdr.fragment=(ntohs(shortval) & 0x1fff);
hdr+=2;
iphdr.ttl =*hdr;
hdr++;
iphdr.proto =*hdr;
hdr++;
memcpy(&shortval,hdr,2);
iphdr.checksum =ntohs(shortval);
hdr+=2;
memcpy(&srcaddr.sin_addr.s_addr, hdr, 4);
iphdr.sourceIP =ntohl(srcaddr.sin_addr.s_addr);
hdr+=4;
memcpy(&destaddr.sin_addr.s_addr, hdr, 4);
iphdr.destIP =ntohl(destaddr.sin_addr.s_addr);
//Filter ip
if(strlen(gSourceIp)>0 )
{
if(strcmp(gSourceIp,inet_ntoa(srcaddr.sin_addr))!=0)
return FALSE;
}
if(strlen(gDestIP)>0)
{
if(strcmp(gDestIP,inet_ntoa(destaddr.sin_addr ))!=0)
return FALSE;
}
/// filter port
if(gParamPort>0)
if(iphdr.proto ==2 ¦¦ iphdr.proto ==6 ¦¦ iphdr.proto ==17)
{
memcpy(&usSPort,nexthdr,2);
usSPort=ntohs(usSPort);
nexthdr+=2;
memcpy(&usDPort,nexthdr,2);
usDPort=ntohs(usDPort);
if(gParamPort!=usSPort && gParamPort!=usDPort)
return FALSE;
}
strcpy(szSource,inet_ntoa(srcaddr.sin_addr ));
strcpy(szDest,inet_ntoa(destaddr.sin_addr ));
//输出 ip header
printf("\n");
printf(" IP HEADER \n");
printf("版本号 %-6d报头长度(Bytes) %-6d服务类型 %-6d\n",iphdr.ver ,iphdr.len ,iphdr.tos );
printf("总长度 %-6d标知符 0x%-6x标志 %-6d\n",iphdr.total_len ,iphdr.ident,iphdr.flags );
printf("分段偏移量 %-6d生存时间 %-6d协议 %-6d\n",iphdr.fragment ,iphdr.ttl ,iphdr.proto );
printf("报头校验和 0x%-6x源地址 %s 目的地址 %s\n",iphdr.checksum ,szSource,szDest);
// 获得 协议
switch(iphdr.proto)
{
case 2://iGmp
break;
case 6://tcp
if(gParamTcp)
DecodeTcpPack(wsa,iphdr.len);
break;
case 17://udp
if(gParamUdp)
DecodeUdpPack(wsa,iphdr.len );
break;
default:
printf("No proto");
}
return TRUE;
}
//*************************************************]]
// MAIN
int main(int argc,char **argv)
{
WSADATA wsd;
SOCKET SocketRaw;
SOCKADDR_IN addr;
unsigned int optval=0;
DWORD dwBytesRet=0;
DWORD dwFlags=0;
WSABUF wsa={0,0};
char buffer[MAX_IP_SIZE]={0};
//Usage
ValidateArgs(argc,argv);
//init winsocket
if(WSAStartup(0x0202,&wsd)==SOCKET_ERROR)
{
printf("Init winsocket Error %d\n",WSAGetLastError());
return FALSE;
}
//printf user selection
printInfo();
//create socket
if((SocketRaw=WSASocket(AF_INET,SOCK_RAW,IPPROTO_IP,NULL,0,WSA_FLAG_OVERLAPPED))
==INVALID_SOCKET)
{
printf("create socket error %d.",WSAGetLastError());
return FALSE;
}
//得到本机的ip 地址
if(!GetHostAddr(SocketRaw,&addr,0))
{
return FALSE;
}
addr.sin_family =AF_INET;
addr.sin_port =htons(0);
if(bind(SocketRaw,(SOCKADDR*)&addr,sizeof(addr))==SOCKET_ERROR)
{
printf("bind socket Error %d.\n",WSAGetLastError());
return FALSE;
}
//set socket SIO_RCVALL
optval=1;
if(WSAIoctl (SocketRaw,SIO_RCVALL,&optval,sizeof(optval),
NULL,0,&dwBytesRet,0,0)==SOCKET_ERROR)
{
printf("WSAIoctl Error %d.\n",WSAGetLastError);
}
//recv ip pack
while(1)
{
memset(buffer,0,sizeof(buffer));
wsa.buf =buffer;
wsa.len =MAX_IP_SIZE;
dwFlags=0;
if(WSARecv(SocketRaw,&wsa,1,&dwBytesRet,&dwFlags,0,0)==SOCKET_ERROR)
{
printf("WSARecv Error %d \n",WSAGetLastError);
return FALSE;
}
DecodeIpPacket(&wsa);
}
closesocket(SocketRaw);
WSACleanup ();
return TRUE;
}
回复人: jetlan(不百) (2001-11-20 16:20:49) 得0分
要记的给分阿。:
回复人: jason802(小糊涂仙) (2001-11-22 9:06:49) 得0分 晕倒,楼上干吗??
--------------------------------------------------------------------------------
我要回复:(请您对您的言行负责,遵守中华人民共和国有关法律、法规,尊重网上道德)
如果你只是觉得这个贴子好,而没想留言的话,请点击后面的贴子提前连接。
返回问题 | 关闭窗口
美达美简介 广告服务 英语步步高 程序员大本营 百联美达美科技有限公司 版权所有
CSDN首页 | 新闻聚焦 | 共享软件 | 俱乐部 | 开发文档 | 专家门诊 | 招聘求职 | Linux园地 | 程序员杂志
--------------------------------------------------------------------------------
我要回复 | 我感兴趣 | 打印贴子 | 推荐给朋友 | 关闭窗口
主 题:有趣的问题!
作 者:nccpu
所属论坛:Visual C++
问题点数:30
回复次数:7
发表时间:2001-11-21 22:24:43
对话框中有两个按钮控件,其中一个控制一个循环的开始,另一个控制它的结束,该如何处理?
回复贴子:
回复人: Flysnow(飞雪) (2001-11-21 22:34:51) 得0分
最简单的方法,不用多线程设一个全局变量来决定循环,另一个按钮来控制全局变量的值好像就可以了不过这个循环可不要太快了,不然的话,可能系统都不能响应另一个按钮了咯
回复人: forrest9910(liaomaomao) (2001-11-22 8:17:12) 得0分
好像得用两个线程,用一个线程的话,循环内要读消息,比较费事。
回复人: jason802(小糊涂仙) (2001-11-22 8:42:12) 得0分
1。对于同一个对话框内的两个控件来说,永远不需要全局变量,一个成员变量搞定。
2。多县城太烦,其实这只是一个逻辑游戏。//发消息通知循环开始
void CMyDlg::OnButton1()
{
m_flag = 1;
PostMessage(WM_JASON,0,0);
return;
}//设置标志,让循环结束,不需要发消息
void CMyDlg::OnButton2()
{
m_flag = 0;
return;
}
void CMyDlg::Jason()
{
while(m_flag)
{
//todo
}
return;
}
回复人: dog_dog(狗狗) (2001-11-22 8:43:14) 得0分
study
回复人: jason802(小糊涂仙) (2001-11-22 8:49:35) 得0分
如果你思维定势,认定循环在OnButton1中进行,那么就很难得到答案,除非用一种很烂的方法:
设定一个变量,不能思维定势根据这个变量是0或者1来判断,而是这两个按纽都让这个变量加1,然后根据这个变量的奇偶来判断。之所以说这个方法烂是因为如果其中一个按纽连续按了两下,这两个按纽的作用就反过来了。
回复人: dongfa(阿东) (2001-11-22 9:01:17) 得0分
如果要循环的话,至少要开一个线程的,否则程序会无响应。
主 题:巨分相送!!回答出来者另开帖子送500分!
作 者:glooby
所属论坛:Visual C++
问题点数:59
回复次数:18
发表时间:2001-11-18 13:12:31
问题1, 如何写程序给某块网卡IP设置地址,当然不能重起
问题2, 如何写一个嗅探器,介绍关键步骤就行了
问题3, 如何发送一个数据链路层报文, 类型由我设定,比如1234。:)
当然, 要用windows编程!
回复贴子:
回复人: glooby(怪物点心) (2001-11-18 13:25:53) 得0分
连个UP的人都没有??
回复人: glooby(怪物点心) (2001-11-18 13:29:57) 得0分
问题1改为, 给一台机子分一个IP,该机子拿到IP后不需要重起就可以使用就行了!
回复人: glooby(怪物点心) (2001-11-18 13:31:13) 得0分
第一个问题用IP伪装行吗?? 该如何做呢??
回复人: pitchstar(一站) (2001-11-18 13:40:05) 得0分
问题 1:用这个 api GetAdaptersInfo(),他返回好象是一个链表,每个节点代表一个卡。
问题 2:需要 ndis 驱动,不懂
问题 3:ip 伪装是比较复杂的技术,而且有运气的成分,给一篇文章:http://www.csdn.net/develop/read_article.asp?id=9343回复人: glooby(怪物点心) (2001-11-18 20:04:59) 得0分
我是要设置IP, 不是得到适配器的信息。
回复人: pitchstar(一站) (2001-11-19 9:54:35) 得0分
设置 ip 不知道,但你用原始套接字可以以任何地址给人发包,但却收不到,如果在局域网可以通过监听以太网帧收到回复的包,但基本没多大意义,自己维护协议是很复杂的UDP 还好说点
回复人: whz_time(时间) (2001-11-19 10:09:44) 得0分
对于问题 2:我这有一段代码,但还有问题,我们可以一起研究一下:// tcp.cpp : Defines the entry point for the console application.
//
#include "stdlib.h"
#include <stdio.h>
#include "winsock2.h"
#include "IPHlpApi.h"
#include "mstcpip.h"
#include "errno.h"
#include "conio.h"//#include "rcv_.h"void init(void);
void GetProtocol(int num, char *str);
void recv_icmp(char *host, int sockfd);
void handle_icmp(char *buf);
void getippak(int SockRaw);/////////////////////////////////////////////////////////typedef struct _PROTN2T
{
int proto ;
char *pprototext ;
}PROTN2T ; /////////////////////////////////////////////////////////
typedef struct _IPHEADER {
unsigned char header_len:4;
unsigned char version:4;
unsigned char tos; // type of service
unsigned short total_len; // length of the packet
unsigned short ident; // unique identifier
unsigned short flags;
unsigned char ttl;
unsigned char proto; // protocol ( IP , TCP, UDP etc)
unsigned short checksum;
unsigned int sourceIP;
unsigned int destIP;}IPHEADER;//////////////////////////////////////////////////////////////int main(int argc, char* argv[])//
{
char *host_="localhost";
int sockfd;
init();
sockfd=socket(AF_INET,SOCK_RAW,IPPROTO_IP);//IPPROTO_IP);
if(sockfd<0)
{
printf("socket error->%s\n",strerror(errno));
exit(1);
}
getippak(sockfd);recv_icmp(host_,sockfd);return(0);
}///////////////////////////////////////////////////////
void init(void)
{
WORD wVersion;
WSADATA wsaData;
int err;
wVersion=MAKEWORD(2,0);
err=WSAStartup(wVersion,&wsaData);
if(err!=0)
exit(1);}
///////////////////////////////////////////////////////
void GetProtocol(int num_, char *str_)
{switch(num_)
{
case 0: str_="IP";
break;
case 1: str_="ICMP";
break;
case 2: str_="IGMP";
break;
case 3: str_="GGP";
break;
case 6: str_="TCP";
break;
case 12: str_="PUP";
break;
case 17: str_="UDP";
break;
case 22: str_="IDP";
break;
case 77: str_="ND";
break;
case 255: str_="RAW";
break;
default: str_="MAX";
break;
}
}///////////////////////////////////////////////////////
void recv_icmp(char *host, int sockfd)
{
char recvbuf[1024],*bufwork;
char *pSource,*pDest;
IPHEADER *pIpHeader;
in_addr ina;
char szSource [16] , szDest[16];// szErr [ 50 ];
char *pLastBuf = NULL ;char *str,*temp;
// int len;
int n;
//long count=0;
for(;;)
{
memset(szSource,0,sizeof(szSource));
memset(szDest,0,sizeof(szDest));
memset(recvbuf,0,sizeof(recvbuf));
n=recvfrom(sockfd,recvbuf,sizeof(recvbuf),0,NULL,NULL);
// GetLastError();
// MessageBox(NULL,(char *)GetLastError(),"",0);
if(n<0)
{
if(errno==EINTR)
continue;
else
{
printf("Recvfrom Error n=%d\n",n);
printf("%s\n",recvbuf);
Sleep(1000);
continue;
}//else
continue;} //if
// iRet = recv(pDlg->m_s, buf , sizeof( buf ) , 0 ) ;
// putch('x');
// getch();
if(*recvbuf)
{
bufwork = recvbuf ;
pIpHeader = (IPHEADER *)bufwork ;
WORD iLen = ntohs(pIpHeader->total_len) ;
ina.S_un.S_addr = pIpHeader->sourceIP ;
pSource =inet_ntoa( ina ) ;
strcpy( szSource , pSource ) ;
// str.Format("Source IP: %s, ",szSource);
sprintf(str,"Source IP: %s, ",szSource);ina.S_un.S_addr = pIpHeader->destIP ;
pDest = inet_ntoa( ina ) ;
strcpy( szDest , pDest ) ;
// temp.Format("Dest IP: %s, Protocol: ",szDest);
sprintf(temp,"Dest IP: %s, Protocol: ",szDest);
// str+=temp;
strcat(str,temp);
int test=pIpHeader->total_len;int num=pIpHeader->proto;
GetProtocol(num, temp);
// str+=temp;
strcat(str,temp);// temp.Format (",%d,%d",buf[20]*256+buf[21],buf[22]*256+buf[23]);
sprintf(temp,",%d,%d",recvbuf[20]*256+recvbuf[21],recvbuf[22]*256+recvbuf[23]);// str+=temp;
strcat(str,temp);
printf("getippak is:%s",str);
// pDlg->m_ctlPort.InsertItem(0,str);
// handle_icmp(recvbuf);
}//if
}//for}
/////////////////////////////////////////////////////////void recv_icmp(char *host, int sockfd)
//{
//char recvbuf[512];
// int len;
//int n;
//long count=0;
//for(;;)
//{
//memset(recvbuf,0,sizeof(recvbuf));
//n=recvfrom(sockfd,recvbuf,sizeof(recvbuf),0,NULL,NULL);
////GetLastError();
///MessageBox(NULL,(char *)GetLastError(),"",0);
//if(n<0)
// {
// if(errno==EINTR) continue;
// else
// {
// printf("Recvfrom Error n=%d\n",n);
// printf("%s\n",recvbuf);
// Sleep(1000);
// continue;
// }
// }
//handle_icmp(recvbuf);
//}
//} /////////////////////////////////////////////////////////void handle_icmp(char *buf)
//{
//// struct ip *ip;
//// ip=(struct ip*)buf;
//// printf("IP:%ld\n",ip->ip_src.s_addr);
//printf("Get--->%s",buf);
//}///////////////////////////////////////////////////////////////void getippak(int SockRaw)
{
#define SIO_RCVALL _WSAIOW(IOC_VENDOR,1) //初始化SOCKET
#define MAX_HOSTNAME_LAN 256// WSADATA wsaData;
int iErrorCode;//iErrorCode = WSAStartup(MAKEWORD(2,1),&wsaData);
//CheckSockError(iErrorCode, "WSAStartup");
//SockRaw = socket(AF_INET , SOCK_RAW , IPPROTO_IP);
//CheckSockError(SockRaw, "socket");
//获取本机IP地址
char FAR name[MAX_HOSTNAME_LAN];
iErrorCode = gethostname(name, MAX_HOSTNAME_LAN);
//CheckSockError(iErrorCode, "gethostname");
struct hostent FAR * pHostent;
pHostent = gethostbyname(name);
SOCKADDR_IN sa;
sa.sin_family = AF_INET;
sa.sin_port = htons(80);//6000);
memcpy(&sa.sin_addr.S_un.S_addr, pHostent->h_addr_list[0], pHostent->h_length);
iErrorCode = bind(SockRaw, (PSOCKADDR)&sa, sizeof(sa));//设置SOCK_RAW为SIO_RCVALL,以便接收所有的IP包DWORD dwBufferLen[10] ;
DWORD dwBufferInLen = 1 ;
DWORD dwBytesReturned = 0 ;
iErrorCode=WSAIoctl(SockRaw, SIO_RCVALL,&dwBufferInLen, sizeof(dwBufferInLen),&dwBufferLen, sizeof(dwBufferLen),&dwBytesReturned , NULL , NULL );}/////////////////////////////////////////////////////////////////////////////回复人: pitchstar(一站) (2001-11-19 10:18:45) 得0分
老兄,我先问你个问题:已经发出去的帖子还可以改吗?我看你好象把第一帖改过了?怎么做到的?
回复人: cntiger(硕虎) (2001-11-19 10:31:23) 得0分
windows中设置ip需要重起,涉及到windows的最底层调用,还涉及到ip协议的上下层的三层。
成功的可能性较小。
回复人: whz_time(时间) (2001-11-19 10:32:32) 得0分
大伙都一起来讨论讨论嘛,我想听听各位高手的意见。回复人: glooby(怪物点心) (2001-11-19 14:18:52) 得0分
to pitchstar(一站): 我没有改过呀,我已经在unix上实现了一个链路层协议,现在是要作一个windows的客户端,又不会作内核编程,所以才想出用嗅探的方法,(可以有机子作arp代理的)
to whz_time(时间): 我是要发送数据链路层包,用rawsocket不行的:)
to cntiger(硕虎): 改动windows98以下系统的注册表或是系统信息都要重起的,2k就好了:), 可是我想问有没有不用重起的办法,比如ip alias, 直接修改内核数据结构,或者有没有什么后门:), 好像真的是有的:)我知道可以用DDK实现嗅探和发包, 可是如何做呢?? 我很少作windows编程的,情各位高手多帮帮忙:)
回复人: pitchstar(一站) (2001-11-19 14:57:20) 得0分
windows 下要抓以太帧,可能需要做 ndis 驱动,你看这里有没有资料
http://www.driverdevelop.com
回复人: glooby(怪物点心) (2001-11-20 12:47:53) 得0分
那个winpcap如何呢?? 有没有人用过??
回复人: glooby(怪物点心) (2001-11-20 15:53:51) 得0分
各位高手帮帮忙了!!:)
回复人: DeadWolf(死狼) (2001-11-20 16:04:09) 得0分
旁听
回复人: jetlan(不百) (2001-11-20 16:19:23) 得0分
对于问题1:可用IpRenewAddress 函数。
问题2:本人用c写了一个rcvall的程序,可以得到网络中的ip数据包。还解了tcp 和udp报。
原代码:
rcvall.h //**************************************************************************************
// filename: rcvall.h
// author : lan bin
// company : smaple
// E_mail : [email protected]
// description: Tcp Ip ICMP 头定义
//*****************************************************************************************
typedef struct _iphdr
{
unsigned short ver, //4位IP版本号
len, //4位首部长度
tos, //8位服务类型TOS
total_len, //16位总长度(字节)
ident, //16位标识
flags, //3位标志位
fragment,//13偏远量
ttl, //8位生存时间 TTL
proto, //8位协议 (TCP, UDP 或其他)
checksum;//16位IP首部校验和
unsigned int sourceIP; //32位源IP地址
unsigned int destIP; //32位目的IP地址
}IP_HEADER;typedef struct _tcphdr //定义TCP首部
{
unsigned short sport; //16位源端口
unsigned short dport; //16位目的端口
unsigned int seq; //32位序列号
unsigned int ackseq; //32位确认号
unsigned short offsetlen; //4位首部长度
unsigned short reserve;//6位保留字
unsigned short flag; //6位标志位
unsigned short win; //16位窗口大小
unsigned short checksum; //16位校验和
unsigned short urp; //16位紧急数据偏移量
}TCP_HEADER;typedef struct _udphdr //定义UDP首部
{
unsigned short sport; //16位源端口
unsigned short dport;//16位目的端口
unsigned short len; //16位长度
unsigned short checksum;//16位校验和
} UDP_HEADER;typedef struct _icmphdr //定义ICMP首部
{
BYTE type;//8位类型
BYTE code; //8位代码
unsigned short checksum; //16位校验和
unsigned short id; //识别号(一般用进程号作为识别号)
unsigned short seq; //报文序列号
ULONG timestamp; //时间戳
}ICMP_HEADER;
typedef struct _ipoptionhdr
{
unsigned char code; // Option type
unsigned char len; // Length of option hdr
unsigned char ptr; // Offset into options
unsigned long addr[9]; // List of IP addrs
} IPOPTIONHEADER;
#define MAX_ADDR_LEN 15 //点分制的最大长度
#define MAX_IP_SIZE 65535
#define MIN_IP_HDR_SIZE 20
rcvall.c
//**************************************************************************************
// filename: rcvall.c
// author : lan bin
// company : smaple
// E_mail : [email protected]
// description: Tcp Ip ICMP 实现
//*****************************************************************************************#include <winsock2.h>
#include <stdio.h>
#include "mstcpip.h"
#include "rcvall.h"
#pragma comment(lib,"ws2_32.lib")
//********* 全局变量定义********************
BOOL gParamTcp=FALSE;//关心TCP
BOOL gParamUdp=FALSE;//关心UDP
BOOL gParamIcmp=FALSE;//关心Icmp
char gSourceIp[MAX_ADDR_LEN+1]={0};//过滤源ip
char gDestIP[MAX_ADDR_LEN+1]={0}; //过滤目的ip
unsigned short gParamPort=0;
//************************************************
// usage
void usage()
{
printf("Example :\n");
printf(" usage: rcvall -t -u -i -s:192.202.35.26 -d:192.202.35.37 -p:80 \n ");
printf(" -t attation Tcp Pack.\n");
printf(" -u attation Udp Pack.\n");
printf(" -i attation Icmp Pack.\n");
printf(" -s source ip address.\n");
printf(" -d dest ip address.\n");
printf(" -p: port");
ExitProcess (0);
}
/////////************************************************
// Validate arguments
void ValidateArgs(int argc, char **argv)
{
int i;
if(argc<2)
usage();
for( i=1;i<argc;i++)
{
if ((argv[i][0] == '-') ¦¦ (argv[i][0] == '/'))
{
switch(tolower(argv[i][1]))
{
case 't':
gParamTcp=TRUE;
break;
case 'u':
gParamUdp=TRUE;
break;
case 'i':
gParamIcmp=TRUE;
break;
case 's':
strcpy(gSourceIp,&argv[i][3]);
break;
case 'd':
strcpy(gDestIP,&argv[i][3]);
break;
case 'p':
gParamPort=atoi(&argv[i][3]);
break;
default:
usage();
}
}
else
{
usage();
}
}
}
//*****************************
// print some info
void printInfo()
{
printf("Created by lanbin .\n");
printf("E_mail:[email protected].\n");}
//**********************************
// GetHostIpadd
BOOL GetHostAddr(SOCKET s,SOCKADDR_IN *ifx,int num)
{
SOCKET_ADDRESS_LIST *slist=NULL;
char buf[2048];
DWORD dwBytesRet;
int ret; ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buf, 2048,
&dwBytesRet, NULL, NULL);
if (ret == SOCKET_ERROR)
{
printf("WSAIoctl(SIO_ADDRESS_LIST_QUERY) failed: %d\n",
WSAGetLastError());
return FALSE;
}
slist = (SOCKET_ADDRESS_LIST *)buf;
if (num >= slist->iAddressCount)
return FALSE;
ifx->sin_addr.s_addr = ((SOCKADDR_IN *)slist->Address[num].lpSockaddr)->sin_addr.s_addr;
return TRUE;
}
BOOL DecodeUdpPack(WSABUF *wsa,int offset)
{
BYTE *hdr=(BYTE*)(wsa->buf +offset);
struct _udphdr udphdr;
unsigned short shortval=0;
memcpy(&shortval,hdr,2);
udphdr.sport =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
udphdr.dport =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
udphdr.len =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
udphdr.checksum =ntohs(shortval);
//printf info
printf(" UDP HEADER \n");
printf("源端口 %-6d目的端口 %-6d\n",udphdr.sport ,udphdr.dport );
printf("长度 %-6d校验和 0x%-6d\n",udphdr.len ,udphdr.checksum );return TRUE;
}
//*****************************************
// Decode TCP Pack
BOOL DecodeTcpPack(WSABUF *wsa,int offset)
{
BYTE *hdr=(BYTE*)(wsa->buf +offset);
unsigned short shortval=0;
unsigned int longval=0;
struct _tcphdr tcphdr;
char *data=0;
memcpy(&shortval,hdr,2);
tcphdr.sport =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
tcphdr.dport =ntohs(shortval);
hdr+=2;
memcpy(&longval,hdr,4);
tcphdr.seq =ntohl(longval);
hdr+=4;
memcpy(&longval,hdr,4);
tcphdr.ackseq =ntohl(longval);
hdr+=4;
tcphdr.offsetlen =((*hdr)>>4 &0x0f)*4;
memcpy(&shortval,hdr,2);
shortval=ntohs(shortval);
tcphdr.flag =(shortval & 0x3f);
hdr+=2;
memcpy(&shortval,hdr,2);
tcphdr.win =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
tcphdr.checksum =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
tcphdr.urp =ntohs(shortval);
// printf tcp header
printf(" Tcp Header \n");
printf("源端口 %-6d 目的端口 %-6d\n",tcphdr.sport ,tcphdr.dport );
printf("序列号 0x%-6x 确认号 0x%-6x\n",tcphdr.seq ,tcphdr.ackseq );
printf("数据偏移量(Bytes) %-3d 标志位 %-6d 窗口 %-6d\n",tcphdr.offsetlen ,tcphdr.flag ,tcphdr.win );
printf("校验和 0x%-6x 紧急指针 %-6d\n",tcphdr.checksum ,tcphdr.urp );
//print tcp data
data=wsa->buf +offset+tcphdr.offsetlen ;
printf(data);
return TRUE;
}
//*******************************************************
//DECODE IP PACK
BOOL DecodeIpPacket(WSABUF *wsa)
{
SOCKADDR_IN srcaddr,
destaddr;
BYTE *hdr=(BYTE*)wsa->buf ;
BYTE *nexthdr=0;
unsigned short shortval=0;
unsigned short usSPort=0;
unsigned short usDPort=0;
IP_HEADER iphdr;
char szSource[16]={0};
char szDest[16]={0};
//获得ip header
iphdr.ver =(((*hdr)>>4) & 0x0f) ;
iphdr.len =((*hdr) & 0x0f)*4;
nexthdr=(BYTE*)(wsa->buf +iphdr.len);
hdr++;
iphdr.tos =*hdr;
hdr++;
memcpy(&shortval,hdr,2);
iphdr.total_len =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
iphdr.ident =ntohs(shortval);
hdr+=2;
iphdr.flags =(((*hdr)>>5) & 0x07);
memcpy(&shortval,hdr,2);
iphdr.fragment=(ntohs(shortval) & 0x1fff);
hdr+=2;
iphdr.ttl =*hdr;
hdr++;
iphdr.proto =*hdr;
hdr++;
memcpy(&shortval,hdr,2);
iphdr.checksum =ntohs(shortval);
hdr+=2;
memcpy(&srcaddr.sin_addr.s_addr, hdr, 4);
iphdr.sourceIP =ntohl(srcaddr.sin_addr.s_addr);
hdr+=4;
memcpy(&destaddr.sin_addr.s_addr, hdr, 4);
iphdr.destIP =ntohl(destaddr.sin_addr.s_addr);
//Filter ip
if(strlen(gSourceIp)>0 )
{
if(strcmp(gSourceIp,inet_ntoa(srcaddr.sin_addr))!=0)
return FALSE;
}
if(strlen(gDestIP)>0)
{
if(strcmp(gDestIP,inet_ntoa(destaddr.sin_addr ))!=0)
return FALSE;
}
/// filter port
if(gParamPort>0)
if(iphdr.proto ==2 ¦¦ iphdr.proto ==6 ¦¦ iphdr.proto ==17)
{
memcpy(&usSPort,nexthdr,2);
usSPort=ntohs(usSPort);
nexthdr+=2;
memcpy(&usDPort,nexthdr,2);
usDPort=ntohs(usDPort);
if(gParamPort!=usSPort && gParamPort!=usDPort)
return FALSE;
}
strcpy(szSource,inet_ntoa(srcaddr.sin_addr ));
strcpy(szDest,inet_ntoa(destaddr.sin_addr ));
//输出 ip header
printf("\n");
printf(" IP HEADER \n");
printf("版本号 %-6d报头长度(Bytes) %-6d服务类型 %-6d\n",iphdr.ver ,iphdr.len ,iphdr.tos );
printf("总长度 %-6d标知符 0x%-6x标志 %-6d\n",iphdr.total_len ,iphdr.ident,iphdr.flags );
printf("分段偏移量 %-6d生存时间 %-6d协议 %-6d\n",iphdr.fragment ,iphdr.ttl ,iphdr.proto );
printf("报头校验和 0x%-6x源地址 %s 目的地址 %s\n",iphdr.checksum ,szSource,szDest);
// 获得 协议
switch(iphdr.proto)
{
case 2://iGmp
break;
case 6://tcp
if(gParamTcp)
DecodeTcpPack(wsa,iphdr.len);
break;
case 17://udp
if(gParamUdp)
DecodeUdpPack(wsa,iphdr.len );
break;
default:
printf("No proto");
}
return TRUE;
}
//*************************************************]]
// MAIN
int main(int argc,char **argv)
{
WSADATA wsd;
SOCKET SocketRaw;
SOCKADDR_IN addr;
unsigned int optval=0;
DWORD dwBytesRet=0;
DWORD dwFlags=0;
WSABUF wsa={0,0};
char buffer[MAX_IP_SIZE]={0};
//Usage
ValidateArgs(argc,argv);
//init winsocket
if(WSAStartup(0x0202,&wsd)==SOCKET_ERROR)
{
printf("Init winsocket Error %d\n",WSAGetLastError());
return FALSE;
}
//printf user selection
printInfo();
//create socket
if((SocketRaw=WSASocket(AF_INET,SOCK_RAW,IPPROTO_IP,NULL,0,WSA_FLAG_OVERLAPPED))
==INVALID_SOCKET)
{
printf("create socket error %d.",WSAGetLastError());
return FALSE;
}
//得到本机的ip 地址
if(!GetHostAddr(SocketRaw,&addr,0))
{
return FALSE;
}
addr.sin_family =AF_INET;
addr.sin_port =htons(0);
if(bind(SocketRaw,(SOCKADDR*)&addr,sizeof(addr))==SOCKET_ERROR)
{
printf("bind socket Error %d.\n",WSAGetLastError());
return FALSE;
}
//set socket SIO_RCVALL
optval=1;
if(WSAIoctl (SocketRaw,SIO_RCVALL,&optval,sizeof(optval),
NULL,0,&dwBytesRet,0,0)==SOCKET_ERROR)
{
printf("WSAIoctl Error %d.\n",WSAGetLastError);
}
//recv ip pack
while(1)
{
memset(buffer,0,sizeof(buffer));
wsa.buf =buffer;
wsa.len =MAX_IP_SIZE;
dwFlags=0;
if(WSARecv(SocketRaw,&wsa,1,&dwBytesRet,&dwFlags,0,0)==SOCKET_ERROR)
{
printf("WSARecv Error %d \n",WSAGetLastError);
return FALSE;
}
DecodeIpPacket(&wsa);
}
closesocket(SocketRaw);
WSACleanup ();
return TRUE;
}
回复人: jetlan(不百) (2001-11-20 16:19:47) 得0分
对于问题1:可用IpRenewAddress 函数。
问题2:本人用c写了一个rcvall的程序,可以得到网络中的ip数据包。还解了tcp 和udp报。
原代码:
rcvall.h //**************************************************************************************
// filename: rcvall.h
// author : lan bin
// company : smaple
// E_mail : [email protected]
// description: Tcp Ip ICMP 头定义
//*****************************************************************************************
typedef struct _iphdr
{
unsigned short ver, //4位IP版本号
len, //4位首部长度
tos, //8位服务类型TOS
total_len, //16位总长度(字节)
ident, //16位标识
flags, //3位标志位
fragment,//13偏远量
ttl, //8位生存时间 TTL
proto, //8位协议 (TCP, UDP 或其他)
checksum;//16位IP首部校验和
unsigned int sourceIP; //32位源IP地址
unsigned int destIP; //32位目的IP地址
}IP_HEADER;typedef struct _tcphdr //定义TCP首部
{
unsigned short sport; //16位源端口
unsigned short dport; //16位目的端口
unsigned int seq; //32位序列号
unsigned int ackseq; //32位确认号
unsigned short offsetlen; //4位首部长度
unsigned short reserve;//6位保留字
unsigned short flag; //6位标志位
unsigned short win; //16位窗口大小
unsigned short checksum; //16位校验和
unsigned short urp; //16位紧急数据偏移量
}TCP_HEADER;typedef struct _udphdr //定义UDP首部
{
unsigned short sport; //16位源端口
unsigned short dport;//16位目的端口
unsigned short len; //16位长度
unsigned short checksum;//16位校验和
} UDP_HEADER;typedef struct _icmphdr //定义ICMP首部
{
BYTE type;//8位类型
BYTE code; //8位代码
unsigned short checksum; //16位校验和
unsigned short id; //识别号(一般用进程号作为识别号)
unsigned short seq; //报文序列号
ULONG timestamp; //时间戳
}ICMP_HEADER;
typedef struct _ipoptionhdr
{
unsigned char code; // Option type
unsigned char len; // Length of option hdr
unsigned char ptr; // Offset into options
unsigned long addr[9]; // List of IP addrs
} IPOPTIONHEADER;
#define MAX_ADDR_LEN 15 //点分制的最大长度
#define MAX_IP_SIZE 65535
#define MIN_IP_HDR_SIZE 20
rcvall.c
//**************************************************************************************
// filename: rcvall.c
// author : lan bin
// company : smaple
// E_mail : [email protected]
// description: Tcp Ip ICMP 实现
//*****************************************************************************************#include <winsock2.h>
#include <stdio.h>
#include "mstcpip.h"
#include "rcvall.h"
#pragma comment(lib,"ws2_32.lib")
//********* 全局变量定义********************
BOOL gParamTcp=FALSE;//关心TCP
BOOL gParamUdp=FALSE;//关心UDP
BOOL gParamIcmp=FALSE;//关心Icmp
char gSourceIp[MAX_ADDR_LEN+1]={0};//过滤源ip
char gDestIP[MAX_ADDR_LEN+1]={0}; //过滤目的ip
unsigned short gParamPort=0;
//************************************************
// usage
void usage()
{
printf("Example :\n");
printf(" usage: rcvall -t -u -i -s:192.202.35.26 -d:192.202.35.37 -p:80 \n ");
printf(" -t attation Tcp Pack.\n");
printf(" -u attation Udp Pack.\n");
printf(" -i attation Icmp Pack.\n");
printf(" -s source ip address.\n");
printf(" -d dest ip address.\n");
printf(" -p: port");
ExitProcess (0);
}
/////////************************************************
// Validate arguments
void ValidateArgs(int argc, char **argv)
{
int i;
if(argc<2)
usage();
for( i=1;i<argc;i++)
{
if ((argv[i][0] == '-') ¦¦ (argv[i][0] == '/'))
{
switch(tolower(argv[i][1]))
{
case 't':
gParamTcp=TRUE;
break;
case 'u':
gParamUdp=TRUE;
break;
case 'i':
gParamIcmp=TRUE;
break;
case 's':
strcpy(gSourceIp,&argv[i][3]);
break;
case 'd':
strcpy(gDestIP,&argv[i][3]);
break;
case 'p':
gParamPort=atoi(&argv[i][3]);
break;
default:
usage();
}
}
else
{
usage();
}
}
}
//*****************************
// print some info
void printInfo()
{
printf("Created by lanbin .\n");
printf("E_mail:[email protected].\n");}
//**********************************
// GetHostIpadd
BOOL GetHostAddr(SOCKET s,SOCKADDR_IN *ifx,int num)
{
SOCKET_ADDRESS_LIST *slist=NULL;
char buf[2048];
DWORD dwBytesRet;
int ret; ret = WSAIoctl(s, SIO_ADDRESS_LIST_QUERY, NULL, 0, buf, 2048,
&dwBytesRet, NULL, NULL);
if (ret == SOCKET_ERROR)
{
printf("WSAIoctl(SIO_ADDRESS_LIST_QUERY) failed: %d\n",
WSAGetLastError());
return FALSE;
}
slist = (SOCKET_ADDRESS_LIST *)buf;
if (num >= slist->iAddressCount)
return FALSE;
ifx->sin_addr.s_addr = ((SOCKADDR_IN *)slist->Address[num].lpSockaddr)->sin_addr.s_addr;
return TRUE;
}
BOOL DecodeUdpPack(WSABUF *wsa,int offset)
{
BYTE *hdr=(BYTE*)(wsa->buf +offset);
struct _udphdr udphdr;
unsigned short shortval=0;
memcpy(&shortval,hdr,2);
udphdr.sport =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
udphdr.dport =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
udphdr.len =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
udphdr.checksum =ntohs(shortval);
//printf info
printf(" UDP HEADER \n");
printf("源端口 %-6d目的端口 %-6d\n",udphdr.sport ,udphdr.dport );
printf("长度 %-6d校验和 0x%-6d\n",udphdr.len ,udphdr.checksum );return TRUE;
}
//*****************************************
// Decode TCP Pack
BOOL DecodeTcpPack(WSABUF *wsa,int offset)
{
BYTE *hdr=(BYTE*)(wsa->buf +offset);
unsigned short shortval=0;
unsigned int longval=0;
struct _tcphdr tcphdr;
char *data=0;
memcpy(&shortval,hdr,2);
tcphdr.sport =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
tcphdr.dport =ntohs(shortval);
hdr+=2;
memcpy(&longval,hdr,4);
tcphdr.seq =ntohl(longval);
hdr+=4;
memcpy(&longval,hdr,4);
tcphdr.ackseq =ntohl(longval);
hdr+=4;
tcphdr.offsetlen =((*hdr)>>4 &0x0f)*4;
memcpy(&shortval,hdr,2);
shortval=ntohs(shortval);
tcphdr.flag =(shortval & 0x3f);
hdr+=2;
memcpy(&shortval,hdr,2);
tcphdr.win =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
tcphdr.checksum =ntohs(shortval);
hdr+=2;
memcpy(&shortval,hdr,2);
tcphdr.urp =ntohs(shortval);
// printf tcp header
printf(" Tcp Header \n");
printf("源端口 %-6d 目的端口 %-6d\n",tcphdr.sport ,tcphdr.dport );
printf("序列号 0x%-6x 确认号 0x%-6x\n",tcphdr.seq ,tcphdr.ackseq );
printf("数据偏移量(Bytes) %-3d 标志位 %-6d 窗口 %-6d\n",tcphdr.offsetlen ,tcphdr.flag ,tcphdr.win );
printf("校验和 0x%-6x 紧急指