1

由于这些错误消息,我在编译代码时遇到了一些麻烦(我怀疑它们有些相关)

In function ‘forgepacket’:
error: expected specifier-qualifier-list before ‘send_tcp’

In function ‘send_tcp’:
error: invalid application of ‘sizeof’ to incomplete type ‘struct ipheader’
error: invalid application of ‘sizeof’ to incomplete type ‘struct tcpheader’

error: dereferencing pointer to incomplete type

每次我尝试访问ip->iphtcp->tcph。现在我已经收集到问题在于 and 的定义struct ipheaderstruct tcpheader但我无法真正弄清楚是什么。

我一直在查看与上述类似的错误消息问题,但我无法弄清楚。

这是代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <getopt.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>

#define VERSION "1.0"
#define PCKT_LEN 8192

/* Prototypes */    

void forgepacket (unsigned int, unsigned int, unsigned short, unsigned short);
int send_tcp(); 
void usage(); 

/* Checksum */
unsigned short checksum (unsigned short *pac, int len)
{ 
    unsigned long sum;
    for (sum = 0; len > 0; len--)
            sum += *pac++;
    sum = (sum >> 16) + (sum & 0xffff);
    sum += (sum >> 16);
    return(~sum);
}               

in_addr_t sip;
in_addr_t dip;
int sport;
int dport;                  

int main(int argc,char **argv)
{
int c;

/* Are we in root? */   
if(geteuid() !=0)
    {
        printf("Root access is required to run this program.\n\n");
        exit(0);        
    }   

while (1)
    {
        static struct option long_options[] =
            {
                /* Options */
            {"send",       no_argument,       0, 's'}, /* args s and r have no function yet */
            {"recieve",    no_argument,       0, 'r'},
            {"file",       required_argument, 0, 'f'}, 
            {"destip",     required_argument, 0, 'i'},
            {"destport",   required_argument, 0, 'p'},
            {"sourceip",   required_argument, 0, 'o'},
            {"sourceport", required_argument, 0, 't'},
            {0, 0, 0, 0}
            };

           int option_index = 0;

           c = getopt_long (argc, argv, "srf:d:i:p:o:t:",
                        long_options, &option_index);

                      /* Detect the end of the options. */
           if (c == -1)
             break;

           switch (c)
             {
             case 0:
               /* If this option set a flag, do nothing else now. */
               if (long_options[option_index].flag != 0)
             break;
               printf ("option %s", long_options[option_index].name);
               if (optarg)
             printf (" with arg %s", optarg);
               printf ("\n");
               break;

             case 's':
               puts ("option -s\n");
               break;

             case 'r':
               puts ("option -r\n");
               break;

             case 'f':
               printf ("option -f with value `%s'\n", optarg);
               break;

             case 'i':
               dip = inet_addr(optarg);
               break;

             case 'p':
               dport = htons(atoi(optarg)); 
               /* Add handling of bad/non number input here */
               break;

             case 'o': 
               sip = inet_addr(optarg);
               break;

             case 't': 
               sport = htons(atoi(optarg));
               break;

             case '?':
               /* Error message printed */
               break;

             default:
               abort ();
             }
         }

           /* Print any remaining command line arguments (not options). */
        if (optind < argc)
    {
        printf ("\nNon-option ARGV-elements: ");
        while (optind < argc)
        printf ("%s ", argv[optind++]);
        putchar ('\n');
    }

            /* check if all mandatory options are set and for unknown arguments */
            /* This really needs changing... */
     if (dip, sip, dport, sport == 0)
        {
            usage();
            return (-1);
        }


    forgepacket(dip, sip, dport, sport);

    getchar ();
    exit (0);

}

void forgepacket(unsigned int sourceip, unsigned int destip, unsigned short sourceport,
                 unsigned short destport)
{           
    /* IP header structure */
    struct ipheader {

        unsigned char      iph_ihl:5, 
                           iph_ver:4;
        unsigned char      iph_tos;
        unsigned short int iph_len;
        unsigned short int iph_id;
        unsigned char      iph_flags;
        unsigned short int iph_offset;
        unsigned char      iph_ttl;
        unsigned char      iph_protocol;
        unsigned short int iph_chksum;
        unsigned int       iph_sourceip;
        unsigned int       iph_destip;

        };

    /* TCP header structure */      
    struct tcpheader {

        unsigned short int tcph_sourceport;
        unsigned short int tcph_destport;
        unsigned int       tcph_seqnum;
        unsigned int       tcph_acknum;
        unsigned char      tcph_reserved:4, tcph_offset:4;
        unsigned int

            tcp_res1:4,       
            tcph_hlen:4,      
            tcph_fin:1,       
            tcph_syn:1,       
            tcph_rst:1,       
            tcph_psh:1,       
            tcph_ack:1,       
            tcph_urg:1,       
            tcph_res2:2;

        unsigned short int tcph_win;
        unsigned short int tcph_chksum;
        unsigned short int tcph_urgptr;

        send_tcp();
        };
}           

    int send_tcp()
        {
            int sock, one = 1;
            char buffer[PCKT_LEN];
            struct sockaddr_in sin, din;
            const int *val = &one;

            sock = socket(PF_INET, SOCK_RAW, IPPROTO_TCP);
            if (sock < 0)
                {
                    printf("\nError: socket()\n\n");
                    exit (-1);
                }
            else
                    printf ("\nsocket() - Using SOCK_RAW and TCP protocol is OK.\n\n");

            /* Size of the headers */           
            struct ipheader *ip = (struct ipheader *) buffer;
            struct tcpheader *tcp = (struct tcpheader *) (buffer + sizeof (struct ipheader));
            memset (buffer, 0, PCKT_LEN);

            /* IP attributes */
            ip->iph_ihl = 5;
            ip->iph_ver = 4;
            ip->iph_tos = 16;
            ip->iph_len = sizeof(struct ipheader) + sizeof(struct tcpheader);
            ip->iph_id = htons(54321);
            ip->iph_offset = 0;
            ip->iph_ttl = 64;
            ip->iph_protocol = 6;
            ip->iph_chksum = 0; 

            ip->iph_sourceip = sip;
            ip->iph_destip = dip;

            /* TCP attributes */
            tcp->tcph_sourceport = sport;
            tcp->tcph_destport = dport;

            tcp->tcph_seqnum = htonl(1);
            tcp->tcph_acknum = 0;
            tcp->tcph_offset = 5;
            tcp->tcph_syn = 1;
            tcp->tcph_ack = 0;
            tcp->tcph_win = htons(32767);
            tcp->tcph_chksum = 0; 
            tcp->tcph_urgptr = 0;

            ip->iph_chksum = checksum ((unsigned short *) buffer, (sizeof (struct ipheader )+ sizeof (struct tcpheader)));

            /* Address family */ 
            sin.sin_family = AF_INET;
            din.sin_family = AF_INET;

            /* Source port */
            sin.sin_port = sport;
            din.sin_port = dport;

            /* Source IP */
            sin.sin_addr.s_addr = sip;
            din.sin_addr.s_addr = dip;      

            /* Tell the Kernel we're building our own packet */
            if ((setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&one, sizeof (one))) < 0)
                {
                    printf("\nError: Can't set socketoptions\n\n");
                    return (-1);
                }

            /* Send */
            if (sendto(sock, buffer, ip->iph_len, 0, (struct sockaddr *)&sin, sizeof(sin)) < 0)
                {
                    printf("\nError: Can't send packet\n\n");
                    return (-1);
                }

            else
                    printf("Packet sent to %d", dip); 

            close(sock);
    }           

void usage() 

{
 /* This is the user manual */  

    printf("\nTCP project %s\n\n", VERSION);

    printf("Usage:  -s -f <file> -i <destip> -p <destport> -o <sourceip> -t <sourceport>\n\n"); 

    printf("-s, --send,         Puts program in send mode\n");
    printf("-r, --recieve,      Puts program in recieve mode\n"); 
    printf("-f, --file,         Specify file containing steganographic message\n");         
    printf("-i, --destip,       Destination IP address\n"); 
    printf("-p, --destport,     Destination port\n"); 
    printf("-o, --sourceip          Source IP address\n"); 
    printf("-t, --sourceport        Source port\n"); 

}   
4

2 回答 2

1

1) 对 send_tcp 的调用应该移到 sturct 定义之外,当然:

};
send_tcp(); 

2) struct tcpheader 和 ipheader 应该移出 forgepacket

代码现在编译得很好。

如果我可以补充,我建议您学习 C 并正确缩进您的代码!

于 2012-07-21T23:01:52.410 回答
0

只需添加此头文件。它会起作用的。

/* Ethernet header */
struct ethheader {
    u_char  ether_dhost[6];    /* destination host address */
    u_char  ether_shost[6];    /* source host address */
    u_short ether_type;                     /* IP? ARP? RARP? etc */
};

/* IP Header */
struct ipheader {
  unsigned char      iph_ihl:4, //IP header length
                     iph_ver:4; //IP version
  unsigned char      iph_tos; //Type of service
  unsigned short int iph_len; //IP Packet length (data + header)
  unsigned short int iph_ident; //Identification
  unsigned short int iph_flag:3, //Fragmentation flags
                     iph_offset:13; //Flags offset
  unsigned char      iph_ttl; //Time to Live
  unsigned char      iph_protocol; //Protocol type
  unsigned short int iph_chksum; //IP datagram checksum
  struct  in_addr    iph_sourceip; //Source IP address
  struct  in_addr    iph_destip;   //Destination IP address
};

/* ICMP Header  */
struct icmpheader {
  unsigned char icmp_type; // ICMP message type
  unsigned char icmp_code; // Error code
  unsigned short int icmp_chksum; //Checksum for ICMP Header and data
  unsigned short int icmp_id;     //Used for identifying request
  unsigned short int icmp_seq;    //Sequence number
};

/* UDP Header */
struct udpheader
{
  u_int16_t udp_sport;           /* source port */
  u_int16_t udp_dport;           /* destination port */
  u_int16_t udp_ulen;            /* udp length */
  u_int16_t udp_sum;             /* udp checksum */
};

/* TCP Header */
struct tcpheader {
    u_short tcp_sport;               /* source port */
    u_short tcp_dport;               /* destination port */
    u_int   tcp_seq;                 /* sequence number */
    u_int   tcp_ack;                 /* acknowledgement number */
    u_char  tcp_offx2;               /* data offset, rsvd */
#define TH_OFF(th)      (((th)->tcp_offx2 & 0xf0) >> 4)
    u_char  tcp_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
#define TH_ECE  0x40
#define TH_CWR  0x80
#define TH_FLAGS        (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)
    u_short tcp_win;                 /* window */
    u_short tcp_sum;                 /* checksum */
    u_short tcp_urp;                 /* urgent pointer */
};

/* Psuedo TCP header */
struct pseudo_tcp
{
        unsigned saddr, daddr;
        unsigned char mbz;
        unsigned char ptcl;
        unsigned short tcpl;
        struct tcpheader tcp;
        char payload[1500];
};
于 2020-04-21T16:29:35.653 回答