原始套接字发包

#include <stdlib.h>
#include <stdio.h>


#include <iostream>
using namespace std;

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifndef WIN32
# include <errno.h>
# include <unistd.h>
# include <arpa/inet.h>
# include <sys/socket.h>
#else
# include <winsock2.h>
# include <windows.h>


# define errno    GetLastError()
# pragma comment(lib, "Ws2_32.lib")
#endif


#define DEBUG

unsigned int GcIpnston(const char* szIp)
{
 if(szIp == NULL)
 {
  return 0;
 }

 char* p = (char*)szIp;
 char nIp[4] = {0};
 nIp[3] = atoi(p);

 for(int i = 2; i >= 0; i--)
 {
  p = strchr(p, '.');
  if(p == NULL)
  {
   return 0;
  }

  nIp[i] = atoi(++p);
 }

 return *(unsigned int*)nIp;
}

unsigned int GcIphston(const char* szIp)
{
 if(szIp == NULL)
 {
  return 0;
 }

 char* p = (char*)szIp;
 char nIp[4] = {0};
 nIp[0] = atoi(p);

 for(int i = 1; i < 4; i++)
 {
  p = strchr(p, '.');
  if(p == NULL)
  {
   return 0;
  }

  nIp[i] = atoi(++p);
 }

 return *(unsigned int*)nIp;
}


unsigned short check_sum(unsigned short *addr,int len)
{
 register int nleft=len;
 register int sum=0;
 register unsigned short *w=addr;
 short answer=0;

 while(nleft>1)
 {
  sum+=*w++;
  nleft-=2;
 }
 if(nleft==1)
 {
  *(unsigned char *)(&answer)=*(unsigned char *)w;
  sum+=answer;
 }

 sum=(sum>>16)+(sum&0xffff);
 sum+=(sum>>16);
 answer=~sum;
 return(answer);
}


#define TCP_WINDOW_SIZE     512


#ifndef WIN32

#include <netinet/ip.h>
#include <netinet/tcp.h>

#else

typedef unsigned char   u_int8_t;
typedef unsigned short   u_int16_t;
typedef unsigned int   u_int32_t;
typedef unsigned short   u_short;

#define IPVERSION    4
#define MAXTTL     255

struct ip
{
 //#if __BYTE_ORDER == __LITTLE_ENDIAN
 unsigned int ip_hl:4;  /* header length */
 unsigned int ip_v:4;  /* version */
 //#endif
 //#if __BYTE_ORDER == __BIG_ENDIAN
 //    unsigned int ip_v:4;  /* version */
 //    unsigned int ip_hl:4;  /* header length */
 //#endif
 u_int8_t ip_tos;   /* type of service */
 u_short ip_len;   /* total length */
 u_short ip_id;   /* identification */
 u_short ip_off;   /* fragment offset field */
#define IP_RF 0x8000   /* reserved fragment flag */
#define IP_DF 0x4000   /* dont fragment flag */
#define IP_MF 0x2000   /* more fragments flag */
#define IP_OFFMASK 0x1fff  /* mask for fragmenting bits */
 u_int8_t ip_ttl;   /* time to live */
 u_int8_t ip_p;   /* protocol */
 u_short ip_sum;   /* checksum */
 struct in_addr ip_src, ip_dst; /* source and dest address */
};

//struct tcphdr
//  {
//    u_int16_t th_sport;  /* source port */
//    u_int16_t th_dport;  /* destination port */
//    tcp_seq th_seq;  /* sequence number */
//    tcp_seq th_ack;  /* acknowledgement number */
//#  if __BYTE_ORDER == __LITTLE_ENDIAN
//    u_int8_t th_x2:4;  /* (unused) */
//    u_int8_t th_off:4;  /* data offset */
//#  endif
//#  if __BYTE_ORDER == __BIG_ENDIAN
//    u_int8_t th_off:4;  /* data offset */
//    u_int8_t th_x2:4;  /* (unused) */
//#  endif
//    u_int8_t th_flags;
//#  define TH_FIN 0x01
//#  define TH_SYN 0x02
//#  define TH_RST 0x04
//#  define TH_PUSH 0x08
//#  define TH_ACK 0x10
//#  define TH_URG 0x20
//    u_int16_t th_win;  /* window */
//    u_int16_t th_sum;  /* checksum */
//    u_int16_t th_urp;  /* urgent pointer */
//};

struct tcphdr
{
 u_int16_t source;
 u_int16_t dest;
 u_int32_t seq;
 u_int32_t ack_seq;
 //#  if __BYTE_ORDER == __LITTLE_ENDIAN
 u_int16_t res1:4;
 u_int16_t doff:4;
 u_int16_t fin:1;
 u_int16_t syn:1;
 u_int16_t rst:1;
 u_int16_t psh:1;
 u_int16_t ack:1;
 u_int16_t urg:1;
 u_int16_t res2:2;
 //#  elif __BYTE_ORDER == __BIG_ENDIAN
 //    u_int16_t doff:4;
 //    u_int16_t res1:4;
 //    u_int16_t res2:2;
 //    u_int16_t urg:1;
 //    u_int16_t ack:1;
 //    u_int16_t psh:1;
 //    u_int16_t rst:1;
 //    u_int16_t syn:1;
 //    u_int16_t fin:1;
 //#  else
 //#   error "Adjust your <bits/endian.h> defines"
 //#  endif
 u_int16_t window;
 u_int16_t check;
 u_int16_t urg_ptr;
};
#endif

struct TcpPseudoHdr_t  //定义TCP伪首部
{
 unsigned int ipSource;  //源地址
 unsigned int ipDestination; //目的地址
 unsigned char mbz;
 unsigned char ipProtocol;  //协议类型
 unsigned short tcpLength;  //TCP长度
};

struct TcpCheckHdr_t
{
 struct TcpPseudoHdr_t tcp_pseud;
 struct tcphdr tcp_real;
};

struct RawPacketInfo_t
{
 // network word
 int src_ip;
 int src_port;
 int dst_ip;
 int dst_port;

 // ----------
 //int ttl;

 int seq;
 int ack;
};

#define MAX_BUFFER_SIZE    4096
#define SSEQ      43289432
/*
#define SSEQ 43289432
//SEND
sip = local
sport = range(1024,5000);
dip = dest
dport = htons(80);
seq = sip + sport + dip + dport + SSEQ;

//RECIVE ...
*/

#ifndef WIN32
int SocketRaw()
{
 int sockfd = socket(AF_INET, SOCK_RAW, /*IPPROTO_TCP*/IPPROTO_ICMP);
 if(sockfd < 0)
 {
  fprintf(stderr, "Socket Error:%s/n/a", strerror(errno));
  exit(1);
 }


 /******** 设置IP数据包格式,告诉系统内核模块IP数据包由我们自己来填写 ***/
 int flag = 1;
 setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, &flag, sizeof(flag));

 /**** 没有办法,只用超级护用户才可以使用原始套接字 *********/
 setuid(getpid());


 return sockfd;
}

#else


#define IP_HDRINCL    2   /* header is included with data */
#define SIO_RCVALL    _WSAIOW(IOC_VENDOR,1)
int SocketRaw()
{
 int ErrorCode = 0;
 unsigned char flag=0x00;
 int TimeOut=2000;
 WSADATA wsaData;

 if((ErrorCode=WSAStartup(MAKEWORD(2,1),&wsaData))!=0)
 {
  return -1;
 }
 int SockRaw=WSASocket(AF_INET,SOCK_RAW,IPPROTO_RAW,NULL,0,WSA_FLAG_OVERLAPPED);
 if (SockRaw==INVALID_SOCKET)
 {
  return -1;
 }
 flag|=0x10;
 ErrorCode=setsockopt(SockRaw,IPPROTO_IP,IP_HDRINCL,(char *)&flag,sizeof(int));
 if (ErrorCode==SOCKET_ERROR)
 {
  return -1;
 }

 ErrorCode=setsockopt(SockRaw,SOL_SOCKET,SO_SNDTIMEO,(char*)&TimeOut,sizeof(TimeOut));
 if (ErrorCode==SOCKET_ERROR)
 {
  return -1;
 }
 return SockRaw;
}
#endif


int SendRaw(int rawsock, struct RawPacketInfo_t* lprpi, char* lpdata = NULL, int size = 0)
{
 char buf[MAX_BUFFER_SIZE] = {0};
 struct ip *ipx;
 struct tcphdr *tcp;

 // struct self
 int total_len = sizeof(struct ip) + sizeof(struct tcphdr);
 if(lpdata != NULL && size > 0 && (MAX_BUFFER_SIZE - total_len) > size)
 {
  memcpy(buf + total_len, lpdata, size);
  total_len += size;
 }
 //#ifdef WIN32
 // else
 // {
 //  const char* sdata = "123";
 //  int slen = strlen(sdata);
 //  memcpy(buf + total_len, sdata, slen);
 //  total_len += slen;
 // }
 //#endif

 ipx = (struct ip *)buf;
 ipx->ip_v = IPVERSION;
 ipx->ip_hl = sizeof(struct ip) >> 2;
 ipx->ip_tos = 0;
 ipx->ip_len = htons(total_len);
 ipx->ip_id = 0;
 ipx->ip_off = 0;
 ipx->ip_ttl = htons(MAXTTL);
 ipx->ip_p = IPPROTO_TCP;
 ipx->ip_src = *(struct in_addr *)&lprpi->src_ip;
 ipx->ip_dst = *(struct in_addr *)&lprpi->dst_ip;
 ipx->ip_sum = 0;
 //ipx->ip_sum = check_sum((unsigned short *)&ipx, sizeof(struct ip));

 tcp = (struct tcphdr *)(buf + sizeof(struct ip));
 tcp->source = lprpi->src_port;
 tcp->dest = lprpi->dst_port;
 tcp->seq = lprpi->seq;
 tcp->ack_seq = lprpi->ack;
 tcp->doff = 5;
 tcp->syn = 1;
 tcp->window = htons(TCP_WINDOW_SIZE);
 //tcp->check = check_sum((unsigned short *)tcp, sizeof(struct tcphdr));

 // pseudo_tcp_header
 TcpCheckHdr_t tcp_check = {0};
 tcp_check.tcp_pseud.ipSource = lprpi->src_ip;
 tcp_check.tcp_pseud.ipDestination = lprpi->dst_ip;
 tcp_check.tcp_pseud.ipProtocol = IPPROTO_TCP;
 //tcp_check.tcp_pseud.tcpLength = ipx->ip_len;
 tcp_check.tcp_pseud.tcpLength = htons(sizeof(struct tcphdr));
 memcpy(&tcp_check.tcp_real, tcp, sizeof(struct tcphdr));
 tcp->check = check_sum((unsigned short *)&tcp_check, sizeof(struct TcpCheckHdr_t));

 printf("send checksum: %x  ",htonl(tcp->check));

 // raw socket sendto
 struct sockaddr_in addr = {0};
 addr.sin_family = AF_INET;
 addr.sin_port = lprpi->dst_port;
 addr.sin_addr = *(struct in_addr *)&lprpi->dst_ip;
 int ret = sendto(rawsock, buf, total_len, 0, (const sockaddr*)&addr, sizeof(struct sockaddr_in));

#ifdef DEBUG
 if(ret == -1)
 {
  //printf("ret = %d, send_len = %d, error = %d/n", ret, total_len, errno);
 }
 //printf("ret = %d, send_len = %d, error = %d/n", ret, total_len, errno);
#endif

 return 0;
}

unsigned int ProductSeq(struct RawPacketInfo_t* lprpi)
{
 return lprpi->src_ip + lprpi->src_port + lprpi->dst_ip + lprpi->dst_port + SSEQ;
}


int SendSyn(char* src_ip, int src_port, char* dst_ip, int dst_port)
{
 int nsip = inet_addr(src_ip);
 int ndip = inet_addr(dst_ip);
 if(nsip == -1 || ndip == -1)
 {
  return -1;
 }

 struct RawPacketInfo_t rpi = {0};
 rpi.src_ip = nsip;
 rpi.src_port = htons(src_port);
 rpi.dst_ip = ndip;
 rpi.dst_port = htons(dst_port);
 rpi.seq = ProductSeq(&rpi);
 rpi.ack = 0;

 return SendRaw(SocketRaw(), &rpi);
}

int SendSyn(int src_ip, int src_port, int dst_ip, int dst_port)
{
 struct RawPacketInfo_t rpi = {0};
 rpi.src_ip = htonl(src_ip);
 rpi.src_port = htons(src_port);
 rpi.dst_ip = htonl(dst_ip);
 rpi.dst_port = htons(dst_port);
 rpi.seq = ProductSeq(&rpi);
 rpi.ack = 0;

 return SendRaw(SocketRaw(), &rpi);
}


#define DEFAULT_WEB_PORT    80

 

// sport = range(1024, 5000);
int Range(int begin, int end)
{
 static int port = begin;
 return port <= end ? port++ : end;
}

int CheckActiveWeb(char* src_ip, char* begin_ip, char* end_ip)
{
 int src_nip = inet_addr(src_ip);
 if(src_nip == -1)
 {
  printf("[error] src ip error, %s --> %d!/n", src_ip, src_nip);
  return -1;
 }

 unsigned int dst_bip = GcIpnston(begin_ip);
 unsigned int dst_eip = GcIpnston(end_ip);

#ifdef DEBUG
 printf("%s(%u) --> %s(%u)/r/n/r/n", begin_ip, dst_bip, end_ip, dst_eip);
#endif

 int sock = SocketRaw();
 int src_port = Range(1024, 5000);

 for(; dst_bip <= dst_eip; dst_bip++)
 {
  struct RawPacketInfo_t rpi = {0};
  rpi.src_ip = src_nip;
  rpi.src_port = htons(src_port);
  rpi.dst_ip = htonl(dst_bip);
  rpi.dst_port = htons(DEFAULT_WEB_PORT);
  rpi.seq = ProductSeq(&rpi);

  SendRaw(sock, &rpi);

#ifdef DEBUG
  printf("%u --> %u --> %s/n", dst_bip, rpi.dst_ip, inet_ntoa(*(struct in_addr*)&(rpi.dst_ip)));
  //printf("%u --> %u --> %s/n", dst_bip, rpi.dst_ip, inet_ntoa(*(struct in_addr*)&(dst_bip)));
#endif
 }

#ifdef DEBUG
 printf("ok/n");
#endif
 return 0;
}

// --------------
void Helper(const char* self)
{
 printf("%s --src_ip [ip]/n"
  "/t--dst_bip [ip]/n"
  "/t--dst_eip [ip]/n"
  , self);
}

int main(int argc, char** argv)
{
 /*
 * argment:
 * --src_ip
 * --dst_bip
 * --dst_eip
 */
 if(argc == 7 && strcmp(argv[1], "--src_ip") == 0
  && strcmp(argv[3], "--dst_bip") == 0
  && strcmp(argv[5], "--dst_eip") == 0)
 {
  CheckActiveWeb(argv[2], argv[4], argv[6]);
 }
 else
 {
  Helper(argv[0]);
 }

 return 0;
}

 


// int main(int argc, char** argv)
// {
//
//  unsigned int n = GcIpnston("192.168.2.11");
//  cout<<n<<endl;
//
//  cout<<((n >> 24) & 0xFF)<<endl;
//  
//
//  return 0;
// };

/*

*/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用setsockopt函数来设置心跳。在设置之前,需要先创建一个套接字并使用accept函数接收客户端连接,然后再使用setsockopt函数来设置心跳。 具体操作步骤如下: 1. 创建套接字并使用bind和listen函数将其绑定到指定的地址和端口上,等待客户端连接。 2. 使用accept函数接收客户端连接,并将返回的客户端套接字保存起来。 3. 使用setsockopt函数设置心跳相关参数,例如心跳间隔时间、心跳发送次数等。可以使用SO_KEEPALIVE选项来启用心跳功能,并使用TCP_KEEPIDLE、TCP_KEEPINTVL和TCP_KEEPCNT选项来设置心跳间隔时间、心跳发送次数等参数。 4. 在客户端和服务器之间进行数据传输时,定时发送心跳,以维持连接的稳定性。 下面是一个示例代码,用于设置心跳参数: ```c int keepAlive = 1; // 开启keepalive属性 int keepIdle = 60; // 如该连接在60秒内没有任何数据往来,则进行探测 int keepInterval = 5; // 探测时发包的时间间隔为5 秒 int keepCount = 3; // 探测尝试的次数。如果第1次探测就收到响应了,则后2次的不再发送 setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepAlive, sizeof(keepAlive)); setsockopt(sockfd, SOL_TCP, TCP_KEEPIDLE, (void *)&keepIdle, sizeof(keepIdle)); setsockopt(sockfd, SOL_TCP, TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval)); setsockopt(sockfd, SOL_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount)); ``` 其中,sockfd是已经建立好的套接字,可以使用accept函数返回的客户端套接字。这段代码将开启keepalive属性,并设置心跳的间隔时间为60秒,发送次数为3次。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值