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 <arpa/inet.h>
 #include <arpa/telnet.h>
 
+#include <net/if.h>
+#include <linux/llc.h>
+#include <netinet/ether.h>
+#define AF_LLC 26
+
 #include <stdio.h>
 #include <signal.h>
 #include <string.h>
@@ -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;