半打开扫描源程序(for WIN2K)[1]

[入库:2005年8月18日] [更新:2007年3月25日]

本文简介:选择自 sundna 的 blog

#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include "mstcpip.h"
#pragma comment(lib,"ws2_32")

#define default_dest_port 5
#define dest_host "www.hrbust.edu.cn"
#define seq 0x28376839

typedef struct _iphdr
{
unsigned char h_lenver; //4位首部长度+4位ip版本号
unsigned char tos; //8位服务类型tos
unsigned short total_len; //16位总长度(字节)
unsigned short ident; //16位标识
unsigned short frag_and_flags; //3位标志位
unsigned char ttl; //8位生存时间 ttl
unsigned char proto; //8位协议 (tcp, udp 或其他)
unsigned short checksum; //16位ip首部校验和
unsigned int sourceip; //32位源ip地址
unsigned int destip; //32位目的ip地址
}ip_header;

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

struct //定义tcp伪首部
{
unsigned long saddr; //源地址
unsigned long daddr; //目的地址
char mbz;
char ptcl; //协议类型
unsigned short tcpl; //tcp长度
}psd_header;

socket sockraw = invalid_socket,
socklisten = invalid_socket;
struct sockaddr_in dest;

//sock错误处理程序
void checksockerror(int ierrorcode, char *perrormsg)
{
if(ierrorcode==socket_error) 
{
printf("%s error:%d\n", perrormsg, getlasterror());
closesocket(sockraw);
exitprocess(-1);
}

}

//计算检验和
ushort checksum(ushort *buffer, int size)
{
  unsigned long cksum=0;

  while (size > 1)
  {
    cksum += *buffer++;
    size -= sizeof(ushort);
  }
  if (size)
  {
    cksum += *(uchar*)buffer;
  }
  cksum = (cksum >> 16) + (cksum & 0xffff);
  cksum += (cksum >>16);
  return (ushort)(~cksum);
}

//ip解包程序
bool decodeipheader(char *buf, int bytes)
{
ip_header *iphdr;
tcp_header *tcphdr;
  unsigned short iphdrlen;

  iphdr = (ip_header *)buf;
  iphdrlen = sizeof(unsigned long) * (iphdr->h_lenver & 0xf);
  tcphdr = (tcp_header*)(buf + iphdrlen);

//是否来自目标ip
if(iphdr->sourceip != dest.sin_addr.s_addr) return false;

//序列号是否正确
if((ntohl(tcphdr->th_ack) != (seq+1)) && (ntohl(tcphdr->th_ack) != seq)) return false;

//rst/ack - 无服务
if(tcphdr->th_flag == 20)
{
printf(".\n");
return true;
}

//syn/ack - 扫描到一个端口
if(tcphdr ->th_flag == 18)
{
printf("%d\n",ntohs(tcphdr->th_sport));
return true;
}

  return true;
}

//主函数
int main(int argc,char **argv)
{
int ierrorcode;
int datasize;
struct hostent *hp;
ip_header ip_header;
tcp_header tcp_header;
char sendbuf[128]={0};
char recvbuf[65535]={0};

//初始化socket
wsadata wsadata;
ierrorcode = wsastartup(makeword(2,2),&wsadata);
checksockerror(ierrorcode, "wsastartup()");
sockraw = socket(af_inet , sock_raw , ipproto_ip);
checksockerror(sockraw, "socket()");
socklisten = socket(af_inet , sock_raw , ipproto_ip);
checksockerror(socklisten, "socket");

//设置ip头操作选项
bool bopt = true;
ierrorcode = setsockopt(sockraw,ipproto_ip,ip_hdrincl,(char *)&bopt,sizeof(bopt));
checksockerror(ierrorcode, "setsockopt()");

//获得本地ip
sockaddr_in sa;
unsigned char localname[256];

ierrorcode = gethostname((char*)localname,sizeof(localname)-1);
checksockerror(ierrorcode, "gethostname()");
if((hp = gethostbyname((char*)localname)) == null)
{
checksockerror(socket_error, "gethostbyname()");
}
memcpy(&sa.sin_addr.s_un.s_addr,hp->h_addr_list[0],hp->h_length);
sa.sin_family = af_inet;
sa.sin_port = htons(7000);
ierrorcode = bind(socklisten, (psockaddr)&sa, sizeof(sa));
checksockerror(ierrorcode, "bind");

//设置sock_raw为sio_rcvall,以便接收所有的ip包
dword dwbufferlen[10] ;
dword dwbufferinlen = 1 ;
dword dwbytesreturned = 0 ;
ierrorcode=wsaioctl(socklisten, sio_rcvall,&dwbufferinlen, sizeof(dwbufferinlen),      
            &dwbufferlen, sizeof(dwbufferlen),&dwbytesreturned , null , null );
checksockerror(ierrorcode, "ioctl");

//获得目标主机ip
memset(&dest,0,sizeof(dest));
dest.sin_family = af_inet;
dest.sin_port = htons(default_dest_port);
if((dest.sin_addr.s_addr = inet_addr(dest_host)) == inaddr_none)
{
if((hp = gethostbyname(dest_host)) != null)
{
memcpy(&(dest.sin_addr),hp->h_addr_list[0],hp->h_length);
dest.sin_family = hp->h_addrtype;
printf("dest.sin_addr = %s\n",inet_ntoa(dest.sin_addr));
}
else
{
checksockerror(socket_error, "gethostbyname()");
}
}

//填充ip首部
ip_header.h_lenver=(4<<4 | sizeof(ip_header)/sizeof(unsigned long));
//高四位ip版本号,低四位首部长度

本文关键:源程序
  相关方案
Google
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top