2015-10-24 2 views
0

Я пытался создать отправитель TCP-пакетов в C с помощью следующего кодаTCP пакетов ошибок Sender

#include <stdio.h> 
#include <sys/socket.h> 
#include <sys/types.h> 
#include <netinet/in.h> 
#include <netinet/ip.h> 
#include <netinet/tcp.h> 
#include <arpa/inet.h> 

int main(void){ 

    char buffer[1024]; 
    int packetsize[100]; 
    char* source_ip = "192.168.2.1"; 


struct sockaddr_in serv; 
struct iphdr *iph; 
struct tcphdr *tcph; 


int sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_TCP); 
serv.sin_family = AF_INET; 
serv.sin_port = htons(80); 
serv.sin_addr.s_addr = inet_addr ("8.8.8.8"); 

struct tcp_pseudo 
{ 
    uint32_t src_addr; 
    uint32_t dst_addr; 
    uint8_t zero; 
    uint8_t proto; 
    uint16_t length; 
} pseudohead; 


struct help_checksum 
{ 
    struct tcp_pseudo pshd; 
    struct tcphdr tcphd; 
    char tcpdata[1024]; 
} tcp_chk_construct; 

// Create Packet Header 
iph.ihl = 5; 
iph.version = 4; 
iph.tos = 0; 
iph.tot_len = sizeof(struct iphdr) + packetsize; 
iph.id = rand_cmwc(); 
iph.frag_off = 0; 
iph.ttl = MAXTTL; 
iph.protocol = IPPROTO_TCP; 
iph.check = 0; 
iph.saddr = source_ip; 
iph.daddr = serv.sin_addr.s_addr; 

// Create TCP Header 
tcph.source = htons (1234); 
tcph.dest = htons (80); 
tcph.seq = 0; 
tcph.ack_seq = 0; 
tcph.doff = 5;  
tcph.fin=0; 
tcph.syn=1; 
tcph.rst=0; 
tcph.psh=0; 
tcph.ack=0; 
tcph.urg=0; 
tcph.window = htons (5840); 
tcph.check = 0; 
tcph.urg_ptr = 0; 


pseudohead.src_addr = iph->saddr; 
pseudohead.dst_addr = iph->daddr; 
pseudohead.dummy = 0; 
pseudohead.proto = iph->protocol; 
pseudohead.length = htons(sizeof(struct tcphdr) + packetsize); 

tcp_chk_construct.pshd = pseudohead; 
tcp_chk_construct.tcphd = tcph; 
memcpy(tcp_chk_construct.tcpdata, buffer, packetsize); 

tcph->check = in_cksum((unsigned short *) &tcp_chk_construct, 
          sizeof(struct tcp_pseudo) + sizeof(struct tcphdr) + packetsize); 



memcpy(packetsize, (char *) &iph 
     , sizeof(iphdr)); 
memcpy(packetsize + sizeof(iphdr), (char *) &tcph 
     , sizeof(tcphdr)); 
memcpy(packetsize + sizeof(iphdr) + sizeof(tcphdr, buffer, packetsize); 



if (sendto (sockfd,  /* our socket */ 
      buffer, /* the buffer containing headers and data */ 
      iph->tot_len, /* total length of our datagram */ 
      0,  /* routing flags, normally always 0 */ 
      (struct sockaddr *) &serv, /* socket addr, just like in */ 
      sizeof (serv)) < 0)  /* a normal send() */ 
    { 
     printf ("error\n"); 
    } 
else 
    { 
     printf ("Packet Send \n"); 
    } 
     } 

Я использую netinet/ip.h и netinet/tcp.h сделать фактический пакет TCP, но я получаю следующие ошибки при компиляции мой код:

error: variable has incomplete type 'struct iphdr'

struct iphdr iph;

forward declaration of 'struct iphdr'

struct iphdr iph;

error: invalid application of 'sizeof' to an incomplete type 'struct iphdr'

iph.tot_len = sizeof(struct iphdr) + packetsize;

error: no member named 'source' in 'struct tcphdr'

tcph.source = htons (1234);

error: no member named 'dest' in 'struct tcphdr'

tcph.dest = htons (80);

и так далее для заголовка tcp.

+0

struct iphdr * iph; struct tcphdr * tcph; Эти указатели используются без выделения. – cm161

+0

@ cm161 как бы исправить эту ошибку – user243

+1

Изучив ваш код w.r.t. * iph и * tcph, они не нужны в качестве указателя. memcpy() вызовы с & iph и & tcph идут не так, если вы собираетесь использовать его в качестве указателей (после правильного выделения). Строковый экземпляр будет работать нормально. Определите экземпляры как struct iphdr iph; struct tcphdr tcph; Затем замените все места, где iph-> и tcph-> разыменование используется с iph. и tcph. (замена -> с. оператором). Надеемся, что вы включили исправления, предложенные @Haris. – cm161

ответ

2

По одному за раз.

warning: incompatible pointer to integer conversion initializing 'char' with an expression of type 'char [12]' [-Wint-conversion] char source_ip = "192.168.2.1";

Это связано с тем, что вы пытаетесь сохранить строку буквального в char переменной. Измените строку на

char* source_ip = "192.168.2.1"; 

warning: implicit declaration of function 'inet_addr' is invalid in C99 [-Wimplicit-function-declaration] serv.sin_addr.s_addr = inet_addr ("8.8.8.8");

Для этого, включите заголовок #include <arpa/inet.h>


0

только ошибка компиляции решена версию исходного кода. Не гарантируется.
[Компилятор используется - gcc 4.9.2 on Ubuntu 15.04]
Некоторый код прокомментирован, так как я не мог понять его использование или нашел его неоднозначным (например, использование переменной массива «packetsize» - это массив «int», но используется в выражение для вычисления длины с использованием базового адреса массива).

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <sys/socket.h> 
#include <sys/types.h> 
#include <netinet/in.h> 
#include <netinet/ip.h> 
#include <netinet/tcp.h> 
#include <arpa/inet.h> 

int main(void) 
{ 
    char buffer[1024]; 
    int packetsize[100]; 
    char *source_ip = "192.168.2.1"; 

    struct sockaddr_in serv; 
    struct iphdr iph; 
    struct tcphdr tcph; 

    int sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_TCP); 
    serv.sin_family = AF_INET; 
    serv.sin_port = htons(80); 
    serv.sin_addr.s_addr = inet_addr ("8.8.8.8"); 

    struct tcp_pseudo 
    { 
     uint32_t src_addr; 
     uint32_t dst_addr; 
     uint8_t zero; 
     uint8_t proto; 
     uint16_t length; 
    } pseudohead; 

    struct help_checksum 
    { 
     struct tcp_pseudo pshd; 
     struct tcphdr tcphd; 
     char tcpdata[1024]; 
    } tcp_chk_construct; 

    // Create Packet Header 
    iph.ihl = 5; 
    iph.version = 4; 
    iph.tos = 0; 
    //iph.tot_len = sizeof(struct iphdr) + packetsize; 
    iph.tot_len = sizeof(struct iphdr) + sizeof(struct tcphdr); 
    iph.id = rand_cmwc(); 
    iph.frag_off = 0; 
    iph.ttl = MAXTTL; 
    iph.protocol = IPPROTO_TCP; 
    iph.check = 0; 
    iph.saddr = inet_addr(source_ip); 
    iph.daddr = serv.sin_addr.s_addr; 

    // Create TCP Header 
    tcph.source = htons (1234); 
    tcph.dest = htons (80); 
    tcph.seq = 0; 
    tcph.ack_seq = 0; 
    tcph.doff = 5;  
    tcph.fin=0; 
    tcph.syn=1; 
    tcph.rst=0; 
    tcph.psh=0; 
    tcph.ack=0; 
    tcph.urg=0; 
    tcph.window = htons (5840); 
    tcph.check = 0; 
    tcph.urg_ptr = 0; 

    //pseudohead.src_addr = iph.saddr; 
    //pseudohead.dst_addr = iph.daddr; 
    //pseudohead.dummy = 0; 
    //pseudohead.proto = iph.protocol; 
    //pseudohead.length = htons(sizeof(struct tcphdr) + packetsize); 

    //tcp_chk_construct.pshd = pseudohead; 
    //tcp_chk_construct.tcphd = tcph; 
    //memcpy(tcp_chk_construct.tcpdata, buffer, packetsize); 

    //tcph.check = in_cksum((unsigned short *) &tcp_chk_construct, sizeof(struct tcp_pseudo) + sizeof(struct tcphdr) + packetsize); 

    memcpy((void *)buffer, (void *) &iph , sizeof(struct iphdr)); 
    memcpy((void *)buffer + sizeof(struct iphdr), (void *) &tcph , sizeof(struct tcphdr)); 
    //memcpy(packetsize + sizeof(struct iphdr) + sizeof(struct tcphdr), buffer, packetsize); 

    if (sendto (sockfd, buffer, iph.tot_len, 0, (struct sockaddr *) &serv, sizeof (serv)) < 0) 
    { 
     printf ("error\n"); 
    } 
    else 
    { 
     printf ("Packet Send \n"); 
    } 

    return 0; 
} 
+0

в стороне от ошибки packetsize, я все еще получаю «iphdr» uneclared (сначала используйте эту функцию). наряду с ошибкой: «tcphdr» undeclared (сначала используйте эту функцию) @ cm161 – user243

Смежные вопросы