Search code examples
cstring-parsing

FTP server PORT command parsing issue


I'll try to keep this simple. Basically, whenever I call ls from the FTP command prompt, it always returns a 425, as seen in the relevant if statement in the code below:

It apparently is due to overflow in the line

sprintf(ip_decimal, "%d.%d.%d.%d", act_ip[0], act_ip[1], act_ip[2], act_ip[3]);
         local_data_addr_act.sin_addr.s_addr=inet_addr(ip_decimal);

Can anyone explain to me why this line is changing all my values for my IP address to 255?

Full code is below.

else if(!strcmp(command,"PORT"))
    {
     int act_port[2];
     int act_ip[4], port_dec;
     char ip_decimal[40];
     active=1;
     sscanf(command, "PORT %d,%d,%d,%d,%d,%d",&act_ip[0],&act_ip[1],&act_ip[2],&act_ip[3], &act_port[0], &act_port[1]);
     local_data_addr_act.sin_family=AF_INET;
     sprintf(ip_decimal, "%d.%d.%d.%d", act_ip[0], act_ip[1], act_ip[2], act_ip[3]);
     local_data_addr_act.sin_addr.s_addr=inet_addr(ip_decimal);
     port_dec=act_port[0];
     port_dec=port_dec<<8;
     port_dec=port_dec+act_port[1];
     local_data_addr_act.sin_port=htons(port_dec);
     if (connect(s_data_act,(struct sockaddr*)&local_data_addr_act, (int)sizeof(struct sockaddr))!=0){
       printf("%s%d\n",inet_ntoa(local_data_addr_act.sin_addr),ntohs(local_data_addr_act.sin_port)); 
       sprintf(buf, "425\r\n"); 
       send(sock2, buf, strlen(buf), 0);
       close(s_data_act);
      }
     else{
     sprintf(buf, "200\r\n");
     send(sock2, buf, strlen(buf), 0); 
      }
}

However, I have no idea why it is doing this. What should I do to fix this problem?

The server returns:

PORT 127,0,0,1,217,89

PORT
255.255.255.25535028

sock1 and sock2 are my sockets.

If you need more info, or think the error is somewhere else, please ask, and I'll be all to happy to provide it.


Solution

  • if(!strcmp(command,"PORT"))
    {
         ...
         sscanf(command, "PORT %d,%d,%d,%d,%d,%d",&act_ip[0],&act_ip[1],&act_ip[2],&act_ip[3], &act_port[0], &act_port[1]);
    

    To get to the sscanf call, the command must be equal to "PORT". So obviously the command variable does not include the arguments. Hence the sscanf call fails. You'd know had you test the sscanf return value.


    You should learn using a debugger. Without that your chances on implementing an FTP server are low.

    You should better pick an existing open-source implementation of FTP server, rather than implementing your own. That's an immense task, even an experienced developer would have troubles accomplishing.