diff -uNr netkit-ftp-0.16/ftp/ftp.c netkit-ftp-0.16.acme/ftp/ftp.c --- netkit-ftp-0.16/ftp/ftp.c Mon Dec 13 18:33:20 1999 +++ netkit-ftp-0.16.acme/ftp/ftp.c Fri Nov 30 20:06:42 2001 @@ -50,6 +50,11 @@ #include #include +#include +#include +#include +#define AF_LLC 26 + #include #include #include @@ -68,8 +73,14 @@ int data = -1; off_t restart_point = 0; -static struct sockaddr_in hisctladdr; -static struct sockaddr_in data_addr; +static union { + struct sockaddr_in ip; + struct sockaddr_llc llc; +} hisctladdr, data_addr; + +static struct sockaddr* serv_addr = (struct sockaddr*)&hisctladdr; +static int addrlen = sizeof(hisctladdr.ip); + static struct sockaddr_in myctladdr; static int ptflag = 0; static sigjmp_buf recvabort; @@ -95,6 +106,17 @@ FILE *cin, *cout; static FILE *dataconn(const char *); +static int get_hwaddr(int skfd, char* ifname, unsigned char* dest) +{ + struct ifreq ifr; + + strcpy(ifr.ifr_name, ifname); + if (ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0) + memset(dest, 0, IFHWADDRLEN); + else + memcpy(dest, ifr.ifr_hwaddr.sa_data, IFHWADDRLEN); +} + char * hookup(char *host, int port) { @@ -104,50 +126,72 @@ static char hostnamebuf[256]; memset(&hisctladdr, 0, sizeof(hisctladdr)); - if (inet_aton(host, &hisctladdr.sin_addr)) { - hisctladdr.sin_family = AF_INET; + if (inet_aton(host, &hisctladdr.ip.sin_addr)) { + serv_addr->sa_family = AF_INET; strncpy(hostnamebuf, host, sizeof(hostnamebuf)); hostnamebuf[sizeof(hostnamebuf)-1]=0; + hisctladdr.ip.sin_port = port; } else { hp = gethostbyname(host); - if (hp == NULL) { - fprintf(stderr, "ftp: %s: ", host); - herror((char *)NULL); - code = -1; - return((char *) 0); + if (hp) { + serv_addr->sa_family = hp->h_addrtype; + hisctladdr.ip.sin_port = port; + if (hp->h_length > sizeof(hisctladdr.ip.sin_addr)) { + hp->h_length = sizeof(hisctladdr.ip.sin_addr); + } + memcpy(&hisctladdr.ip.sin_addr, hp->h_addr_list[0], + hp->h_length); + strncpy(hostnamebuf, hp->h_name, sizeof(hostnamebuf)); + hostnamebuf[sizeof(hostnamebuf)-1] = 0; + } else { + struct ether_addr *e = ether_aton(host); + + if (e) { + passivemode = 1; + hisctladdr.llc.sllc_family = AF_LLC; + hisctladdr.llc.sllc_arphrd = ARPHRD_ETHER; + addrlen = sizeof(hisctladdr.llc); + hisctladdr.llc.sllc_dsap = 90; + memcpy(hisctladdr.llc.sllc_dmac, + e->ether_addr_octet, IFHWADDRLEN); + memcpy(hisctladdr.llc.sllc_smac, + e->ether_addr_octet, IFHWADDRLEN); + strncpy(hostnamebuf, host, sizeof(hostnamebuf)); + hostnamebuf[sizeof(hostnamebuf)-1] = 0; + } else { + fprintf(stderr, "ftp: %s: ", host); + herror((char *)NULL); + code = -1; + return((char *) 0); + } } - hisctladdr.sin_family = hp->h_addrtype; - if (hp->h_length > (int)sizeof(hisctladdr.sin_addr)) { - hp->h_length = sizeof(hisctladdr.sin_addr); - } - memcpy(&hisctladdr.sin_addr, hp->h_addr_list[0], hp->h_length); - (void) strncpy(hostnamebuf, hp->h_name, sizeof(hostnamebuf)); - hostnamebuf[sizeof(hostnamebuf)-1] = 0; } hostname = hostnamebuf; - s = socket(hisctladdr.sin_family, SOCK_STREAM, 0); + s = socket(serv_addr->sa_family, SOCK_STREAM, 0); if (s < 0) { perror("ftp: socket"); code = -1; return (0); } - hisctladdr.sin_port = port; - while (connect(s, (struct sockaddr *)&hisctladdr, sizeof (hisctladdr)) < 0) { - if (hp && hp->h_addr_list[1]) { + if (serv_addr->sa_family == AF_LLC) + get_hwaddr(s, "eth0", hisctladdr.llc.sllc_smac); + while (connect(s, serv_addr, addrlen) < 0) { + if (serv_addr->sa_family != AF_LLC && + hp && hp->h_addr_list[1]) { int oerrno = errno; fprintf(stderr, "ftp: connect to address %s: ", - inet_ntoa(hisctladdr.sin_addr)); + inet_ntoa(hisctladdr.ip.sin_addr)); errno = oerrno; perror((char *) 0); hp->h_addr_list++; - memcpy(&hisctladdr.sin_addr, hp->h_addr_list[0], + memcpy(&hisctladdr.ip.sin_addr, hp->h_addr_list[0], hp->h_length); fprintf(stdout, "Trying %s...\n", - inet_ntoa(hisctladdr.sin_addr)); + inet_ntoa(hisctladdr.ip.sin_addr)); (void) close(s); - s = socket(hisctladdr.sin_family, SOCK_STREAM, 0); + s = socket(serv_addr->sa_family, SOCK_STREAM, 0); if (s < 0) { perror("ftp: socket"); code = -1; @@ -166,9 +210,12 @@ goto bad; } #ifdef IP_TOS - tos = IPTOS_LOWDELAY; - if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0) - perror("ftp: setsockopt TOS (ignored)"); + if (serv_addr->sa_family != AF_LLC) { + tos = IPTOS_LOWDELAY; + if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, + sizeof(int)) < 0) + perror("ftp: setsockopt TOS (ignored)"); + } #endif cin = fdopen(s, "r"); cout = fdopen(s, "w"); @@ -598,7 +645,7 @@ case TYPE_I: case TYPE_L: errno = d = 0; - while ((c = read(fileno(fin), buf, sizeof (buf))) > 0) { + while ((c = read(fileno(fin), buf, 1400)) > 0) { bytes += c; for (bufp = buf; c > 0; c -= d, bufp += d) if ((d = write(fileno(dout), bufp, c)) <= 0) @@ -939,7 +986,7 @@ } if (c < 0) { if (errno != EPIPE) - perror("netin"); + perror("netin1"); bytes = -1; } if (d < c) { @@ -1024,7 +1071,7 @@ } if (ferror(din)) { if (errno != EPIPE) - perror("netin"); + perror("netin2"); bytes = -1; } if (ferror(fout)) @@ -1091,7 +1138,7 @@ u_long a1,a2,a3,a4,p1,p2; if (passivemode) { - data = socket(AF_INET, SOCK_STREAM, 0); + data = socket(serv_addr->sa_family, SOCK_STREAM, 0); if (data < 0) { perror("ftp: socket"); return(1); @@ -1121,28 +1168,39 @@ return(1); } - data_addr.sin_family = AF_INET; - data_addr.sin_addr.s_addr = htonl((a1 << 24) | (a2 << 16) | - (a3 << 8) | a4); - data_addr.sin_port = htons((p1 << 8) | p2); - - if (connect(data, (struct sockaddr *) &data_addr, - sizeof(data_addr))<0) { + if (0) { + data_addr.ip.sin_family = AF_INET; + data_addr.ip.sin_addr.s_addr = htonl((a1 << 24) | + (a2 << 16) | (a3 << 8) | a4); + data_addr.ip.sin_port = htons((p1 << 8) | p2); + } else { + memset(&data_addr.llc, 0, sizeof(data_addr.llc)); + data_addr.llc.sllc_family = AF_LLC; + data_addr.llc.sllc_arphrd = ARPHRD_ETHER; + data_addr.llc.sllc_dsap = 92; + memcpy(data_addr.llc.sllc_dmac, + hisctladdr.llc.sllc_dmac, IFHWADDRLEN); + memcpy(data_addr.llc.sllc_smac, + hisctladdr.llc.sllc_smac, IFHWADDRLEN); + } + if (connect(data, (struct sockaddr *)&data_addr, addrlen) < 0) { perror("ftp: connect"); return(1); } #ifdef IP_TOS - tos = IPTOS_THROUGHPUT; - if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&tos, - sizeof(tos)) < 0) - perror("ftp: setsockopt TOS (ignored)"); + if (serv_addr->sa_family != AF_LLC) { + tos = IPTOS_THROUGHPUT; + if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&tos, + sizeof(tos)) < 0) + perror("ftp: setsockopt TOS (ignored)"); + } #endif return(0); } noport: - data_addr = myctladdr; + data_addr.ip = myctladdr; if (sendport) - data_addr.sin_port = 0; /* let system pick one */ + data_addr.ip.sin_port = 0; /* let system pick one */ if (data != -1) (void) close(data); data = socket(AF_INET, SOCK_STREAM, 0); @@ -1172,8 +1230,8 @@ if (listen(data, 1) < 0) perror("ftp: listen"); if (sendport) { - a = (char *)&data_addr.sin_addr; - p = (char *)&data_addr.sin_port; + a = (char *)&data_addr.ip.sin_addr; + p = (char *)&data_addr.ip.sin_port; #define UC(b) (((int)b)&0xff) result = command("PORT %d,%d,%d,%d,%d,%d", @@ -1189,9 +1247,12 @@ if (tmpno) sendport = 1; #ifdef IP_TOS - on = IPTOS_THROUGHPUT; - if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0) - perror("ftp: setsockopt TOS (ignored)"); + if (serv_addr->sa_family != AF_LLC) { + on = IPTOS_THROUGHPUT; + if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&on, + sizeof(int)) < 0) + perror("ftp: setsockopt TOS (ignored)"); + } #endif return (0); bad: @@ -1220,9 +1281,12 @@ (void) close(data); data = s; #ifdef IP_TOS - tos = IPTOS_THROUGHPUT; - if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0) - perror("ftp: setsockopt TOS (ignored)"); + if (serv_addr->sa_family != AF_LLC) { + tos = IPTOS_THROUGHPUT; + if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, + sizeof(int)) < 0) + perror("ftp: setsockopt TOS (ignored)"); + } #endif return (fdopen(data, lmode)); } @@ -1329,8 +1393,8 @@ ip->name[0] = 0; } hostname = op->name; - ip->hctl = hisctladdr; - hisctladdr = op->hctl; + ip->hctl = hisctladdr.ip; + hisctladdr.ip = op->hctl; ip->mctl = myctladdr; myctladdr = op->mctl; ip->in = cin;