Генерация SYN пакетов (Linux)

Тема в разделе "WASM.NETWORKS", создана пользователем Serg79, 6 окт 2008.

  1. Serg79

    Serg79 New Member

    Публикаций:
    0
    Регистрация:
    16 ноя 2007
    Сообщения:
    3
    Необходимо генерировать tcp пакеты с установленным флагом SYN.
    Создаю RAW-сокет и через него посылаю 'tcp'-пакет с установленным <SYN>. Но столкнулся с неприятной проблемой, когда удаленная машина в ответ отправляет пакет <SYN,ACK>, моя почему то в ответ шлет пакет <RST>, что приводит к сбросу данного соединения на удаленной машине.
    Подскажите, как побороть данную проблему?
    Код (Text):
    1. #include <stdio.h>
    2. #include <stdlib.h>
    3. #include <time.h>
    4. #include <string.h>
    5. #include <stdarg.h>
    6. #include <errno.h>
    7. #include <inttypes.h>
    8. #include <sys/socket.h>
    9. #include <netinet/in.h>
    10. #include <netinet/ip.h>
    11. #include <netinet/tcp.h>
    12. #include <netinet/ip_icmp.h>
    13.  
    14. static const char ip_src[] = "192.168.20.220";
    15. static const char ip_dst[] = "192.168.20.236";
    16.  
    17. static const char *progname;
    18.  
    19. struct tcphdr tcp;
    20.  
    21. struct {
    22.     struct ip ip;
    23.     struct icmp icmp;
    24. } msg;
    25.  
    26. struct {
    27.     struct {
    28.         struct in_addr ip_src, ip_dst;
    29.         uint16_t ptcl;
    30.         uint16_t len;
    31.     } ptcp;
    32.     struct tcphdr tcp;
    33. } pack;
    34.  
    35. static void errprint(const char *fmt, ...)
    36. {
    37.     va_list args;
    38.  
    39.     if (progname != NULL)
    40.         fprintf(stderr,"%s: ",progname);
    41.     va_start(args,fmt);
    42.     vfprintf(stderr,fmt,args);
    43.     va_end(args);
    44.  
    45.     exit(1);
    46. }
    47.  
    48. static uint16_t ip_sum_calc(const uint8_t *buff, int len)
    49. {
    50.     const uint16_t *p = (const uint16_t *)buff;
    51.     uint32_t sum = 0;
    52.     int i;
    53.  
    54.     for (i = 0; i < len / 2; i++) {
    55.         sum += p[i];
    56.         if (sum > 0xffff)
    57.             sum = (sum & 0xffff) + 1;
    58.     }
    59.  
    60.     sum = ~sum;
    61.     return sum;
    62. }
    63.  
    64. static void print_hex(const uint8_t *buff, int len)
    65. {
    66.     int i = 0;
    67.  
    68.     while (i < len) {
    69.         printf("0x%02x ",buff[i++]);
    70.         if ((i % 4) == 0)
    71.             putchar('\n');
    72.     }
    73. }
    74.  
    75. static void create_msg(void)
    76. {
    77.     char ch;
    78.     int i;
    79.  
    80.     /* prepare 'icmp' */
    81.     msg.icmp.icmp_type = ICMP_ECHO;
    82.     msg.icmp.icmp_code = 0;
    83.     msg.icmp.icmp_cksum = 0;
    84.     msg.icmp.icmp_id = rand();
    85.     msg.icmp.icmp_seq = 0;
    86.     ch = 'a';
    87.     for (i = 0; i < sizeof(struct icmp) - sizeof(struct icmphdr); i++, ch++)
    88.         ((char *)&msg.icmp.icmp_dun.id_data[0])[i] = ch;
    89.     msg.icmp.icmp_cksum = ip_sum_calc((uint8_t *)&msg.icmp,sizeof(msg.icmp));
    90.  
    91.     /* prepare 'ip' */
    92.     msg.ip.ip_v = 4;
    93.     msg.ip.ip_hl = 5;
    94.     msg.ip.ip_tos = 0;
    95.     msg.ip.ip_len = htons(sizeof(msg));
    96.     msg.ip.ip_id = htons(rand());
    97.     msg.ip.ip_off = htons(IP_DF);
    98.     msg.ip.ip_ttl = 64;
    99.     msg.ip.ip_p = IPPROTO_ICMP;
    100.     msg.ip.ip_sum = 0;
    101.     msg.ip.ip_src.s_addr = inet_addr(ip_src);
    102.     msg.ip.ip_dst.s_addr = inet_addr(ip_dst);
    103.     msg.ip.ip_sum = htons(ip_sum_calc((void *)&msg.ip,sizeof(msg.ip)));
    104. }
    105.  
    106. void create_tcp(void)
    107. {
    108.     memset(&pack,0,sizeof(pack));
    109.  
    110.     pack.ptcp.ip_src.s_addr = inet_addr(ip_src);
    111.     pack.ptcp.ip_dst.s_addr = inet_addr(ip_dst);
    112.     pack.ptcp.ptcl = htons(IPPROTO_TCP);
    113.     pack.ptcp.len = htons(sizeof(pack.tcp));
    114.  
    115.     pack.tcp.source = htons(1000);
    116.     pack.tcp.dest = htons(448);
    117.     pack.tcp.seq = htonl(101);
    118.     pack.tcp.doff = 5;
    119.     pack.tcp.syn = 1;
    120.     pack.tcp.window = 1024;
    121.     pack.tcp.check = ip_sum_calc((void *)&pack,sizeof(pack));
    122. }
    123.  
    124. int main(int argc, char **argv)
    125. {
    126.     char buff[1024];
    127.     struct sockaddr_in addr;
    128.     int raw_socket;
    129.     int res,tmp;
    130.  
    131.     progname = argv[0];
    132.     srand(time(NULL));
    133.  
    134.     create_msg();
    135.     create_tcp();
    136.  
    137.     raw_socket = socket(PF_INET,SOCK_RAW,IPPROTO_TCP);
    138.     if (raw_socket < 0)
    139.         errprint("Failed execute 'socket': %s\n",strerror(errno));
    140.     tmp = 1;
    141. //  res = setsockopt(raw_socket,IPPROTO_IP,IP_HDRINCL,&tmp,sizeof(tmp));
    142. //  if (res < 0)
    143. //      errprint("Failed execute 'setsockopt': %s\n",strerror(errno));
    144.  
    145.     printf("to:\n");
    146.     print_hex((uint8_t *)&pack,sizeof(pack));
    147.  
    148.     memset(&addr,0,sizeof(addr));
    149.     addr.sin_family = AF_INET;
    150.     addr.sin_port = 448;
    151.     addr.sin_addr.s_addr = inet_addr(ip_dst);
    152. //  res = sendto(raw_socket,&msg,sizeof(msg),0,
    153. //          (struct sockaddr *)&addr,sizeof(addr));
    154.     res = sendto(raw_socket,&pack.tcp,sizeof(pack.tcp),0,
    155.             (struct sockaddr *)&addr,sizeof(addr));
    156.     if (res < 0)
    157.         errprint("Failed execute 'sendto': %s\n",strerror(errno));
    158.  
    159.     addr.sin_family = AF_INET;
    160.     addr.sin_port = IPPROTO_TCP;
    161.     addr.sin_addr.s_addr = inet_addr(ip_dst);
    162.     tmp = sizeof(addr);
    163.     res = recvfrom(raw_socket,buff,sizeof(buff),0,
    164.             (struct sockaddr *)&addr,&tmp);
    165.     if (res < 0)
    166.         errprint("Failed execute 'recvfrom': %s\n",strerror(errno));
    167.  
    168.     printf("from:\n");
    169.     print_hex(buff,res);
    170.  
    171.     sleep(10);
    172.  
    173.     close(raw_socket);
    174.  
    175.     return 0;
    176. }
     
  2. s0larian

    s0larian New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2004
    Сообщения:
    489
    Адрес:
    Крыжёпполь
    :) ессно. Syn/ack приходит в tcp/ip stack который проверяет список сокетов и посылает rst. Побороть это надо так - посылать syn от виртуального IP адреса (но с той же подсети) и прописывать вирт. MAC address. То есть, это не будет никак связяно с реальным stack-ом. На втором компе пропиши static arp запись.
     
  3. nester7

    nester7 New Member

    Публикаций:
    0
    Регистрация:
    5 дек 2003
    Сообщения:
    720
    Адрес:
    Russia
    libnet + libpcap.