半打开扫描源程序(for WIN2K)#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.gmhose.com#define SEQ 0x28376839typedef struct _iphdr {unsigned char h_lenver; //4位首部长度+4位IP版本号unsigned char tos; //8位服务类型TOSunsigned short total_len; //16位总长度(字节)unsigned short ident; //16位标识unsigned short frag_and_flags; //3位标志位unsigned char ttl; //8位生存时间 TTLunsigned 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 intth_seq; //32位序列号unsigned intth_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_indest;//SOCK错误处理程序void CheckSockError(int iErrorCode, char *pErrorMsg){if(iErrorCode==SOCKET_ERROR){printf("%s Error:%dn", 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 shortiphdrlen;iphdr = (IP_HEADER *)buf;iphdrlen = sizeof(unsigned long) * (iphdr->h_lenver & 0xf);tcphdr = (TCP_HEADER*)(buf + iphdrlen);//是否来自目标IPif(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("%dn",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};//初始化SOCKETWSADATA 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()"); //获得本地IPSOCKADDR_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");//获得目标主机IPmemset(&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 = %sn",inet_ntoa(dest.sin_addr));}else{CheckSockError(SOCKET_ERROR, "gethostbyname()");}}//填充IP首部ip_header.h_lenver=(4<<4 | sizeof(ip_header)/sizeof(unsigned long));//高四位IP版本号,低四位首部长度ip_header.total_len=htons(sizeof(IP_HEADER)+sizeof(TCP_HEADER)); //16位总长度(字节)ip_header.ident=1; //16位标识ip_header.frag_and_flags=0; //3位标志位ip_header.ttl=128; //8位生存时间TTLip_header.proto=IPPROTO_TCP; //8位协议(TCP,UDP…)ip_header.checksum=0; //16位IP首部校验和ip_header.sourceIP=sa.sin_addr.s_addr; //32位源IP地址ip_header.destIP=dest.sin_addr.s_addr; //32位目的IP地址//填充TCP首部tcp_header.th_sport=htons(7000); //源端口号tcp_header.th_dport=htons(DEFAULT_DEST_PORT); //目的端口号tcp_header.th_seq=htonl(SEQ); //SYN序列号tcp_header.th_ack=0; //ACK序列号置为0tcp_header.th_lenres=(sizeof(TCP_HEADER)/4<<4|0); //TCP长度和保留位tcp_header.th_flag=2; //SYN 标志tcp_header.th_win=htons(16384); //窗口大小tcp_header.th_urp=0; //偏移tcp_header.th_sum=0; //校验和//填充TCP伪首部(用于计算校验和,并不真正发送)psd_header.saddr=ip_header.sourceIP;psd_header.daddr=ip_header.destIP;psd_header.mbz=0;psd_header.ptcl=IPPROTO_TCP;psd_header.tcpl=htons(sizeof(tcp_header));//计算TCP校验和,计算校验和时需要包括TCP pseudo header memcpy(SendBuf,&psd_header,sizeof(psd_header)); memcpy(SendBuf+sizeof(psd_header),&tcp_header,sizeof(tcp_header));tcp_header.th_sum=checksum((USHORT *)SendBuf,sizeof(psd_header)+sizeof(tcp_header));//计算IP校验和memcpy(SendBuf,&ip_header,sizeof(ip_header));memcpy(SendBuf+sizeof(ip_header),&tcp_header,sizeof(tcp_header));memset(SendBuf+sizeof(ip_header)+sizeof(tcp_header),0,4);datasize=sizeof(ip_header)+sizeof(tcp_header);ip_header.checksum=checksum((USHORT *)SendBuf,datasize);//填充发送缓冲区memcpy(SendBuf,&ip_header,sizeof(ip_header));//发送TCP报文iErrorCode=sendto(sockRaw,SendBuf,datasize,0,(struct sockaddr*) &dest,sizeof(dest));CheckSockError(iErrorCode, "sendto()");//接收数据DWORD timeout = 2000;DWORD start = GetTickCount();while(true){//计时,2s超时if((GetTickCount() - start) >= timeout) break;memset(RecvBuf, 0, sizeof(RecvBuf));iErrorCode = recv(sockListen, RecvBuf, sizeof(RecvBuf), 0);CheckSockError(iErrorCode, "recv");if(DecodeIPHeader(RecvBuf,iErrorCode)) break;}//退出前清理if(sockRaw != INVALID_SOCKET) closesocket(sockRaw);WSACleanup();return 0;}