zoukankan      html  css  js  c++  java
  • 原始套接字-自定义IP首部和TCP首部

      1 /* =====================================================================================
      2 *
      3 *       Filename:    raw.c
      4 *    Description:    使用原始套接字发送TCP协议,并外带自己的数据。
      5 *
      6 * ====================================================================================*/
      7 #include <stdio.h>
      8 #include <stdlib.h>
      9 #include <string.h>
     10 #include <sys/socket.h>
     11 #include <netinet/in.h>
     12 #include <netinet/ip.h>
     13 #include <netinet/tcp.h>
     14 #include <arpa/inet.h>
     15 #define DATA "hello"
     16 #define PACKET_SIZE sizeof(struct iphdr) + sizeof(struct tcphdr) + sizeof(DATA)
     17 
     18 /*---------------------------------------------------------
     19  Function Name : check_sum()
     20    Descrypthon : 校验和计算,摘自UNP源码
     21 ------------------------------------------------------------*/
     22 unsigned short check_sum(unsigned short *addr, int len)
     23 {
     24     int nleft = len;
     25     int sum = 0;
     26     unsigned short *w = addr;
     27     short answer = 0;
     28     while (nleft > 1)
     29     {
     30         sum += *w++;
     31         nleft -=2;
     32     }
     33     if (nleft == 1)
     34     {
     35         *(unsigned char *)(&answer) = *(unsigned char *)w;
     36         sum += answer;
     37     }
     38     sum = (sum >> 16) + (sum & 0xffff);
     39     sum += (sum >> 16);
     40     answer = ~sum;
     41     return answer;
     42 }
     43 
     44 /*---------------------------------------------------------
     45  Function Name : init_socket()
     46    Descrypthon : 初始化socket,使用原始套接字
     47    parameter   : P1 一个待初始化的原始套接字,P2 待初始化的目标地址结构,P3 目标地址,P4 目标端口
     48    return      : 返回一个原始套接字,在函数体内将目标地址结构进行初始
     49 ------------------------------------------------------------*/
     50 int init_socket(int sockfd, struct sockaddr_in *target,const char *dst_addr, const char *dst_port)
     51 {
     52     const int flag = 1;
     53     //目标协议簇
     54     target->sin_family = AF_INET;
     55     //目标端口
     56     target->sin_port = htons(atoi(dst_port));
     57 
     58     //将dst_addr中的ASCII-IP地址更新到target->sin_addr结构中
     59     if (inet_aton(dst_addr, &target->sin_addr) == 0)
     60     {
     61         perror("inet_aton fail
    ");
     62         exit(-1);
     63     }
     64     //初始化原始套接字
     65     if((sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) < 0)
     66     {
     67         perror("error");
     68         exit(-1);
     69     }
     70     //设置套接字×××
     71     if (setsockopt(sockfd,IPPROTO_IP, IP_HDRINCL, &flag, sizeof(flag)) < 0)
     72     {
     73         perror("setsockopt fail 
    ");
     74         exit(-1);
     75     }
     76     return sockfd;
     77 }
     78 
     79 /*---------------------------------------------------------------
     80  Function Name : buile_iphdr()
     81    Descrypthon : 构建IP头部数据, 源地址使用伪随机地址
     82 -----------------------------------------------------------------*/
     83 void buile_iphdr(struct sockaddr_in *target, char *buffer)
     84 {
     85     struct iphdr *ip = (struct iphdr *)(buffer);
     86     ip->version = 4;//版本
     87     ip->ihl = 5;//首部长度 5*4 = 20
     88     ip->tos = 0;//8位服务类型
     89     ip->tot_len = htons(PACKET_SIZE);//16位总长度
     90     ip->id = 0;//16位标识符
     91     ip->frag_off = 0;//3位标志
     92     ip->ttl = 255;//生存时间
     93     ip->protocol = IPPROTO_TCP;//协议
     94     ip->check = check_sum((unsigned short *)ip, sizeof(struct iphdr) + sizeof(DATA));//16位首部校验和
     95     ip->saddr = random();//源ip地址
     96     ip->daddr = target->sin_addr.s_addr;//目标ip地址
     97 }
     98 
     99 /*---------------------------------------------------------------
    100  Function Name : buile_tcphdr()
    101    Descrypthon : 构建TCP头部信息,并加入一些自己的数据,然后进行
    102                  校验计算。
    103 -----------------------------------------------------------------*/
    104 void buile_tcphdr(struct sockaddr_in *target, const char *src_port, char *buffer)
    105 {
    106     struct tcphdr *tcp = (struct tcphdr *)(buffer);
    107     tcp->source = htons(atoi(src_port));//16位源端口号
    108     tcp->dest = target->sin_port;//16位目的端口号
    109     tcp->seq = random();//32位序号
    110     tcp->doff = 5;//
    111     tcp->syn = 1;//同步序号
    112     buffer += sizeof(struct tcphdr);
    113     tcp->check = check_sum((unsigned short *)tcp, sizeof(struct tcphdr) + sizeof(DATA));//16位检验和
    114     memcpy(buffer, DATA, sizeof(DATA));//将DATA中的数据拷贝sizeof(DATA)字节到buffer所指的地址中
    115 }
    116 int main(int argc, const char *argv[])
    117 {
    118     char *buffer;
    119     char *buffer_head = NULL;
    120     int sockfd = 0;
    121     struct sockaddr_in *target;
    122     if (argc != 4)
    123     {
    124         printf("usage: destination addresss, destination port, source port 
    ");
    125         exit(-1);
    126     }
    127     const char *dst_addr = argv[1];
    128     const char *dst_port = argv[2];
    129     const char *src_port = argv[3];
    130 
    131     target = calloc(sizeof(struct sockaddr_in),1);
    132     //calloc在动态分配完内存后,自动初始化该内存空间为零,而malloc不初始化,里边数据是随机的垃圾数据。
    133     buffer = calloc(PACKET_SIZE, 1);
    134     buffer_head = buffer;
    135 
    136     //初始化套接字
    137     sockfd = init_socket(sockfd, target, dst_addr, dst_port);
    138     //创建IP首部
    139     buile_iphdr(target, buffer);
    140     buffer += sizeof(struct iphdr);//指针下移
    141     //创建TCP首部
    142     buile_tcphdr(target, src_port, buffer);
    143     //发送
    144     sendto(sockfd, buffer_head, PACKET_SIZE, 0,(struct sockaddr *)target, sizeof(struct sockaddr_in));
    145 
    146     //下两行是对calloc申请的释放
    147     free(buffer_head);
    148     free(target);
    149     return 0;
    150 }
  • 相关阅读:
    最长回文子串
    学习与提升
    jupyter notebook nginx 试听录音文件,网页试听
    【神经网络】batch、epoch、iteration的含义
    【tensorflow】Tensorflow入门教程
    最全BAT面试题
    打印二叉树
    基于argparser模块实现 ls 功能(基本实现)
    比较详细的argpasrse模块的基本使用
    ini文件转换为Json文件
  • 原文地址:https://www.cnblogs.com/A--Q/p/7151805.html
Copyright © 2011-2022 走看看