救命啊:我要在win95&win98&win2000上实现对ip包得过滤,请问有哪些方法可以?采用Ndis or DDK获得网卡的所有通讯包并进行过滤是否可以? 因本人对这问题搞了很久不得其解。如哪位知道,哪怕是相关信息都可告诉我,本人定会感激不尽!

tanwanyuan 2001-11-21 07:35:12
本人要实现一防火墙功能,如对进入或出去的包进行过滤,并可在win95&win98&win2000上都可运行实现.请问有哪些方法可以?采用那种方法好些?
有实现这方面的资料吗?
采用Ndis or DDK获得网卡的所有通讯包,并进行过滤是否可达到我的目标?
但我对Ndis根本不熟,有没有这方面的书籍或资料参考?
谢谢先!
...全文
195 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
likevclinux 2001-12-21
  • 打赏
  • 举报
回复
http://bbs.whnet.edu.cn
上面有你要的东西,而且高手如云
chenm001 2001-12-21
  • 打赏
  • 举报
回复
如果有结果请通知我,谢谢!
chenm003@cmmail.com
tanwanyuan 2001-11-26
  • 打赏
  • 举报
回复
近段我忙于查找这方面资料及初步代码的实现.差点给忘记了!
感谢各位高手的回复.不过好象问题并没有得到解决,还得讨论、研究、请教各位.
to dongfa(阿东):
感谢你把自己的心得及代码都奉现出来,在下实在感激不尽.也收获甚多.
raw socket可以获取网络层的数据包,但不能获取链路层数据包,且只可在NT&W2000中实现,在W98&W95中raw socket却未能获取及过滤.
to BlueLight(量子妖):
我也知晓DDK及Ndis可以实现,但小第实在对DDK不太熟,又要在极段的时间內交差.所以你若有时间可以的话呢,可否给出再详细的提示,比如:例子.
----------------------------------------
本人看过也研究过:
1、window环境:windump 和wpcap的实现原理和方法(http://netgroup-serv.polito.it/netgroup/tools.html).但因其牵涉底层性的原因直今没有找到一适合自己的一中实现方法.
2、linux环境:ipchain与內核、tcpdump 和libcap的实现原理及方法.因linux最可贵的是Free故本人可以随时找到相应的实现代码及內核实现代码,总算可以明白其大概.
我想window与linux的原理实现和实现方法应该一制,RAW sock及SOCK_PACKET绝对可在linux下实现,且RAW sock也可在w2000&NT实现,但如在w95&w98就不行了!
-------------------------------------------------------------------------
要求:
而我现在要实现一IP包过滤的简单防火墙,又可在W95&W98&W2000都可以实现.RAW SOCK就派不上用场了.
问题:
我剩下的问题是利用DDK&Ndis 或windump&wpcap中的pcap.dll&packet32.dll
1、怎样获取IP包?
2、怎样分析IP包?
3、获取、分析后怎样处理IP包?怎样写IP&UDP&TCP&ICMP包头进行回复?(处理包括:1、ACCEPT,2、FORWARD,3、REJECT,4、DENY.写IP&UDP&TCP&ICMP包头)

最后如各位有提示代码,联系:
lltxyz@trumptech.com.cn lltxyz@21cn.com
本人衷心感谢!
BlueLight 2001-11-22
  • 打赏
  • 举报
回复
DDK中有现成的例子可用!
dongfa 2001-11-22
  • 打赏
  • 举报
回复
原来有过一个贴子的。我给你copy上来:
主  题:巨分相送!!回答出来者另开帖子送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 : lb@sample.ia.ac.cn
// 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 : lb@sample.ia.ac.cn
// 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:lanbincn@263.net.\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 : lb@sample.ia.ac.cn
// 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 : lb@sample.ia.ac.cn
// 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:lanbincn@263.net.\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分
要记的给分阿。:

coolworm2000 2001-11-22
  • 打赏
  • 举报
回复
去Codeguru看一看吧,国内的程序员很保守的,有一点东西都藏得跟宝贝似地,不可能给你的,防火墙之类的软件现在正是火者呢,你相会有人告诉你吗?我也不会,但我从不期望能在国内的论坛上得道什么,
tanwanyuan 2001-11-21
  • 打赏
  • 举报
回复
各为大侠!
小第有难于此,有钱的出钱,有力的出力。
小第感激万分!
tvia_zgc 2001-11-21
  • 打赏
  • 举报
回复
真的很同情你,可我也不会!加油努力吧!

16,551

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Creator Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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