2012-07-20 4 views
0

TCP 패킷을 보낼 수있는 프로그램을 만들려고하지만 send 함수를 테스트하기 위해 코드를 컴파일 할 때 실행 방식이 올바르지 않습니다. 인수가 주어지면 getchar으로 건너 뛰고 함수가 전혀 호출되지 않은 것처럼 프로그램을 종료합니다. 지금 나는 특별히 경험이 없으며 아마도 어리석은 질문이지만 다른 곳에서 해결책을 찾을 수 없었습니다. 내 추측은 내가 어떻게 든 그것을 잘못 호출하고 아마도 send_tcp 함수는 forgepacket 함수 안에있을 수 없다는 것입니다.C - 함수가 실행되지 않습니다. 호출 오류?

다음은 내 코드 (전혀 완료되지는 않았지만 약간의 테스트를 실행하기에 충분해야 함)이며 문제점을주는 함수는 forge 패킷입니다.

#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); 
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, r and f 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 ("non-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; 

     }; 

    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"); 

} 

답변

1

send_tcp()의 기능 정의가 forgepacket()의 함수 정의 내 (I이가 ??도 가능 몰랐)를 표시하지만, 아무 전화도 없다.

/* Prototype. */ 
int send_tcp(); /* add whatever parameters are required. */ 

forgepacket()send_tcp() 외부의 정의를 이동 forgepacket()send_tcp()에 호출을 추가 : send_tcp() 당신이 forgepacket() 위해 가지고 배열을 복제합니다.

1

C는 기본적으로 중첩 기능을 허용하지 않습니다. 게다가 코드가 있다고해도 send_tcp에 대한 호출이 보이지 않고 있습니다 (빠른 검색에서 표시되지 않을 수도 있음).

forge_packet에서 send_tcp 기능을 해제하고 필요한 데이터를 매개 변수로 전달하면 어떻게됩니까?

관련 문제