2012-07-21 74 views
1

我遇到一些麻煩編譯我的代碼由於這些錯誤信息(我懷疑他們是有些關聯)Ç - 「的sizeof」不完全型「結構ipheader」和其他錯誤的無效申請

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。現在我已經知道問題在於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"); 

} 
+2

你確定你沒有切換'send_tcp();'和'};'? – Mysticial 2012-07-21 22:44:11

+0

'buffer'是字符數組。你確定你要這麼做嗎 ? 'struct ipheader * ip =(struct ipheader *)buffer;' – Mahesh 2012-07-21 22:47:33

+0

@Mysticial uhm ...現在你提到它了哈哈。好吧,我當然希望這很簡單。我會再試一次並回報。謝謝! – youjustreadthis 2012-07-21 22:51:18

回答

1

1)至send_tcp應sturct定義之外移動的呼叫,當然:

}; 
send_tcp(); 

2)結構tcpheader和ipheader應該被移動outside forgepacket

現在代碼編譯好了。

如果我可以添加,我建議你學習C並正確縮進你的代碼!

+0

謝謝,是的,我知道我有很多東西要學。 – youjustreadthis 2012-07-21 23:07:02

+1

如果你在Linux上工作,你可以使用「indent」來修復你的縮進,祝你好運:) – iabdalkader 2012-07-21 23:11:25

+2

問題是struct tcpheader和ipheader是在forgepacket中定義的。函數send_tcp不知道,因爲這些函數的作用域結構只在內部僞造功能,通過將它帶到外面,可以使這些結構的範圍對當前文件中的所有功能可見。此外,我建議您閱讀「K&R的C編程」 – Deepthought 2012-07-22 01:16:20