一个实现伪IP的例子(欢迎讨论,分儿多多)

wx_zzm 2002-05-28 12:02:09
下面的例子编译通过,WIN2000下执行OK,但在win98下执行不通
报告“fail to set sock option2.10042”--即非法参数

请问:有没有办法在WIN98下实现同样功能?



#include <stdio.h>
#include <winsock2.h>
#include <ws2tcpip.h>

#define ICMP_ECHO 8

typedef struct iphdr {
unsigned char verlen; // length and version of the header
unsigned char tos; // Type of service
unsigned short total_len; // total length of the packet
unsigned short ident; // unique identifier
unsigned short frag_and_flags; // flags
unsigned char ttl;
unsigned char proto; // protocol (TCP, UDP etc)
unsigned short checksum; // IP checksum
unsigned int sourceIP;
unsigned int destIP;

} IPHDR;

typedef struct icmphdr {
BYTE i_type;
BYTE i_code; // type sub code
USHORT i_cksum;
USHORT i_id;
USHORT i_seq;

} ICMPHDR;

unsigned short cal_checksum( unsigned short *buf, int size);

void main()
{
SOCKET s;
WSADATA WSAData;
BOOL bIphdrIncl;
int iRtn;
IPHDR *pIphdr;
ICMPHDR *pIcmphdr;
unsigned long *pIcmpdata;
char buf[1024];
struct sockaddr_in dest;

int ttl=255;

if ( WSAStartup( MAKEWORD( 2, 2), &WSAData)) {
printf( "fail to start up winsock.\n");
return;
}

// create a raw socket to send fake ICMP_ECHO message ...
s = socket( AF_INET, SOCK_RAW, IPPROTO_IP);
if ( s == INVALID_SOCKET) {
printf( "socket error.\n");
return;
}

bIphdrIncl = TRUE;
iRtn=setsockopt(s,IPPROTO_IP,IP_TTL,(char *)&ttl,sizeof(int));
if(iRtn){
printf( "fail to set sock option1.%ld\n",WSAGetLastError());

return;
}
iRtn =
setsockopt( s, IPPROTO_IP, IP_HDRINCL, (char *)&bIphdrIncl, sizeof(int));
if ( iRtn) {
printf( "fail to set sock option2.%ld\n",WSAGetLastError());
return;
}

// fill in ip header ...
pIphdr = (IPHDR *)buf;
pIphdr->verlen = 0x45;
pIphdr->tos = 0;
pIphdr->total_len = sizeof( IPHDR) + sizeof( ICMPHDR) + sizeof( unsigned long);
pIphdr->ident = htons(0);
pIphdr->frag_and_flags = htons(0);
pIphdr->ttl = 255;
pIphdr->proto = IPPROTO_ICMP;
pIphdr->sourceIP = inet_addr( "192.168.0.7");
pIphdr->destIP = inet_addr( "192.168.0.7");
pIphdr->checksum = 0; // ip checksum is set to 0 temperarily.

// fill in icmp header ...
pIcmphdr = (ICMPHDR *)(buf + sizeof( IPHDR));
pIcmphdr->i_type = ICMP_ECHO;
pIcmphdr->i_code = 0;
pIcmphdr->i_cksum = 0;
pIcmphdr->i_id = ( unsigned short)GetCurrentProcessId();
pIcmphdr->i_seq = 0;

// fill in icmp data ...
pIcmpdata = ( unsigned long *)(buf + sizeof( IPHDR) + sizeof( ICMPHDR));
*pIcmpdata = GetTickCount();

// calculate icmp check sum ...
pIcmphdr->i_cksum = cal_checksum( (unsigned short *)pIcmphdr, sizeof(ICMPHDR) + sizeof(unsigned long));

// calculate ip check sum ...
pIphdr->checksum = cal_checksum( (unsigned short *)pIphdr, pIphdr->total_len);

dest.sin_addr.S_un.S_addr = inet_addr( "192.168.0.7");
dest.sin_family = AF_INET;

iRtn =
sendto( s, buf, pIphdr->total_len, 0, (SOCKADDR *)&dest, sizeof(dest));
if ( iRtn == SOCKET_ERROR) {
printf( "fail to send raw ip packet to destination.%ld\n",WSAGetLastError());
return;
} else {
printf( "success.\n");
}

closesocket( s);
WSACleanup();
}

unsigned short cal_checksum( unsigned short *buf, int size)
{
unsigned long cksum = 0;

while( size > 1) {
cksum += *buf++;
size -= sizeof( unsigned short);
}

if(size) {
cksum += *( unsigned char *)buf;
}

cksum = ( cksum >> 16) + ( cksum & 0xffff);
cksum += (cksum >>16);
return ( unsigned short)(~cksum);
}



...全文
90 13 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
wx_zzm 2002-05-30
  • 打赏
  • 举报
回复
to cyAnalyst(cc):
请赐教.
Mars_wx 2002-05-30
  • 打赏
  • 举报
回复
so hard !
i no way!!!
cyAnalyst 2002-05-30
  • 打赏
  • 举报
回复
建议你使用Packet编程的方法。
功能更强大,能伪造任意的IP包进行发送(甚至可以伪造ARP包、数据帧等)。
如果有兴趣可以回复我,我再教你。
wx_zzm 2002-05-29
  • 打赏
  • 举报
回复
up有分
wx_zzm 2002-05-29
  • 打赏
  • 举报
回复
up
wx_zzm 2002-05-29
  • 打赏
  • 举报
回复
我在98和2000下都调试过,的确在98下在设置IP_HDRINCL选项时出错,如程序代码。

我是想知道在98下是否可以通过其它方法来实现?

to xuying:
你所说的packet.lib在哪可以找到?谢谢
qsfsea 2002-05-28
  • 打赏
  • 举报
回复
gz
NowCan 2002-05-28
  • 打赏
  • 举报
回复
98 不支持IP_HDRINCL,这个选项知道Win2000才开始支持。
ychener 2002-05-28
  • 打赏
  • 举报
回复
在Window98 window95 以及 winnt 下不支持
setsockopt( s, IPPROTO_IP, IP_HDRINCL, (char *)&bIphdrIncl, sizeof(int));操作,主要是不支持IP_HDRINCL选项
ychener 2002-05-28
  • 打赏
  • 举报
回复
在WinNT4.0 Window95 Window98 安装了WinSocket2的系统中可以使用IGMP和ICMP协议层上封装
在WIN2000下提供对Socket的原始封装,因此可以对UDP和IP协议进行Socket的封装

这个主要看看各个系统上对Socket的IP_HDRINCL选项的支持程度?就可以判断是否支持UDP和IP协议封装。

ychener 2002-05-28
  • 打赏
  • 举报
回复
在window网络编程上有例程

用原始套结字就可以高定!
wx_zzm 2002-05-28
  • 打赏
  • 举报
回复
高手看过来啊
xuying 2002-05-28
  • 打赏
  • 举报
回复
NowCan说得对,win98不支持IP_HDRINCL。
在win98下直接写ip报文头需要用packet.lib,一个外部库函数。

16,548

社区成员

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

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

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