【问题标题】:TCP Packet Sender errorsTCP 数据包发送方错误
【发布时间】:2015-10-25 15:23:06
【问题描述】:

我一直在尝试使用以下代码在 c 中创建一个 tcp 数据包发送方

#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.hnetinet/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 标头等等。

【问题讨论】:

  • 结构 iphdr *iph;结构 tcphdr *tcph;这些指针无需分配即可使用。
  • @cm161 我该如何解决这个错误
  • 在研究了您的代码 w.r.t. *iph 和 *tcph,你不需要它们作为指针。如果您打算将其用作指针(在正确分配之后),使用 &iph 和 &tcph 调用 memcpy() 会出错。结构实例可以正常工作。将实例定义为 struct iphdr iph;结构 tcphdr tcph;然后,用 iph 替换所有使用 iph-> 和 tcph-> 取消引用的地方。和tcph。 (将 -> 替换为 . 运算符)。希望您已合并@Haris 建议的更正。
  • 我已经按照你和哈里斯所说的做了,但是得到了我在问题@cm161 中更新的新错误
  • 我用你的代码检查编译错误。我没有得到你提到的错误。之前在 stackoverflow stackoverflow.com/questions/13620607/… 上讨论了类似的主题。希望对您有所帮助。

标签: c compiler-errors


【解决方案1】:

一次一个。

警告:使用“char [12]”类型的表达式初始化“char”的整数转换指针不兼容 [-Wint-conversion] char source_ip = "192.168.2.1";

这是因为您尝试将字符串文字保存在 char 变量中。将行改为

char* source_ip = "192.168.2.1";

警告:函数“inet_addr”的隐式声明在 C99 [-Wimplicit-function-declaration] serv.sin_addr.s_addr = inet_addr ("8.8.8.8") 中无效;

为此,请包含标题#include &lt;arpa/inet.h&gt;


【讨论】:

    【解决方案2】:

    只有原始代码的编译错误解决版本。不保证运行。
    [使用的编译器 - Ubuntu 15.04 上的 gcc 4.9.2]
    注释了一些代码,因为我无法理解它的用法或发现它模棱两可(例如,使用 '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;
    }
    

    【讨论】:

    • 除了数据包大小错误,我仍然得到一个未声明的“iphdr”(首先使用这个函数)。连同错误:'tcphdr' undeclared (首先使用这个函数)@cm161
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-23
    • 2015-04-10
    • 1970-01-01
    • 1970-01-01
    • 2015-04-16
    • 1970-01-01
    • 2017-12-28
    相关资源
    最近更新 更多