Skip to content

Instantly share code, notes, and snippets.

@jsianes
Created August 16, 2015 11:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jsianes/ab0c915819a5ae4e0ed8 to your computer and use it in GitHub Desktop.
Save jsianes/ab0c915819a5ae4e0ed8 to your computer and use it in GitHub Desktop.
Patch for 'ftp.c' file of ncftp v.2.3.5 to use within AWS instances
--- libncftp/ftp.c.orig 2009-10-23 23:31:22.000000000 +0000
+++ libncftp/ftp.c 2015-08-15 19:49:04.014889944 +0000
@@ -5,6 +5,73 @@
*
*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <curl/curl.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+
+#define AWS_PUBLIC_IPV4_ADDRESS_URL "http://169.254.169.254/latest/meta-data/public-ipv4"
+
+struct MemoryStruct {
+ char *memory;
+ size_t size;
+};
+
+static size_t
+WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
+{
+ size_t realsize = size * nmemb;
+ struct MemoryStruct *mem = (struct MemoryStruct *)userp;
+
+ mem->memory = realloc(mem->memory, mem->size + realsize + 1);
+ if(mem->memory == NULL) { return 1; }
+
+ memcpy(&(mem->memory[mem->size]), contents, realsize);
+ mem->size += realsize;
+ mem->memory[mem->size] = 0;
+
+ return realsize;
+}
+
+int hostname_to_ip (char *hostname , char *ip)
+{
+ struct hostent *he;
+ struct in_addr **addr_list;
+ int i;
+
+ if ((he=gethostbyname(hostname))==NULL) { return 0; }
+ addr_list=(struct in_addr **) he->h_addr_list;
+ for(i=0;addr_list[i]!=NULL;i++) { strcpy(ip, inet_ntoa(*addr_list[i]) ); return 1; }
+ return 0;
+}
+
+int is_a_private_ip (char *the_ip)
+{
+ char *ip_number;
+ int i=0,value[4];
+
+ for (i=0;i<4;i++) { value[i]=0; }
+ ip_number = strtok (the_ip,".");
+
+ i=0;
+ while ((ip_number!=NULL)&&(i<4)) { value[i++]=atoi(ip_number); ip_number=strtok (NULL, "."); }
+
+ if ((value[0]==127)||(value[0]==10)) { return 1; }
+ if ((value[0]==192)&&(value[1]==168)) { return 1; }
+ if ((value[0]==169)&&(value[1]==254)) { return 1; }
+ if ((value[0]==172)&&(value[1]>=16)&&(value[1]<=31)) { return 1; }
+ return 0;
+}
+
+int valid_ip (int *ip)
+{
+ if ((ip[0]>0)&&(ip[1]>0)&&(ip[2]>0)&&(ip[3]>0)&&(ip[0]<256)&&(ip[1]<256)&&(ip[2]<256)&&(ip[3]<256)) { return 1; } else { return 0; }
+}
+
#include "syshdrs.h"
#ifdef PRAGMA_HDRSTOP
# pragma hdrstop
@@ -743,9 +810,9 @@
int
FTPSendPort(const FTPCIPtr cip, struct sockaddr_in *saddr)
{
- char *a, *p;
- int result;
ResponsePtr rp;
+ char *a, *p, the_ip[128];
+ int i=0,use_default=1,ext_aws_ipv4[4],result,resolv;
rp = InitResponse();
if (rp == NULL) {
@@ -762,8 +829,50 @@
/* Need to tell the other side which host (the address) and
* which process (port) on that host to send data to.
*/
- result = RCmd(cip, rp, "PORT %d,%d,%d,%d,%d,%d",
- UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]), UC(p[0]), UC(p[1]));
+
+ CURL *curl_handle;
+ CURLcode res;
+
+ struct MemoryStruct chunk;
+
+ chunk.memory = malloc(1);
+ chunk.size = 0;
+
+ curl_global_init(CURL_GLOBAL_ALL);
+ curl_handle = curl_easy_init();
+ curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT_MS, 5000L);
+ curl_easy_setopt(curl_handle, CURLOPT_URL, AWS_PUBLIC_IPV4_ADDRESS_URL);
+ curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
+ curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk);
+ curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
+
+ res=curl_easy_perform(curl_handle);
+ resolv=hostname_to_ip(cip->host, the_ip);
+
+ if((res==CURLE_OK)&&(chunk.size>0)) {
+ char *ip_number;
+
+ for (i=0;i<4;i++) { ext_aws_ipv4[i]=0; }
+ ip_number = strtok (chunk.memory,".");
+
+ i=0;
+ while ((ip_number!=NULL)&&(i<4)) { ext_aws_ipv4[i++]=atoi(ip_number); ip_number = strtok (NULL, "."); }
+
+ if (valid_ip(ext_aws_ipv4)) { if (resolv) { if (!is_a_private_ip(the_ip)) { use_default=0; }}}
+ free(ip_number);
+ }
+
+ if (use_default) {
+ result = RCmd(cip, rp, "PORT %d,%d,%d,%d,%d,%d",
+ UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]), UC(p[0]), UC(p[1]));
+ } else {
+ result = RCmd(cip, rp, "PORT %d,%d,%d,%d,%d,%d",
+ ext_aws_ipv4[0], ext_aws_ipv4[1], ext_aws_ipv4[2], ext_aws_ipv4[3], UC(p[0]), UC(p[1]));
+ }
+
+ curl_easy_cleanup(curl_handle);
+ free(chunk.memory);
+ curl_global_cleanup();
DoneWithResponse(cip, rp);
if (result < 0) {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment