Skip to contentSkip to conversation

First cut of PR430 / extended 6pack driver

PATCH In review Ralf Baechle DL5RB 18 participants 52 messages Jul 11, 2005 – Aug 2, 2005 Network drivers

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 First cut of PR430 / extended 6pack driver

Below there's a first cut of a extended 6pack driver featuring support for the PR-430 driver. It should work unchanged for non-PR430 6pack hardware. PR430 drivers frequency etc. can be configured through sysfs:

[ralf@dea linux-cvs]$ ssh -l root 172.20.1.2
[email protected]'s password:
Last login: Sun Jul 10 20:52:26 2005
[root@kiste ~]# cd /sys/class/net/sp0
[root@kiste sp0]# ls -l tnc
total 0

-r--r--r--  1 root root 4096 Jul 10 20:52 author
-rw-r--r--  1 root root 4096 Jul 10 20:52 bitrate
-r--r--r--  1 root root 4096 Jul 10 20:52 hwtype
-r--r--r--  1 root root 4096 Jul 10 20:52 major
-r--r--r--  1 root root 4096 Jul 10 20:52 minor
-rw-r--r--  1 root root 4096 Jul 10 20:52 qrg
-rw-r--r--  1 root root 4096 Jul 10 20:52 shift
-rw-r--r--  1 root root 4096 Jul 10 20:52 txpower

[root@kiste sp0]#

The use of sysfs is the main difference to DL9SAU's PR430 driver which was (ab-)using the 802.11 wireless tool for configuration; otherwise this driver is largely based on his work. Patch is against 2.6.12.

73 de DL5RB op Ralf

--
Loc. JN47BS / CQ 14 / ITU 28 / DOK A21

 6pack.c | 1385 ++++++++++++++++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 1083 insertions(+), 302 deletions(-)
drivers/net/hamradio/6pack.c +1083 -302
Index: linux-cvs/drivers/net/hamradio/6pack.c
===================================================================
@@ -5,11 +5,6 @@
  *
  * Authors:	Andreas Könsgen <[email protected]>
  *              Ralf Baechle DL5RB <[email protected]>
- *
- * Quite a lot of stuff "stolen" by Joerg Reuter from slip.c, written by
- *
- *		Laurence Culhane, <[email protected]>
- *		Fred N. van Kempen, <[email protected]>
  */
 
 #include <linux/config.h>
@@ -24,6 +19,7 @@
 #include <linux/tty.h>
 #include <linux/errno.h>
 #include <linux/netdevice.h>
+#include <linux/sysfs.h>
 #include <linux/timer.h>
 #include <net/ax25.h>
 #include <linux/etherdevice.h>
@@ -74,12 +70,61 @@
 #define SIXP_INIT_RESYNC_TIMEOUT	(3*HZ/2) /* in 1 s */
 #define SIXP_RESYNC_TIMEOUT		5*HZ	/* in 1 s */
 
-/* 6pack configuration. */
-#define SIXP_NRUNIT			31      /* MAX number of 6pack channels */
 #define SIXP_MTU			256	/* Default MTU */
 
+/*
+ * TNC430 specefic
+ */
+#define DO_AFSK		1		/* Achtung, TNC kodiert das um
+					   gegenueber seinem Mode */
+#define DO_FM           16
+#define DO_DELAY_TX	128		/* vielleicht ein Provisorium: ein paar
+					   ms txdelay */
+
 enum sixpack_flags {
-	SIXPF_ERROR,	/* Parity, etc. error	*/
+	SIXPF_ERROR,			/* Parity, etc. error	*/
+};
+
+struct hf_param_struct {
+	unsigned int	qrg;            /* Hz */
+	int		shift;          /* Shift */
+	unsigned char	mode;           /* 0:Unknown */
+					/* 1: FSK */
+					/* 2: AFSK */
+					/* 3: voice */
+	unsigned int	baud;           /* 12 = 1k2, 96 = 9k6, etc. */
+	unsigned char	txpower;	/* 0 reserved */
+					/*, 16, 64, 255 (low, mid, high) */
+	unsigned char	status254_cmd;  /* sent status 254 command /
+	                                   received info for status 254 cmd */
+	unsigned long	status254_cmd_t;/* time of last tx/rx */
+};
+
+struct hw_type_struct {
+	unsigned char	type;           /* 0: default, 4: pr430 */
+	unsigned char	author;		/* 7: dk7wj */
+	unsigned char	major;
+	unsigned char	minor;
+	unsigned char	announced;      /* announce_hardware() */
+};
+
+struct hw_struct {
+					/* meassurements */
+	char		smeter;		/* SNR  caveat: signed */
+	char		center;		/* Middlefreq */
+	unsigned char	hub;		/* messured HUB */
+	unsigned char	txpower_auto;	/* automatical power tune */
+					/* based on SN/R */
+	struct hf_param_struct	hf_want;
+	struct hf_param_struct	hf_act;
+	struct hw_type_struct	hw_type;
+};
+
+enum tnc_state {
+	TNC_UNINITIALIZED,
+	TNC_UNSYNC_STARTUP,
+	TNC_UNSYNCED,
+	TNC_IN_SYNC
 };
 
 struct sixpack {
@@ -103,7 +148,7 @@
 	/* 6pack interface statistics. */
 	struct net_device_stats stats;
 
-	int			mtu;		/* Our mtu (to spot changes!) */
+	int			mtu;		/* Our MTU (to spot changes!) */
 	int			buffsize;       /* Max buffers sizes */
 
 	unsigned long		flags;		/* Flag values/ mode etc */
@@ -119,20 +164,26 @@
 	unsigned char		status1;
 	unsigned char		status2;
 	unsigned char		tx_enable;
-	unsigned char		tnc_state;
+	enum tnc_state		tnc_state;
 
 	struct timer_list	tx_t;
 	struct timer_list	resync_t;
+	struct timer_list	status_t;
 	atomic_t		refcnt;
 	struct semaphore	dead_sem;
 	spinlock_t		lock;
+
+	struct hw_struct	hw;
 };
 
+static inline int is_hw_tnc430(const struct sixpack *sp)
+{
+	return (sp->hw.hw_type.type == 4 && sp->hw.hw_type.author == 7);
+}
+
 #define AX25_6PACK_HEADER_LEN 0
 
 static void sp_start_tx_timer(struct sixpack *);
-static void sixpack_decode(struct sixpack *, unsigned char[], int);
-static int encode_sixpack(unsigned char *, unsigned char *, int, unsigned char);
 
 /*
  * perform the persistence/slottime algorithm for CSMA access. If the
@@ -167,11 +218,45 @@
 {
 	int when = sp->slottime;
 
-	del_timer(&sp->tx_t);
-	sp->tx_t.data = (unsigned long) sp;
-	sp->tx_t.function = sp_xmit_on_air;
-	sp->tx_t.expires = jiffies + ((when + 1) * HZ) / 100;
-	add_timer(&sp->tx_t);
+	mod_timer(&sp->tx_t, jiffies + ((when + 1) * HZ) / 100);
+}
+
+/* encode an AX.25 packet into 6pack */
+
+static int encode_sixpack(unsigned char *tx_buf, unsigned char *tx_buf_raw,
+	int length, unsigned char tx_delay)
+{
+	int count = 0;
+	unsigned char checksum = 0, buf[400];
+	int raw_count = 0;
+
+	tx_buf_raw[raw_count++] = SIXP_PRIO_CMD_MASK | SIXP_TX_MASK;
+	tx_buf_raw[raw_count++] = SIXP_SEOF;
+
+	buf[0] = tx_delay;
+	for (count = 1; count < length; count++)
+		buf[count] = tx_buf[count];
+
+	for (count = 0; count < length; count++)
+		checksum += buf[count];
+	buf[length] = (unsigned char) 0xff - checksum;
+
+	for (count = 0; count <= length; count++) {
+		if ((count % 3) == 0) {
+			tx_buf_raw[raw_count++] = (buf[count] & 0x3f);
+			tx_buf_raw[raw_count] = ((buf[count] >> 2) & 0x30);
+		} else if ((count % 3) == 1) {
+			tx_buf_raw[raw_count++] |= (buf[count] & 0x0f);
+			tx_buf_raw[raw_count] =	((buf[count] >> 2) & 0x3c);
+		} else {
+			tx_buf_raw[raw_count++] |= (buf[count] & 0x03);
+			tx_buf_raw[raw_count++] = (buf[count] >> 2);
+		}
+	}
+	if ((length % 3) != 2)
+		raw_count++;
+	tx_buf_raw[raw_count++] = SIXP_SEOF;
+	return raw_count;
 }
 
 /* Encapsulate one AX.25 frame and stuff into a TTY queue. */
@@ -369,12 +454,391 @@
 	memcpy(dev->broadcast, ax25_bcast, AX25_ADDR_LEN);
 	memcpy(dev->dev_addr, ax25_test, AX25_ADDR_LEN);
 
-	SET_MODULE_OWNER(dev);
-
 	dev->flags		= 0;
 }
 
-/* Send one completely decapsulated IP datagram to the IP layer. */
+static void trace_frame(struct sixpack *sp, char *s)
+{
+	unsigned int i;
+
+	if (s)
+		printk(KERN_DEBUG "6pack: %s - ", s);
+	for (i = 0/*+1*/; i < sp->rx_count_cooked; i++) {
+		printk(KERN_DEBUG "0x%02x%s", sp->cooked_buf[i], ((i < sp->rx_count_cooked-1) ? " " : ""));
+	}
+	printk(KERN_DEBUG "\n");
+	sp->stats.rx_dropped++;
+}
+
+/* xmit status requests to tnc */
+
+static int sp_xmit_status_request(struct sixpack *sp, unsigned char *data, int len)
+{
+	unsigned char xbuff[SIXP_MTU * 2 + 4]; // needed by encode_sixpack()*2
+
+	if (len * 2 + 4 > sizeof(xbuff)) {
+		printk("6pack: status request too long: %d", len);
+		return -1;
+	}
+
+	len = encode_sixpack(data, xbuff, len, data[0]);
+
+	// still running?
+	if (!sp)
+		return -1;
+
+	if (sp->xleft <= 0) {
+		// don't interrupt me
+		//netif_stop_queue(sp->dev);
+		//sp->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
+		//sp->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
+		sp->led_state = 0x60;
+		if (sp->tty->driver->write(sp->tty, &sp->led_state, 1) < 1 || 
+				(sp->tty->driver->write(sp->tty, xbuff, len) < len)) {
+			//sp->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
+printk(KERN_DEBUG "tty busy\n");
+			return -1;
+		}
+		//if (sp->xleft > 0)
+			//sp->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
+		// hmm, the tty driver counts these status requests, so we have to correct :(
+		// but only when already > 0..
+		//if (sp->stats.tx_packets)
+			//sp->stats.tx_packets--;
+		return 0;
+	}
+	return -1;
+	// re-enable queue only if the normal xbuff is empty
+	//if (sp->xleft <= 0) {
+		//sp->tx_enable = 0;
+		//netif_wake_queue(sp->dev);
+	//}
+}
+
+/* some TNCs have status reports - polled by timer */
+
+static void status_request(unsigned long data)
+{
+	struct sixpack *sp = (struct sixpack *) data;
+
+	if (!sp->hw.hw_type.type) {
+		del_timer(&sp->status_t); /* stop timer for unknown hardware */
+		return;
+	}
+
+	/*
+	 * Provisorisch (?) hier angeordnet: TNC-Parameter abfragen
+	 * spaeter auch zyklisch, aber nicht so oft, ansonsten bei Aenderung
+	 * soll/ist 
+	 * status request is encoded as param txdelay:
+	 * txd >251 is reserved for those kinds of hack
+	 */
+	if (sp->xleft <= 0) {
+		unsigned char data[3*2];
+
+		if (!is_hw_tnc430(sp)) {
+			/* Don't start timer for unsupported hardware */
+			return;
+		}
+
+		if (sp->hw.hf_want.status254_cmd_t + HZ < jiffies) {
+
+			// every second
+
+			sp->hw.hf_want.status254_cmd_t = jiffies;
+			//if (sp->hw.hf_want.status254_cmd && sp->hw.hf_act.status254_cmd_t && sp->hw.hf_act.status254_cmd != sp->hw.hf_want.status254_cmd) {
+				//if (sp->hw.hf_act.status254_cmd_t + 10*HZ > jiffies) {
+					//goto give_some_more_time;
+				//}
+				//printk(KERN_INFO "6pack: status254 cmd %d not acked for 10s. last received was %d. got lost?\n", sp->hw.hf_want.status254_cmd, sp->hw.hf_act.status254_cmd);
+			//}
+
+			data[0] = 254;	/* Kennung TNC430-Special */
+			switch (sp->hw.hf_want.status254_cmd) {
+			case 1:
+				data[1] = 2;	/* Mode */
+				break;
+			default:
+				data[1] = 1;	/* Frequenz */
+			}
+			//printk(KERN_DEBUG "requesting %ld data[0] %d data[1] = %d, last was %d\n", jiffies, data[0], data[1], sp->hw.hf_want.status254_cmd);
+			if (sp_xmit_status_request(sp, data, 2) >= 0) {
+				// success
+				sp->hw.hf_want.status254_cmd = data[1];
+			}
+		} else {
+//give_some_more_time:
+
+			/*
+			 * nothing important to do
+			 * data[len++] = 16;	// S-Meter
+			 * sp_xmit_status_request(sp, data, len);
+			 */
+
+			/*
+			 * we send prio command 0xe8 (1110 1000): channel 0
+			 * this will put the tnc in mode 0xe8
+			 * and automaticaly leads to an s-meter response,
+			 */
+
+			/*
+			 * dummy - not actually sent.  Triggers 0xe8 via
+			 * sp_xmit_status_request() / * encode_sixpack()
+			 */
+			data[0] = 254;
+			sp_xmit_status_request(sp, data, 0);
+		}
+	}
+
+	/*
+	 * Cyclic 100ms timer
+	 */
+	mod_timer(&sp->status_t, jiffies + (HZ/10));
+}
+
+/* TNC has hardware information */
+
+static void initialize_hardware(struct sixpack *sp)
+{
+	char *type, *author;
+	int i;
+
+	sp->hw.hw_type.announced = 1;
+
+	switch (sp->hw.hw_type.type) {
+	case 4:
+		type = "PR430";
+		break;
+	case 0:
+		return;					/* do not announce */
+	default:
+		type = "[unknown]";
+	}
+
+	printk(KERN_INFO "6pack: TNC is extended-6pack capable.\n");
+
+	switch (sp->hw.hw_type.author) {
+	case 7:
+		author = "DK7WJ";
+		break;
+	default:
+		author = "[unknown]";
+	}
+	printk(KERN_INFO "6pack: TNC type %d: %s. author %d: %s. extra: %d, %d.\n",
+	       sp->hw.hw_type.type, type,
+	       sp->hw.hw_type.author, author,
+	       sp->hw.hw_type.major, sp->hw.hw_type.minor);
+
+	/*
+	 * Poll config - supported TNC types only
+	 */
+
+	if (is_hw_tnc430(sp)) {
+		unsigned char data[2];
+
+		data[0] = 254;
+		for (i = 1; i < /* 3 */ 4; i++) {
+			data[1] = i;
+			if (sp_xmit_status_request(sp, data, 2) < 0)
+				break;
+		}
+	}
+
+	/*
+	 * New request thread for known hardware
+	 */
+	if (sp->hw.hw_type.type)
+		__mod_timer(&sp->status_t, jiffies + (HZ/10));
+}
+
+/* several status reports for privilliged commands encoded as "txd's" > 251 */
+
+static void trace_unknown_status_report(struct sixpack *sp)
+{
+	//sp->led_state = 0x68;
+	//sp->tty->driver->write(sp->tty, &sp->led_state, 1);
+	//#ifdef DEBUG
+	trace_frame(sp, "status info");
+	//#endif
+}
+
+/* pr430 hardware status */
+
+static void decode_status254_tnc430(struct sixpack *sp)
+{
+	int len;
+	unsigned char *args;
+
+	/*
+	 * len: sp->rxcount is already without checksum
+	 * and without pos0 (txdelay) and refers pure data
+	 */
+	len = sp->rcount;
+	/* cooked_buf[0] is still txdelay == 254 */
+	args = &sp->cooked_buf[1];
+
+	if (len == 1 && args[0] == 0 && args[1] == 1 /* checksum */) {
+		// answer was 0xfe + 0x00 + 0x01 == 0xff (checksum ok, as verified before)
+		printk(KERN_INFO "6pack: tnc is alive (response: 0xfe 0x00 0x01)\n");
+		return;
+	}
+	// remember last status we received from tnc. is it the status we asked for?
+	// note that for s-meter (16) we poll regulary
+	if (args[0] != 16) {
+		// hack: sometimes there's the answer in the rx buffer. give
+		//   time for 2 pending status commands (more never seen)
+		static int complain = 0;
+		if (sp->hw.hf_want.status254_cmd && args[0] != sp->hw.hf_want.status254_cmd) {
+			if (complain > 1) {
+				printk(KERN_INFO "6pack: decode_status254_tnc430: asked for %d, got %d\n", sp->hw.hf_want.status254_cmd, args[0]);
+				complain = 0;
+			} else
+				complain++;
+		} else
+			complain = 0;
+		//sp->hw.hf_act.status254_cmd = args[0];
+		//sp->hw.hf_act.status254_cmd_t = jiffies;
+	}
+	//printk(KERN_DEBUG "6pack: decode_status254_tnc430() called, cmd %d, len %d %ld\n", args[0], len, jiffies);
+
+	switch (args[0]) {
+	case 1:	// QRG and Shift
+		if (len == 4) {
+			unsigned int freq;
+			int shift;
+
+			freq  = (args[1] * 256 + args[2]) * 12500 + 400000000;
+			shift = args[3] * 100000;
+			if (sp->hw.hf_act.qrg != freq) {
+				if (sp->hw.hf_want.qrg)
+					printk(KERN_INFO "6pack: qrg change: %d to %d\n", sp->hw.hf_act.qrg, freq);
+				sp->hw.hf_act.qrg = freq;
+			}
+			if (sp->hw.hf_act.shift != shift) {
+				if (sp->hw.hf_want.shift)
+					printk(KERN_INFO "6pack: shift change: %d to %d\n", sp->hw.hf_act.shift, shift);
+				sp->hw.hf_act.shift = shift;
+			}
+			if (sp->hw.hf_act.qrg != sp->hw.hf_want.qrg) {
+				printk(KERN_INFO "6pack: qrg change: %d\n", freq);
+			}
+			if (sp->hw.hf_act.shift != sp->hw.hf_want.shift) {
+				printk(KERN_INFO "6pack: shift change: %d\n", shift);
+			}
+			// never initialized?
+			if (!sp->hw.hf_want.qrg) {
+				sp->hw.hf_want.qrg = sp->hw.hf_act.qrg;
+				sp->hw.hf_want.shift = sp->hw.hf_act.shift;
+			}
+		}
+		break;
+	case 2:	// Mode
+		if (len == 2) {
+			char new_mode;
+			if (args[1] & DO_FM) {
+				new_mode = 3;
+				sp->hw.hf_act.baud = 0;	// wg. Signalisierung in Parms
+			}
+			else if ((args[1] & ~DO_DELAY_TX) == DO_AFSK) {
+				new_mode = 2;	// AFSK
+				sp->hw.hf_act.baud = 12;
+			}
+			else {
+				new_mode = 1;	// FSK
+				sp->hw.hf_act.baud = 96;
+			}
+			if (sp->hw.hf_act.mode != new_mode) {
+				if (sp->hw.hf_want.mode) {
+					printk(KERN_INFO "6pack: mode change: %d %d\n", new_mode, sp->hw.hf_act.baud);
+				}
+				sp->hw.hf_act.mode = new_mode;
+				// never initialized?
+				if (!sp->hw.hf_want.mode) {
+					sp->hw.hf_want.mode = sp->hw.hf_act.mode;
+					sp->hw.hf_want.baud = sp->hw.hf_act.baud;
+				}
+			}
+		}
+		break;
+	case 3: /* current tx-power */
+		//printk(KERN_DEBUG "txpower act %d want %d got %d\n",
+		//       sp->hw.hf_act.txpower, sp->hw.hf_want.txpower, args[1]);
+		if (len == 2) {
+			if (sp->hw.hf_act.txpower != args[1]) {
+				//if (sp->hw.hf_want.txpower)
+					printk(KERN_INFO "6pack: tx power change %d\n", args[1]);
+				sp->hw.hf_act.txpower = args[1];
+			}
+			if (!sp->hw.hf_want.txpower)
+				sp->hw.hf_want.txpower = sp->hw.hf_act.txpower;
+		}
+		break;
+	case 16:
+		/*
+		 * S-Meter, Hub etc..
+		 * sometimes it's 79*4 316 196dbm - what does that mean???
+		 * args[1] = args[1] & 0xf;
+		 * sometimes on tx pr430 reports arg1=14 arg2=255 arg3=57.
+		 * perhaps not a center information in arg2,3. currently
+		 * ignore values >= 192
+		 */
+		if (args[2] >= 192)
+			break;
+		if (/* no, off */ 0 && sp->hw.smeter != args[1]*4) {
+			char tmpbuf[16];
+			if (args[1] < 16)
+				sprintf(tmpbuf, "%d", (args[1] - 1) * 4 / 6);
+			else
+				sprintf(tmpbuf, "9+%d", (args[1]-15) * 10);
+			printk(KERN_DEBUG "6pack: s-meter change: %d*4 %d %ddbm -> S%s\n", args[1], args[1]*4, args[1]*4-120, tmpbuf);
+		}
+		sp->hw.smeter = args[1] * 4;
+		if (len > 2) {
+			//if (sp->hw.center != (args[2] ^ 0x80))
+				//printk(KERN_DEBUG "6pack: center change: %dHz (%d)\n", ((1000/5) * (char ) (args[2] ^ 0x80)), (char ) (args[2] ^ 0x80));
+			// inform if signal is >7kHz out ouf center
+			if (abs((char) (args[2] ^ 0x80)) > 7*5/1)
+				printk(KERN_DEBUG "6pack: info: center out of range: %dHz (%d)\n", ((1000/5) * (char ) (args[2] ^ 0x80)), (char ) args[2] ^ 0x80);
+			sp->hw.center = (char ) (args[2] ^ 0x80);	// 128->0
+		}
+		if (len > 3) {
+			//if (sp->hw.hub != args[3])
+				//printk(KERN_DEBUG "6pack: hub change: %dHz (%d)\n", ((3000/25) * args[3]), args[3]);
+			//if (args[3] > 4*25/3)
+				//printk(KERN_DEBUG "6pack: info: great hub: %dHz (%d)\n", 3000/25 * args[3], args[3]);
+			sp->hw.hub = args[3];
+		}
+		break;
+	default:
+		printk("6pack: unknown status from tnc430: %d cmd %d len %d\n", sp->cooked_buf[0], args[0], len);
+		trace_unknown_status_report(sp);
+	}
+
+	//printk(KERN_DEBUG "6pack: debug: cmd %d %d qrg %d shift %d mode %d baud %d smeter %d center %d hub %d\n",
+	//		                     args[0], args[1], (int ) sp->hw.hf_act.qrg, (int ) sp->hw.hf_act.shift, (int ) sp->hw.hf_act.mode, (int ) sp->hw.hf_act.baud, (int ) sp->hw.smeter, (int ) sp->hw.center, (int ) sp->hw.hub);
+}
+
+static void decode_status254(struct sixpack *sp)
+{
+	if (is_hw_tnc430(sp))
+		decode_status254_tnc430(sp);
+	else
+		trace_unknown_status_report(sp);
+}
+
+static void decode_status255(struct sixpack *sp)
+{
+	if (sp->rcount >= 4) {
+		sp->hw.hw_type.type	= sp->cooked_buf[1];
+		sp->hw.hw_type.author	= sp->cooked_buf[2];
+		sp->hw.hw_type.major	= sp->cooked_buf[3];
+		sp->hw.hw_type.minor	= sp->cooked_buf[4];
+
+		if (!sp->hw.hw_type.announced)
+			initialize_hardware(sp);
+	} else
+		trace_unknown_status_report(sp);
+}
 
 /*
  * This is the routine that sends the received data to the kernel AX.25.
@@ -409,6 +873,28 @@
 	sp->stats.rx_dropped++;
 }
 
+/* interprete 6pack extension or rx data */
+
+static void sp_rxhandler(struct sixpack *sp)
+{
+	// tx_delay > 251 have special means
+	switch (sp->cooked_buf[0]) {
+	case 255:
+		decode_status255(sp);
+		break;
+	case 254:
+		decode_status254(sp);
+		break;
+	default:
+		if (sp->rcount >= 5) {
+			sp_bump(sp, 0);
+			break;
+		}
+
+		sp->stats.rx_length_errors++;
+	}
+}
+
 
 /* ----------------------------------------------------------------------- */
 
@@ -480,62 +966,17 @@
 }
 
 /*
- * Handle the 'receiver data ready' interrupt.
- * This function is called by the 'tty_io' module in the kernel when
- * a block of 6pack data has been received, which can now be decapsulated
- * and sent on to some IP layer for further processing.
- */
-static void sixpack_receive_buf(struct tty_struct *tty,
-	const unsigned char *cp, char *fp, int count)
-{
-	struct sixpack *sp;
-	unsigned char buf[512];
-	int count1;
-
-	if (!count)
-		return;
-
-	sp = sp_get(tty);
-	if (!sp)
-		return;
-
-	memcpy(buf, cp, count < sizeof(buf) ? count : sizeof(buf));
-
-	/* Read the characters out of the buffer */
-
-	count1 = count;
-	while (count) {
-		count--;
-		if (fp && *fp++) {
-			if (!test_and_set_bit(SIXPF_ERROR, &sp->flags))
-				sp->stats.rx_errors++;
-			continue;
-		}
-	}
-	sixpack_decode(sp, buf, count1);
-
-	sp_put(sp);
-	if (test_and_clear_bit(TTY_THROTTLED, &tty->flags)
-	    && tty->driver->unthrottle)
-		tty->driver->unthrottle(tty);
-}
-
-/*
  * Try to resync the TNC. Called by the resync timer defined in
  * decode_prio_command
  */
 
-#define TNC_UNINITIALIZED	0
-#define TNC_UNSYNC_STARTUP	1
-#define TNC_UNSYNCED		2
-#define TNC_IN_SYNC		3
-
-static void __tnc_set_sync_state(struct sixpack *sp, int new_tnc_state)
+static void __tnc_set_sync_state(struct sixpack *sp,
+	enum tnc_state new_tnc_state)
 {
 	char *msg;
 
 	switch (new_tnc_state) {
-	default:			/* gcc oh piece-o-crap ... */
+	default:
 	case TNC_UNSYNC_STARTUP:
 		msg = "Synchronizing with TNC";
 		break;
@@ -551,7 +992,8 @@
 	printk(KERN_INFO "%s: %s\n", sp->dev->name, msg);
 }
 
-static inline void tnc_set_sync_state(struct sixpack *sp, int new_tnc_state)
+static inline void tnc_set_sync_state(struct sixpack *sp,
+	enum tnc_state new_tnc_state)
 {
 	int old_tnc_state = sp->tnc_state;
 
@@ -575,70 +1017,582 @@
 	sp->status1 = 1;
 	sp->status2 = 0;
 
-	/* resync the TNC */
+	/* Resync the TNC */
 
 	sp->led_state = 0x60;
 	sp->tty->driver->write(sp->tty, &sp->led_state, 1);
 	sp->tty->driver->write(sp->tty, &resync_cmd, 1);
 
-
 	/* Start resync timer again -- the TNC might be still absent */
-
-	del_timer(&sp->resync_t);
-	sp->resync_t.data	= (unsigned long) sp;
-	sp->resync_t.function	= resync_tnc;
-	sp->resync_t.expires	= jiffies + SIXP_RESYNC_TIMEOUT;
-	add_timer(&sp->resync_t);
+	mod_timer(&sp->resync_t, jiffies + SIXP_RESYNC_TIMEOUT);
 }
 
-static inline int tnc_init(struct sixpack *sp)
+static inline void tnc_init(struct sixpack *sp)
 {
-	unsigned char inbyte = 0xe8;
+	static const unsigned char inbyte = 0xe8;
 
 	tnc_set_sync_state(sp, TNC_UNSYNC_STARTUP);
 
 	sp->tty->driver->write(sp->tty, &inbyte, 1);
 
-	del_timer(&sp->resync_t);
+	init_timer(&sp->resync_t);
 	sp->resync_t.data = (unsigned long) sp;
 	sp->resync_t.function = resync_tnc;
-	sp->resync_t.expires = jiffies + SIXP_RESYNC_TIMEOUT;
-	add_timer(&sp->resync_t);
-
-	return 0;
+	__mod_timer(&sp->resync_t, jiffies + SIXP_RESYNC_TIMEOUT);
 }
 
-/*
- * Open the high-level part of the 6pack channel.
- * This function is called by the TTY module when the
- * 6pack line discipline is called for.  Because we are
- * sure the tty line exists, we only have to link it to
- * a free 6pcack channel...
- */
-static int sixpack_open(struct tty_struct *tty)
+/* decode 4 sixpack-encoded bytes into 3 data bytes */
+
+static void decode_data(struct sixpack *sp, unsigned char inbyte)
 {
-	char *rbuff = NULL, *xbuff = NULL;
-	struct net_device *dev;
-	struct sixpack *sp;
-	unsigned long len;
-	int err = 0;
+	unsigned char *buf;
 
-	if (!capable(CAP_NET_ADMIN))
-		return -EPERM;
+	if (sp->rx_count != 3) {
+		sp->raw_buf[sp->rx_count++] = inbyte;
 
-	dev = alloc_netdev(sizeof(struct sixpack), "sp%d", sp_setup);
-	if (!dev) {
-		err = -ENOMEM;
-		goto out;
+		return;
 	}
 
-	sp = netdev_priv(dev);
-	sp->dev = dev;
-
-	spin_lock_init(&sp->lock);
-	atomic_set(&sp->refcnt, 1);
-	init_MUTEX_LOCKED(&sp->dead_sem);
-
+	buf = sp->raw_buf;
+	sp->cooked_buf[sp->rx_count_cooked++] =
+		buf[0] | ((buf[1] << 2) & 0xc0);
+	sp->cooked_buf[sp->rx_count_cooked++] =
+		(buf[1] & 0x0f) | ((buf[2] << 2) & 0xf0);
+	sp->cooked_buf[sp->rx_count_cooked++] =
+		(buf[2] & 0x03) | (inbyte << 2);
+	sp->rx_count = 0;
+}
+
+/* identify and execute a 6pack priority command byte */
+
+static void decode_prio_command(struct sixpack *sp, unsigned char cmd)
+{
+	unsigned char channel;
+	int actual;
+
+	channel = cmd & SIXP_CHN_MASK;
+	if ((cmd & SIXP_PRIO_DATA_MASK) != 0) {     /* idle ? */
+
+	/* RX and DCD flags can only be set in the same prio command,
+	   if the DCD flag has been set without the RX flag in the previous
+	   prio command. If DCD has not been set before, something in the
+	   transmission has gone wrong. In this case, RX and DCD are
+	   cleared in order to prevent the decode_data routine from
+	   reading further data that might be corrupt. */
+
+		if (((sp->status & SIXP_DCD_MASK) == 0) &&
+			((cmd & SIXP_RX_DCD_MASK) == SIXP_RX_DCD_MASK)) {
+				if (sp->status != 1)
+					printk(KERN_DEBUG "6pack: protocol violation\n");
+				else
+					sp->status = 0;
+				cmd &= !SIXP_RX_DCD_MASK;
+		}
+		sp->status = cmd & SIXP_PRIO_DATA_MASK;
+	} else { /* output watchdog char if idle */
+		if ((sp->status2 != 0) && (sp->duplex == 1)) {
+			sp->led_state = 0x70;
+			sp->tty->driver->write(sp->tty, &sp->led_state, 1);
+			sp->tx_enable = 1;
+			actual = sp->tty->driver->write(sp->tty, sp->xbuff, sp->status2);
+			sp->xleft -= actual;
+			sp->xhead += actual;
+			sp->led_state = 0x60;
+			sp->status2 = 0;
+
+		}
+	}
+
+	/* needed to trigger the TNC watchdog */
+	sp->tty->driver->write(sp->tty, &sp->led_state, 1);
+
+	/*
+	 * If the state byte has been received, the TNC is present,
+         * so the resync timer can be reset.
+	 */
+	if (sp->tnc_state == TNC_IN_SYNC)
+		mod_timer(&sp->resync_t, jiffies + SIXP_INIT_RESYNC_TIMEOUT);
+
+	sp->status1 = cmd & SIXP_PRIO_DATA_MASK;
+}
+
+/* identify and execute a standard 6pack command byte */
+
+static void decode_std_command(struct sixpack *sp, unsigned char cmd)
+{
+	unsigned char checksum = 0, rest = 0, channel;
+	short i;
+
+	channel = cmd & SIXP_CHN_MASK;
+	switch (cmd & SIXP_CMD_MASK) {     /* normal command */
+	case SIXP_SEOF:
+		if ((sp->rx_count == 0) && (sp->rx_count_cooked == 0)) {
+			if ((sp->status & SIXP_RX_DCD_MASK) ==
+				SIXP_RX_DCD_MASK) {
+				sp->led_state = 0x68;
+				sp->tty->driver->write(sp->tty, &sp->led_state, 1);
+			}
+		} else {
+			sp->led_state = 0x60;
+			/* fill trailing bytes with zeroes */
+			sp->tty->driver->write(sp->tty, &sp->led_state, 1);
+			rest = sp->rx_count;
+			if (rest != 0)
+				 for (i = rest; i <= 3; i++)
+					decode_data(sp, 0);
+			if (rest == 2)
+				sp->rx_count_cooked -= 2;
+			else if (rest == 3)
+				sp->rx_count_cooked -= 1;
+			for (i = 0; i < sp->rx_count_cooked; i++)
+				checksum += sp->cooked_buf[i];
+			if (checksum != SIXP_CHKSUM) {
+				sp->stats.rx_crc_errors++;
+				printk(KERN_DEBUG "6pack: bad checksum %2.2x\n", checksum);
+			} else {
+				sp->rcount = sp->rx_count_cooked - 2;
+				sp_rxhandler(sp);
+			}
+			sp->rx_count_cooked = 0;
+		}
+		break;
+	case SIXP_TX_URUN:
+		sp->stats.tx_fifo_errors++;
+		printk(KERN_DEBUG "6pack: TX underrun\n");
+		break;
+	case SIXP_RX_ORUN:
+		sp->stats.rx_fifo_errors++;
+		printk(KERN_DEBUG "6pack: RX overrun\n");
+		break;
+	case SIXP_RX_BUF_OVL:
+		sp->stats.rx_length_errors++;
+		printk(KERN_DEBUG "6pack: RX buffer overflow\n");
+	default:
+		printk(KERN_DEBUG "6pack: unknown std command: %d (%2.2x)\n", cmd, cmd);
+	}
+}
+
+/* decode a 6pack packet */
+
+static inline void
+sixpack_decode(struct sixpack *sp, unsigned char *pre_rbuff, int count)
+{
+	unsigned char inbyte;
+	int count1;
+
+	for (count1 = 0; count1 < count; count1++) {
+		inbyte = pre_rbuff[count1];
+		if (inbyte == SIXP_FOUND_TNC) {
+			tnc_set_sync_state(sp, TNC_IN_SYNC);
+			mod_timer(&sp->resync_t,
+			          jiffies + SIXP_INIT_RESYNC_TIMEOUT);
+		}
+		if ((inbyte & SIXP_PRIO_CMD_MASK) != 0)
+			decode_prio_command(sp, inbyte);
+		else if ((inbyte & SIXP_STD_CMD_MASK) != 0)
+			decode_std_command(sp, inbyte);
+		else if ((sp->status & SIXP_RX_DCD_MASK) == SIXP_RX_DCD_MASK)
+			decode_data(sp, inbyte);
+	}
+}
+
+/*
+ * Handle the 'receiver data ready' interrupt.
+ * This function is called by the 'tty_io' module in the kernel when
+ * a block of 6pack data has been received, which can now be decapsulated
+ * and sent on to some IP layer for further processing.
+ */
+static void sixpack_receive_buf(struct tty_struct *tty,
+	const unsigned char *cp, char *fp, int count)
+{
+	struct sixpack *sp;
+	unsigned char buf[512];
+	int count1;
+
+	if (!count)
+		return;
+
+	sp = sp_get(tty);
+	if (!sp)
+		return;
+
+	memcpy(buf, cp, count < sizeof(buf) ? count : sizeof(buf));
+
+	/* Read the characters out of the buffer */
+
+	count1 = count;
+	while (count) {
+		count--;
+		if (fp && *fp++) {
+			if (!test_and_set_bit(SIXPF_ERROR, &sp->flags))
+				sp->stats.rx_errors++;
+			continue;
+		}
+	}
+	sixpack_decode(sp, buf, count1);
+
+	sp_put(sp);
+	if (test_and_clear_bit(TTY_THROTTLED, &tty->flags)
+	    && tty->driver->unthrottle)
+		tty->driver->unthrottle(tty);
+}
+
+/*
+ * PR-430 specific configuration
+ */
+
+/*
+ * Shift is a byte, so there's a design limit.
+ */
+#define	SHIFT_MAX	256*100000
+
+/*
+ * 12.5 kHz steps from 400Mhz up
+ */
+#define	QRG2CHANNEL(x)	(((x - 400000000) * 2 + 1) / 25000)
+
+static int change_qrg_shift(struct sixpack *sp, unsigned long freq, long shift)
+{
+	unsigned int qrg, txqrg;
+	unsigned char data[5];
+
+	if (freq < (long ) -1 * SHIFT_MAX)
+		return -EINVAL;
+
+	qrg = sp->hw.hf_act.qrg;
+
+	printk(KERN_DEBUG "qrg %d act.qrg %d\n", qrg, sp->hw.hf_act.qrg);
+
+	if ((long ) freq < (long ) SHIFT_MAX) {
+		// new shift
+		shift = (freq / 100000) * 100000 /* rounded */;
+		if (shift)
+			printk(KERN_DEBUG "switching to shift %ld\n", shift);
+		else
+			printk(KERN_DEBUG "switching to simplex\n");
+	} else {
+		//printk(KERN_DEBUG "test2: %ld > %d\n",
+		//       (long ) freq /1000, SHIFT_MAX / 1000);
+		/*
+		 * New QRG
+		 */
+		qrg = freq;
+	}
+	txqrg = qrg + shift;
+#ifdef US_QRG
+	if (qrg > 420000000 && qrg < 450000000
+		&& txqrg > 420000000 && txqrg < 450000000)
+#else
+	if (qrg > 430000000 && qrg < 440000000
+		&& txqrg > 430000000 && txqrg < 440000000)
+#endif
+	{
+		sp->hw.hf_want.qrg = qrg;
+		sp->hw.hf_want.shift = shift;
+		data[0] = 254;	// Kennung TNC430-Special
+		data[1] = 1;
+		data[2] = QRG2CHANNEL(qrg) / 256;
+		data[3] = QRG2CHANNEL(qrg);
+		data[4] = shift / 100000;
+		sp->hw.hf_want.status254_cmd = data[1];
+		{
+			printk(KERN_DEBUG "New qrg/shift: "
+			       "%d %d, sending %d %d %d %d %d\n",
+			       sp->hw.hf_want.qrg, sp->hw.hf_want.shift,
+			       data[0], data[1], data[2], data[3], data[4]);
+
+			if (sp_xmit_status_request(sp, data, 5) < 0)
+				return -EADDRNOTAVAIL;
+		}
+		/*
+		 * And poll
+		 */
+		//sp_xmit_status_request(sp, data, 2);
+
+		return 0;
+	}
+
+	printk(KERN_INFO "6pack: refusing qsy: out of band range: "
+	       "qrg %d shift %ld -> tx-qrg %ld.\n", qrg, shift, qrg + shift);
+
+	return -EINVAL;
+}
+
+static int change_qrg(struct net_device *dev, unsigned long freq)
+{
+	struct sixpack *sp = netdev_priv(dev);
+
+	return change_qrg_shift(sp, freq, sp->hw.hf_act.shift);
+}
+
+static int change_shift(struct net_device *dev, unsigned long txshift)
+{
+	struct sixpack *sp = netdev_priv(dev);
+	long shift = txshift;
+
+	return change_qrg_shift(sp, sp->hw.hf_act.qrg, shift);
+}
+
+static int change_txpower(struct net_device *dev, unsigned long txpower)
+{
+	struct sixpack *sp = netdev_priv(dev);
+	unsigned char data[3];
+
+	data[0] = 254;
+	data[1] = 3;
+	switch (txpower) {
+	case 0:
+		sp->hw.hf_want.txpower = 0;
+		break;
+
+	case 1: // ord
+	case 16: // cmd
+	case 25: // dBm
+		sp->hw.hf_want.txpower = 16;
+		break;
+
+	case 2: // ord
+	case 64: // cmd
+	case 30: // dBm
+		sp->hw.hf_want.txpower = 64;
+		break;
+
+	case 3: // ord
+	case 255: // cmd
+	case 38: // dBm
+		sp->hw.hf_want.txpower = 255;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+	data[2] = sp->hw.hf_want.txpower;
+
+	sp->hw.hf_want.status254_cmd = data[1];
+	printk(KERN_DEBUG "New txpower: %d (%ld), sending %d %d %d\n",
+	       sp->hw.hf_want.txpower, txpower, data[0], data[1], data[2]);
+
+	if (sp_xmit_status_request(sp, data, 3) < 0)
+		return -EADDRNOTAVAIL;
+
+	/*
+	 * and poll
+	 */
+	// sp_xmit_status_request(sp, data, 2);
+
+	return 0;
+}
+
+/*
+ * For now changing the bitrate implies changing to AFSK for 1200bps
+ * and to FSK for 9600bps.  This may eventually change, you've been
+ * warned.
+ */
+static int change_bitrate(struct net_device *dev, unsigned long bitrate)
+{
+	struct sixpack *sp = netdev_priv(dev);
+	unsigned char data [3];
+
+	data[0] = 254;
+	data[1] = 2;
+
+	switch (bitrate) {
+	case 2:
+	case 1200:
+		sp->hw.hf_want.baud = 12;
+		data[2] = DO_AFSK | DO_DELAY_TX;
+		sp->hw.hf_want.mode = 2;
+		break;
+	case 1:
+	case 9600:
+		sp->hw.hf_want.baud = 96;
+		data[2] = DO_DELAY_TX;
+		sp->hw.hf_want.mode = 1;
+		break;
+#if 0
+	case 3:
+		/*
+		 * Voice - currently not supported
+		 */
+		sp->hw.hf_want.baud = 0;
+		data[2] = DO_FM;
+		sp->hw.hf_want.mode = 3;
+		break;
+#endif
+	default:
+		return -EINVAL;
+	}
+
+	sp->hw.hf_want.status254_cmd = data[1];
+	printk(KERN_DEBUG "New mode: %d (%ld, %d), sending %d %d %d\n",
+	       sp->hw.hf_want.mode, bitrate, sp->hw.hf_want.baud * 100,
+	       data[0], data[1], data[2]);
+
+	if (sp_xmit_status_request(sp, data, 3) < 0)
+		return -EADDRNOTAVAIL;
+	/*
+	 * and poll
+	 */
+	//sp_xmit_status_request(sp, data, 2);
+
+	return 0;
+}
+
+#define to_net_dev(class) container_of(class, struct net_device, class_dev)
+
+static const char fmt_hex[] = "%#x\n";
+static const char fmt_dec[] = "%d\n";
+static const char fmt_ulong[] = "%lu\n";
+
+static inline int dev_isalive(const struct net_device *dev)
+{
+	return dev->reg_state == NETREG_REGISTERED;
+}
+
+/* helper function that does all the locking etc for wireless stats */
+static ssize_t tnc_show(struct class_device *cd, char *buf,
+                        ssize_t (*format)(const struct sixpack *, char *))
+{
+	struct net_device *dev = to_net_dev(cd);
+	const struct sixpack *sp = netdev_priv(dev);
+	ssize_t ret = -EINVAL;
+
+	read_lock(&dev_base_lock);
+	if (dev_isalive(dev) && is_hw_tnc430(sp))
+		ret = format(sp, buf);
+	read_unlock(&dev_base_lock);
+
+	return ret;
+}
+
+/*
+ * Common code for r/w and r/o variables
+ */
+#define TNC_SHOW_VAR(name, field, format_string)			\
+									\
+static ssize_t format_sp_##name(const struct sixpack *sp, char *buf)	\
+{									\
+	return sprintf(buf, format_string, sp->field);			\
+}									\
+									\
+static ssize_t show_sp_##name(struct class_device *cd, char *buf)	\
+{									\
+	return tnc_show(cd, buf, format_sp_##name);			\
+}
+
+/*
+ * Macro to define a read-only variable
+ */
+#define TNC_RO_VAR(name, field, format_string)				\
+									\
+TNC_SHOW_VAR(name, field, format_string)				\
+									\
+static CLASS_DEVICE_ATTR(name, S_IRUGO, show_sp_##name, NULL)
+
+/*
+ * Macro to define a read-write variable
+ */
+#define TNC_RW_VAR(name, field, format_string)				\
+									\
+TNC_SHOW_VAR(name, field, format_string)				\
+									\
+static ssize_t store_sp_##name(struct class_device *dev,		\
+                               const char *buf, size_t len)		\
+{									\
+	return netdev_store(dev, buf, len, change_##name);		\
+}									\
+									\
+static CLASS_DEVICE_ATTR(name, S_IRUGO | S_IWUSR,			\
+                         show_sp_##name, store_sp_##name)
+
+/*
+ * Use same locking and permission rules as SIF* ioctl's
+ */
+static ssize_t netdev_store(struct class_device *dev,
+			    const char *buf, size_t len,
+			    int (*set)(struct net_device *, unsigned long))
+{
+	struct net_device *net = to_net_dev(dev);
+	char *endp;
+	unsigned long new;
+	int ret = -EINVAL;
+
+	if (!capable(CAP_NET_ADMIN))
+		return -EPERM;
+
+	new = simple_strtoul(buf, &endp, 0);
+	if (endp == buf)
+		goto err;
+
+	rtnl_lock();
+	if (dev_isalive(net)) {
+		if ((ret = (*set)(net, new)) == 0)
+			ret = len;
+	}
+	rtnl_unlock();
+ err:
+	return ret;
+}
+
+TNC_RO_VAR(hwtype, hw.hw_type.type, fmt_dec);
+TNC_RO_VAR(author, hw.hw_type.author, fmt_dec);
+TNC_RO_VAR(major, hw.hw_type.major, fmt_dec);
+TNC_RO_VAR(minor, hw.hw_type.minor, fmt_dec);
+
+TNC_RW_VAR(qrg, hw.hf_act.qrg, fmt_dec);
+TNC_RW_VAR(shift, hw.hf_act.shift, fmt_dec);
+//TNC_RW_VAR(mode, hw.hf_act.mode, fmt_dec);
+TNC_RW_VAR(bitrate, hw.hf_act.baud, fmt_dec);
+TNC_RW_VAR(txpower, hw.hf_act.txpower, fmt_dec);
+
+static struct attribute *tnc_attrs[] = {
+	&class_device_attr_hwtype.attr,
+	&class_device_attr_author.attr,
+	&class_device_attr_major.attr,
+	&class_device_attr_minor.attr,
+
+	&class_device_attr_qrg.attr,
+	&class_device_attr_shift.attr,
+	//&class_device_attr_mode.attr,
+	&class_device_attr_bitrate.attr,
+	&class_device_attr_txpower.attr,
+	NULL
+};
+
+static struct attribute_group tnc_group = {
+	.name	= "tnc",
+	.attrs	= tnc_attrs,
+};
+
+/*
+ * Open the high-level part of the 6pack channel.  This function is called by
+ * the TTY module when the 6pack line discipline is called for.  Because we are
+ * sure the tty line exists, we only have to link it to a free 6pack channel ...
+ */
+static int sixpack_open(struct tty_struct *tty)
+{
+	char *rbuff = NULL, *xbuff = NULL;
+	struct net_device *dev;
+	struct sixpack *sp;
+	unsigned long len;
+	int err = 0;
+
+	if (!capable(CAP_NET_ADMIN))
+		return -EPERM;
+
+	dev = alloc_netdev(sizeof(struct sixpack), "sp%d", sp_setup);
+	if (!dev) {
+		err = -ENOMEM;
+		goto out;
+	}
+
+	sp = netdev_priv(dev);
+	sp->dev = dev;
+
+	spin_lock_init(&sp->lock);
+	atomic_set(&sp->refcnt, 1);
+	init_MUTEX_LOCKED(&sp->dead_sem);
+
 	/* !!! length of the buffers. MTU is IP MTU, not PACLEN!  */
 
 	len = dev->mtu * 2;
@@ -680,7 +1634,12 @@
 	netif_start_queue(dev);
 
 	init_timer(&sp->tx_t);
-	init_timer(&sp->resync_t);
+	sp->tx_t.function = sp_xmit_on_air;
+	sp->tx_t.data = (unsigned long) sp;
+
+	init_timer(&sp->status_t);
+	sp->status_t.function = status_request;
+	sp->status_t.data = (unsigned long) sp;
 
 	spin_unlock_bh(&sp->lock);
 
@@ -691,10 +1650,17 @@
 	if (register_netdev(dev))
 		goto out_free;
 
+	err = sysfs_create_group(&dev->class_dev.kobj, &tnc_group);
+	if (err)
+		goto out_unregister;
+
 	tnc_init(sp);
 
 	return 0;
 
+out_unregister:
+	unregister_netdev(dev);
+
 out_free:
 	kfree(xbuff);
 	kfree(rbuff);
@@ -721,20 +1687,23 @@
 	sp = tty->disc_data;
 	tty->disc_data = NULL;
 	write_unlock(&disc_data_lock);
+
 	if (sp == 0)
 		return;
 
 	/*
-	 * We have now ensured that nobody can start using ap from now on, but
+	 * We have now ensured that nobody can start using sp from now on, but
 	 * we have to wait for all existing users to finish.
 	 */
 	if (!atomic_dec_and_test(&sp->refcnt))
 		down(&sp->dead_sem);
 
+	sysfs_remove_group(&sp->dev->class_dev.kobj, &tnc_group);
 	unregister_netdev(sp->dev);
 
 	del_timer(&sp->tx_t);
-	del_timer(&sp->resync_t);
+	del_timer_sync(&sp->resync_t);
+	del_timer_sync(&sp->status_t);
 
 	/* Free all 6pack frame buffers. */
 	kfree(sp->rbuff);
@@ -852,195 +1821,7 @@
 		printk(msg_unregfail, ret);
 }
 
-/* encode an AX.25 packet into 6pack */
-
-static int encode_sixpack(unsigned char *tx_buf, unsigned char *tx_buf_raw,
-	int length, unsigned char tx_delay)
-{
-	int count = 0;
-	unsigned char checksum = 0, buf[400];
-	int raw_count = 0;
-
-	tx_buf_raw[raw_count++] = SIXP_PRIO_CMD_MASK | SIXP_TX_MASK;
-	tx_buf_raw[raw_count++] = SIXP_SEOF;
-
-	buf[0] = tx_delay;
-	for (count = 1; count < length; count++)
-		buf[count] = tx_buf[count];
-
-	for (count = 0; count < length; count++)
-		checksum += buf[count];
-	buf[length] = (unsigned char) 0xff - checksum;
-
-	for (count = 0; count <= length; count++) {
-		if ((count % 3) == 0) {
-			tx_buf_raw[raw_count++] = (buf[count] & 0x3f);
-			tx_buf_raw[raw_count] = ((buf[count] >> 2) & 0x30);
-		} else if ((count % 3) == 1) {
-			tx_buf_raw[raw_count++] |= (buf[count] & 0x0f);
-			tx_buf_raw[raw_count] =	((buf[count] >> 2) & 0x3c);
-		} else {
-			tx_buf_raw[raw_count++] |= (buf[count] & 0x03);
-			tx_buf_raw[raw_count++] = (buf[count] >> 2);
-		}
-	}
-	if ((length % 3) != 2)
-		raw_count++;
-	tx_buf_raw[raw_count++] = SIXP_SEOF;
-	return raw_count;
-}
-
-/* decode 4 sixpack-encoded bytes into 3 data bytes */
-
-static void decode_data(struct sixpack *sp, unsigned char inbyte)
-{
-	unsigned char *buf;
-
-	if (sp->rx_count != 3) {
-		sp->raw_buf[sp->rx_count++] = inbyte;
-
-		return;
-	}
-
-	buf = sp->raw_buf;
-	sp->cooked_buf[sp->rx_count_cooked++] =
-		buf[0] | ((buf[1] << 2) & 0xc0);
-	sp->cooked_buf[sp->rx_count_cooked++] =
-		(buf[1] & 0x0f) | ((buf[2] << 2) & 0xf0);
-	sp->cooked_buf[sp->rx_count_cooked++] =
-		(buf[2] & 0x03) | (inbyte << 2);
-	sp->rx_count = 0;
-}
-
-/* identify and execute a 6pack priority command byte */
-
-static void decode_prio_command(struct sixpack *sp, unsigned char cmd)
-{
-	unsigned char channel;
-	int actual;
-
-	channel = cmd & SIXP_CHN_MASK;
-	if ((cmd & SIXP_PRIO_DATA_MASK) != 0) {     /* idle ? */
-
-	/* RX and DCD flags can only be set in the same prio command,
-	   if the DCD flag has been set without the RX flag in the previous
-	   prio command. If DCD has not been set before, something in the
-	   transmission has gone wrong. In this case, RX and DCD are
-	   cleared in order to prevent the decode_data routine from
-	   reading further data that might be corrupt. */
-
-		if (((sp->status & SIXP_DCD_MASK) == 0) &&
-			((cmd & SIXP_RX_DCD_MASK) == SIXP_RX_DCD_MASK)) {
-				if (sp->status != 1)
-					printk(KERN_DEBUG "6pack: protocol violation\n");
-				else
-					sp->status = 0;
-				cmd &= !SIXP_RX_DCD_MASK;
-		}
-		sp->status = cmd & SIXP_PRIO_DATA_MASK;
-	} else { /* output watchdog char if idle */
-		if ((sp->status2 != 0) && (sp->duplex == 1)) {
-			sp->led_state = 0x70;
-			sp->tty->driver->write(sp->tty, &sp->led_state, 1);
-			sp->tx_enable = 1;
-			actual = sp->tty->driver->write(sp->tty, sp->xbuff, sp->status2);
-			sp->xleft -= actual;
-			sp->xhead += actual;
-			sp->led_state = 0x60;
-			sp->status2 = 0;
-
-		}
-	}
-
-	/* needed to trigger the TNC watchdog */
-	sp->tty->driver->write(sp->tty, &sp->led_state, 1);
-
-        /* if the state byte has been received, the TNC is present,
-           so the resync timer can be reset. */
-
-	if (sp->tnc_state == TNC_IN_SYNC) {
-		del_timer(&sp->resync_t);
-		sp->resync_t.data	= (unsigned long) sp;
-		sp->resync_t.function	= resync_tnc;
-		sp->resync_t.expires	= jiffies + SIXP_INIT_RESYNC_TIMEOUT;
-		add_timer(&sp->resync_t);
-	}
-
-	sp->status1 = cmd & SIXP_PRIO_DATA_MASK;
-}
-
-/* identify and execute a standard 6pack command byte */
-
-static void decode_std_command(struct sixpack *sp, unsigned char cmd)
-{
-	unsigned char checksum = 0, rest = 0, channel;
-	short i;
-
-	channel = cmd & SIXP_CHN_MASK;
-	switch (cmd & SIXP_CMD_MASK) {     /* normal command */
-	case SIXP_SEOF:
-		if ((sp->rx_count == 0) && (sp->rx_count_cooked == 0)) {
-			if ((sp->status & SIXP_RX_DCD_MASK) ==
-				SIXP_RX_DCD_MASK) {
-				sp->led_state = 0x68;
-				sp->tty->driver->write(sp->tty, &sp->led_state, 1);
-			}
-		} else {
-			sp->led_state = 0x60;
-			/* fill trailing bytes with zeroes */
-			sp->tty->driver->write(sp->tty, &sp->led_state, 1);
-			rest = sp->rx_count;
-			if (rest != 0)
-				 for (i = rest; i <= 3; i++)
-					decode_data(sp, 0);
-			if (rest == 2)
-				sp->rx_count_cooked -= 2;
-			else if (rest == 3)
-				sp->rx_count_cooked -= 1;
-			for (i = 0; i < sp->rx_count_cooked; i++)
-				checksum += sp->cooked_buf[i];
-			if (checksum != SIXP_CHKSUM) {
-				printk(KERN_DEBUG "6pack: bad checksum %2.2x\n", checksum);
-			} else {
-				sp->rcount = sp->rx_count_cooked-2;
-				sp_bump(sp, 0);
-			}
-			sp->rx_count_cooked = 0;
-		}
-		break;
-	case SIXP_TX_URUN: printk(KERN_DEBUG "6pack: TX underrun\n");
-		break;
-	case SIXP_RX_ORUN: printk(KERN_DEBUG "6pack: RX overrun\n");
-		break;
-	case SIXP_RX_BUF_OVL:
-		printk(KERN_DEBUG "6pack: RX buffer overflow\n");
-	}
-}
-
-/* decode a 6pack packet */
-
-static void
-sixpack_decode(struct sixpack *sp, unsigned char *pre_rbuff, int count)
-{
-	unsigned char inbyte;
-	int count1;
-
-	for (count1 = 0; count1 < count; count1++) {
-		inbyte = pre_rbuff[count1];
-		if (inbyte == SIXP_FOUND_TNC) {
-			tnc_set_sync_state(sp, TNC_IN_SYNC);
-			del_timer(&sp->resync_t);
-		}
-		if ((inbyte & SIXP_PRIO_CMD_MASK) != 0)
-			decode_prio_command(sp, inbyte);
-		else if ((inbyte & SIXP_STD_CMD_MASK) != 0)
-			decode_std_command(sp, inbyte);
-		else if ((sp->status & SIXP_RX_DCD_MASK) == SIXP_RX_DCD_MASK)
-			decode_data(sp, inbyte);
-	}
-}
-
-MODULE_AUTHOR("Ralf Baechle DO1GRB <[email protected]>");
+MODULE_AUTHOR("Ralf Baechle DL5RB <[email protected]>");
 MODULE_DESCRIPTION("6pack driver for AX.25");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_LDISC(N_6PACK);

-
To unsubscribe from this list: send the line "unsubscribe linux-hams" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#2 lore raw

Re: YAPP File Transfer with Linux

Quoted 8 lines · On Mon, 11 Jul 2005, Bill Vodall WA7NWP wrote:

I'm looking for a command line YAPP file transfer
facility for Linux.

I found AFServ at Hamsoft but the links there are dead.

<http://radio.linux.org.au/pkgdetail.phtml?sectpat=All&ordpat=title&descpat=&pkgid=352>

Might this work?

http://www.sm5sxl.net/~mats/src/unix/mfjterm/

A Google search for "YAPP linux protocol WA7MBL" found it. Found a few others too.

--
Curt, WE7U. APRS Client Comparisons: http://www.eskimo.com/~archer
"Lotto: A tax on people who are bad at math." -- unknown
"Windows: Microsoft's tax on computer illiterates." -- WE7U "The world DOES revolve around me: I picked the coordinate system!"

#3 lore raw

Re: YAPP File Transfer with Linux

In reply to Bill Vodall WA7NWP
Quoted 2 lines · On Mon, 11 Jul 2005, Bill Vodall WA7NWP wrote:

I'm looking for a command line YAPP file transfer
facility for Linux.

Found this on my SuSE system:

/usr/share/doc/packages/ax25-doc/yappxfer.pas and yappxfer.doc

You could either compile the pascal program or convert it to C and compile it.

--
Curt, WE7U. APRS Client Comparisons: http://www.eskimo.com/~archer
"Lotto: A tax on people who are bad at math." -- unknown
"Windows: Microsoft's tax on computer illiterates." -- WE7U "The world DOES revolve around me: I picked the coordinate system!"

#4 lore raw

Re: YAPP File Transfer with Linux

In reply to Bill Vodall WA7NWP
Quoted 3 lines · On Mon, 11 Jul 2005 14:59:36 -0700 Bill Vodall WA7NWP wrote:

I'm looking for a command line YAPP file transfer
facility for Linux.

Linpac does yapp transfers. I use it, and can upload or download files from the local fbb bbs.

Linpac is a console packet terminal program. It seems like old dos baycom program. It's mail support is not that good, but I like it.

#5 lore raw

Re: YAPP File Transfer with Linux

Quoted 11 lines
Quoted 2 lines · Bill Vodall WA7NWP wrote:

I'm looking for a command line YAPP file transfer
facility for Linux.

Linpac does yapp transfers. I use it, and can upload or download files from the local fbb bbs.

Linpac is a console packet terminal program. It seems like old dos baycom program. It's mail support is not that good, but I like it.

Thanks for the reply.

Linpac might work as the client IF it can be scripted to do the transfer as part of a script with no user intervention.

I'm looking for a much lighter weight serve application then having to use a full FBB installation.

The examples Curt found might work with some modifications if I can't find anything else.

Ideally this will work over the AX25 packet system in Linux.

The goal is to be able to script something like:

# Package Email and NNTP postings in a single file (UUCP does this) # (or use a file of exported packet bulletins)

 $ bzip2 -9 FILE
 # send the compressed bundle to the remote system
 $ ax2cp FILE.bz  REMOTE-SYSTEM:FILE.bz

Once at the remote, the file would be decompressed and imported into the standard Email, News or Packet communication systems.

An alternate solution would be UUCP directly over AX25 packet. I know it's been done. Has anybody here worked through the details and set it up?

Thanks all,

Bill - WA7NWP

#6 lore raw

Digi-ned output file and logrotate

Another Linux question:

Is it possible to use syslogd on stdout from an application?

I'd like to save the verbose output from digi_ned in a file for monitoring. I don't want the file to get too large.

Restarting the program on a regular basis would be one solution but I'm hoping for something cleaner.

Hmmm. Maybe "logrotate" is what I'm looking for.

Any suggestions or hints?

Thanks,
Bill - WA7NWP

#7 lore raw

Re: Digi-ned output file and logrotate

Bill,

You can configure logrotate to rotate a log file based on size. Then it can be compresssed and even emailed to a given address.

If you need syntax I can scare some up for you

Signature · 3 lines
'73'

Jim - KC9AOP
Quoted 27 lines · Bill Vodall

Another Linux question:

Is it possible to use syslogd on stdout from an application?

I'd like to save the verbose output from digi_ned in a file for monitoring. I don't want the file to get too large.

Restarting the program on a regular basis would be one solution but I'm hoping for something cleaner.

Hmmm. Maybe "logrotate" is what I'm looking for.

Any suggestions or hints?

Thanks,
Bill - WA7NWP

-
To unsubscribe from this list: send the line "unsubscribe linux-hams" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

Signature · 3 lines
'73'

Jim - KC9AOP
#8 lore raw

Re: YAPP File Transfer with Linux

In reply to Bill Vodall
Quoted 33 lines · Bill Vodall
Quoted 11 lines
Quoted 2 lines · Bill Vodall WA7NWP wrote:

I'm looking for a command line YAPP file transfer
facility for Linux.

Linpac does yapp transfers. I use it, and can upload or download files from the local fbb bbs.

Linpac is a console packet terminal program. It seems like old dos baycom program. It's mail support is not that good, but I like it.

Thanks for the reply.

Linpac might work as the client IF it can be scripted to do the transfer as part of a script with no user intervention.

I'm looking for a much lighter weight serve application then having to use a full FBB installation.

The examples Curt found might work with some modifications if I can't find anything else.

Ideally this will work over the AX25 packet system in Linux.

The goal is to be able to script something like:

# Package Email and NNTP postings in a single file (UUCP does this) # (or use a file of exported packet bulletins)

 $ bzip2 -9 FILE
 # send the compressed bundle to the remote system
 $ ax2cp FILE.bz  REMOTE-SYSTEM:FILE.bz
Quoted 7 lines

Once at the remote, the file would be decompressed and imported into the standard Email, News or Packet communication systems.

An alternate solution would be UUCP directly over AX25 packet. I know it's been done. Has anybody here worked through the details and set it up?

Another alternate would be to use a FTP client which allows sending a file via the command line, such as ncftpput. If there is a way to use SSH without encryption (or if the FCC dropped the prohibition of encryption), scp could handle the file transfer and compression in one step. Or are you trying to avoid tcp/ip?

Bob, N7XY

#9 lore raw

Re: YAPP File Transfer with Linux

Quoted 5 lines · Bob Nielsen

Another alternate would be to use a FTP client which allows sending a file via the command line, such as ncftpput. If there is a way to use SSH without encryption (or if the FCC dropped the prohibition of encryption), scp could handle the file transfer and compression in one step. Or are you trying to avoid tcp/ip?

Yes. I'm guessing TCP/IP cuts the transfer rate in half and that's a best case without any digi's or nodes.

FTP (and other options <wink>) work fine but I'm looking for something that reduces the overhead to a minimum.

Thanks for the reply.

Quoted 1 line

Bob, N7XY

Bill

#10 lore raw

Re: YAPP File Transfer with Linux

Quoted 8 lines · Bill Vodall
Quoted 5 lines · Bob Nielsen

Another alternate would be to use a FTP client which allows sending a file via the command line, such as ncftpput. If there is a way to use SSH without encryption (or if the FCC dropped the prohibition of encryption), scp could handle the file transfer and compression in one step. Or are you trying to avoid tcp/ip?

Quoted 6 lines

Yes. I'm guessing TCP/IP cuts the transfer rate in half and that's a best case without any digi's or nodes.

FTP (and other options <wink>) work fine but I'm looking for something that reduces the overhead to a minimum.

You realize, of course, that YAPP has its own overhead issues.

Bob

#11 lore raw

Re: YAPP File Transfer with Linux

Quoted 11 lines
Quoted 7 lines

Yes. I'm guessing TCP/IP cuts the transfer rate in half and that's a best case without any digi's or nodes.

FTP (and other options <wink>) work fine but I'm looking for something that reduces the overhead to a minimum.

You realize, of course, that YAPP has its own overhead issues.

Bob

Hopefully it's per file and not per packet like TCP/IP.

I watched Airmail send a message (15k picture) over AX25
a couple weeks ago and it beautiful. 3 full packets
of compressed data followed by a single ACK. 3 more data
packets and one more ACK. A minute or so later and it
was done.

We should be able to do the same, or better (as we have better compression) with native system tools.

Bill - WA7NWP

#12 lore raw

RE: YAPP File Transfer with Linux

Quoted 5 lines · Bill - WA7NWP wrote:

I watched Airmail send a message (15k picture) over AX25
a couple weeks ago and it beautiful. 3 full packets
of compressed data followed by a single ACK. 3 more data
packets and one more ACK. A minute or so later and it
was done.

Is TCP/IP often (always?) encapsulated in NetROM or similar protocols over AX.25, or is it possible (implemented somewhere) to send IP-packets right in AX.25's payload? The routing has to be figured out some way...

I know TCP/IP, but I'm not an expoert on AX.25. The max packet length is 256 bytes, right? Alignment in order to send full packets should be the clue to an efficient transfer.

Regards
Bob - LA6GHA

#13 lore raw

Re: YAPP File Transfer with Linux

Quoted 3 lines · Robert Eliassen

Is TCP/IP often (always?) encapsulated in NetROM or similar protocols over AX.25, or is it possible (implemented somewhere) to send IP-packets right in AX.25's payload? The routing has to be figured out some way...

From what I remember, both are possible. TCP/IP can be encapsulated into the payload of an AX.25 frame, or it can also be a part of netrom communication. IIRC, when TCP/IP is sent via NET/ROM there are 3 layers - TCP/IP encapsulated in AX.25, further encapsulated into NETROM, but I may be mistaken about that. It's been a while since I played with JNOS and saw all that stuff.

Jeremy, NW7JU

#14 lore raw

Re: YAPP File Transfer with Linux

Quoted 10 lines · Jeremy Utley
Quoted 6 lines · Robert Eliassen

Is TCP/IP often (always?) encapsulated in NetROM or similar protocols over AX.25, or is it possible (implemented somewhere) to send IP-packets right in AX.25's payload? The routing has to be figured out some way...

From what I remember, both are possible. TCP/IP can be encapsulated

into the payload of an AX.25 frame, or it can also be a part of netrom communication.

That's correct. With TCP/IP on packet, 40 of the 256 bytes are overhead. Putting it on Netrom adds another 20 bytes. The real killer is that all the ACK packets have the same (40 or 60 bytes) of overhead.

Bytes? What are bytes these days? Time to download another 2.4 GB file off the Tivo.

Bill

#15 lore raw

RE: YAPP File Transfer with Linux

Quoted 3 lines · Bill

That's correct. With TCP/IP on packet, 40 of the 256 bytes are
overhead. Putting it on Netrom adds another 20 bytes. The real killer
is that all the ACK packets have the same (40 or 60 bytes) of overhead.

Right. The IP-header is 20 bytes, and the TCP-header is also 20 bytes. I wouldn't be surprised if NetRom adds another 20 bytes as wrapping.

Now, the AX.25 protocol adds another chunk of overhead, probably close to 20 bytes (don't remember, but both source and destination address are included AFAIK) or even more when digipeaters are being used.

Avoiding the AX.25 overhead is close to impossible. But it should be possible to skip netrom and load TCP/IP right into the info-field of an AX.25 frame. Fragmented of course. But... Having double ACK (both AX.25 and TCP) is bad and a waste of bandwidth.

Another problem is the routing. It would be possible to rewrite the ARP-protocol and replace hardware addresses (MAC) with callsigs. And of course we would need to broadcast the ARP protocol... Unconnected <UI> frame mode perhaps... (starting to sound like netrom)

But the double ACK problem is still unsolved.

Another question: There is no length-field in an AX.25-frame, right? The payload is wrapped in 01111110-flags if I remember correct. So in theory we can transmit fullsize IP-frames (1500 bytes), in a single AX.25-frame ?

But I guess all this has been discussed years ago. :-)

Bob, LA6GHA

#16 lore raw

RE: YAPP File Transfer with Linux

Quoted 4 lines · Robert Eliassen

Avoiding the AX.25 overhead is close to impossible. But it should be possible to skip netrom and load TCP/IP right into the info-field of an AX.25 frame. Fragmented of course. But... Having double ACK (both AX.25 and TCP) is bad and a waste of bandwidth.

This is how IP over AX.25 works. You have the choise of using connected or unconnected mode AX.25. Unconnected (UI) has the advantage of lower overhead and avoiding double ack's but connected mode gives you lower packet loss (as visible to TCP). Relying solely on the TCP retransmissions with it's exponential backoff is a quick way to frustration. The non-TCP/IP band users will steal your bandwidth as they are running linear or no backoff and in general much more aggressive timers.

Quoted 4 lines

Another problem is the routing. It would be possible to rewrite the ARP-protocol and replace hardware addresses (MAC) with callsigs. And of course we would need to broadcast the ARP protocol... Unconnected <UI> frame mode perhaps... (starting to sound like netrom)

Callsigns are used in ARP over AX.25. Broadcasted as UI frames, destined to the AX.25 address "QST".

Quoted 1 line

But the double ACK problem is still unsolved.

Actually the ACK'ing isn't all that bad. What's bad is retransmissions on several layers. On a busy or lossy channel, when using connected mode AX.25, you quickly get in to the situation where you have TCP retransmissions in your AX.25 send queue, while the original data hasn't even been transmitted yet.

There used to be a re-write of the linux AX.25 stack around, based on work done in the Flexnet project I think (?), that had a few quite clever tricks in it. By using connected mode AX.25 to transport IP frames, they could for example use VJ compression to squeeze out some of the IP header overhead. But also they had a mechanism that purged any duplicate TCP retransmissions from the AX.25 send queue. I never got around to test it but reportedly it worked quite well.

Unfortunately the so called NEWAX25 stack died because of loss of time/interest of the original authors. :(

Quoted 3 lines

Another question: There is no length-field in an AX.25-frame, right? The payload is wrapped in 01111110-flags if I remember correct. So in theory we can transmit fullsize IP-frames (1500 bytes), in a single AX.25-frame ?

Yes. You might get some negative feedback from other users though. At least in the past some AX.25 stacks didn't quite like seeing such oversized frames and crashed... But I guess that is history now.

Quoted 1 line

But I guess all this has been discussed years ago. :-)

Yes. Discussed and implemented (in KA9Q NOS) about 20 years ago. :)

Signature · 1 line
Tomi Manninen / OH2BNS / KP20JF74
#17 lore raw

Re: YAPP File Transfer with Linux

Quoted 46 lines · Tomi Manninen
Quoted 4 lines · Robert Eliassen

Avoiding the AX.25 overhead is close to impossible. But it should be possible to skip netrom and load TCP/IP right into the info-field of an AX.25 frame. Fragmented of course. But... Having double ACK (both AX.25 and TCP) is bad and a waste of bandwidth.

This is how IP over AX.25 works. You have the choise of using connected or unconnected mode AX.25. Unconnected (UI) has the advantage of lower overhead and avoiding double ack's but connected mode gives you lower packet loss (as visible to TCP). Relying solely on the TCP retransmissions with it's exponential backoff is a quick way to frustration. The non-TCP/IP band users will steal your bandwidth as they are running linear or no backoff and in general much more aggressive timers.

Quoted 4 lines

Another problem is the routing. It would be possible to rewrite the ARP-protocol and replace hardware addresses (MAC) with callsigs. And of course we would need to broadcast the ARP protocol... Unconnected <UI> frame mode perhaps... (starting to sound like netrom)

Callsigns are used in ARP over AX.25. Broadcasted as UI frames, destined to the AX.25 address "QST".

Quoted 1 line

But the double ACK problem is still unsolved.

Actually the ACK'ing isn't all that bad. What's bad is retransmissions on several layers. On a busy or lossy channel, when using connected mode AX.25, you quickly get in to the situation where you have TCP retransmissions in your AX.25 send queue, while the original data hasn't even been transmitted yet.

There used to be a re-write of the linux AX.25 stack around, based on work done in the Flexnet project I think (?), that had a few quite clever tricks in it. By using connected mode AX.25 to transport IP frames, they could for example use VJ compression to squeeze out some of the IP header overhead. But also they had a mechanism that purged any duplicate TCP retransmissions from the AX.25 send queue. I never got around to test it but reportedly it worked quite well.

Unfortunately the so called NEWAX25 stack died because of loss of time/interest of the original authors. :(

Quoted 3 lines

Another question: There is no length-field in an AX.25-frame, right? The payload is wrapped in 01111110-flags if I remember correct. So in theory we can transmit fullsize IP-frames (1500 bytes), in a single AX.25-frame ?

Quoted 7 lines

Yes. You might get some negative feedback from other users though. At least in the past some AX.25 stacks didn't quite like seeing such oversized frames and crashed... But I guess that is history now.

Quoted 1 line

But I guess all this has been discussed years ago. :-)

Yes. Discussed and implemented (in KA9Q NOS) about 20 years ago. :)

Some years back we had some links that we ran IP over ROSE, we used TNOS boxes on each end of the path to talk to the network, we took advantage of the fact that ROSE handled the 'M' bit such that you could hand a IP frame in fragments to the network and it would rebuild the thing on the far end and pass it on in it's original state. ROSE did so quite elegantly, and it's follow on FPAC does the same thing quite well
It appears that the ax25 implementation will allow for frame sizes of up to 512 bytes, and it will also appears to allow for extended ax25 i.e. module 128 rather
than modulo 7, and by going to modulo 128 you can then run selective reject.

I would think that on good paths a combination of the above should be able to give some impressive results. Combining that with FPAC should make it run even better if the testing we did with the older ROSE and max 7 frames with no selective
reject worked so well. As we replace the old network here in Florida I hope to give
some of this a try. too bad the newax15 did not prosper, it sounds like it may have been a good move.

Using KISS TNC's talking with TNOS boxes I have tested the sending of 1500 byte packets, it worked just fine and that was back 10 - 12 years ago, using tek radios
at 9k6 b/s

One thing that both ROSE and FPAC do is extend the size of the level 3 frame in order to avoid taking space from the 256 bytes of bearer space unlike NetRom, so we did not have to worry about that issue when passing IP over ROSE/FPAC links. But indeed some tnc's even did not like to see the large frames, too bad that that some were short sighted in this area. The use of the 'm' bit reduced the
IP over head to just the first frame of the series of frames that made up the larger
IP frame. It was neat to watch it on a monitor screen, indeed the monitor screen on TNOS and I am pretty sure JNOS would show those segements arriving and show the segemnt number count down as they arrived.

You know I miss that stuff, it was fun...

Signature · 5 lines
Chuck Hast 
To paraphrase my flight instructor;
"the only dumb question is the one you DID NOT ask resulting in my going
out and having to identify your bits and pieces in the midst of torn
and twisted metal."
#18 lore raw

RE: YAPP File Transfer with Linux

In reply to Robert Eliassen
Quoted 11 lines

Right. The IP-header is 20 bytes, and the TCP-header is also 20 bytes. I wouldn't be surprised if NetRom adds another 20 bytes as wrapping.

Now, the AX.25 protocol adds another chunk of overhead, probably close to 20 bytes (don't remember, but both source and destination address are included AFAIK) or even more when digipeaters are being used.

Avoiding the AX.25 overhead is close to impossible. But it should be possible to skip netrom and load TCP/IP right into the info-field of an AX.25 frame. Fragmented of course. But... Having double ACK (both AX.25 and TCP) is bad and a waste of bandwidth.

This is, I believe, the preferred way of doing TCP/IP over AX.25. AX.25 has "first class citizen" support for IP - there's a unique AX.25 protocol identifier for IP (just as there is for NETROM and for the normal AX.25 connection protocol) and another for IP ARP.

These IP and ARP packets are not encapsulated in the higher-level AX.25 Layer 3 packets. Rather, they're riding on top of AX.25 Layer 2, just as AX.25 Layer 3 and NETROM packets do.

It's entirely possible to run TCP/IP over AX.25 without suffering from IP fragmentation in the packets when they traverse the AX.25 link(s). This is done by configuring the MTU of the AX.25 interface properly, and letting the (fairly standard) IP path-MTU-discovery algorithm figure out the minimum MTU of any link in the path.

Quoted 5 lines

Another problem is the routing. It would be possible to rewrite the ARP-protocol and replace hardware addresses (MAC) with callsigs. And of course we would need to broadcast the ARP protocol... Unconnected <UI> frame mode perhaps... (starting to sound like netrom)

No need. Already been done, long ago. Linux supports it beautifully.

Quoted 1 line

But the double ACK problem is still unsolved.

With IP-in-AX.25, I believe that there is no double-ACK problem at all. IP-in-AX.25 uses unnumbered (UI) frames. All acknowledgement and flow control is handled at the TCP layer. If you do UDP-over-IP-over AX.25, any acknowledgement is done at a higher layer - there won't be any done at all by UDP, IP, or AX.25!

Quoted 3 lines

Another question: There is no length-field in an AX.25-frame, right? The payload is wrapped in 01111110-flags if I remember correct. So in theory we can transmit fullsize IP-frames (1500 bytes), in a single AX.25-frame ?

The spec says "The default maximum number of octets allowed in the I field is 256. This variable is negotiable between end stations. The I field is an integral number of octets."

So, as I read it, if you're running IP-over-AX.25, you could negotiate a larger I-limit (and thus a larger interface MTU) with your peer stations ahead of time. I suspect that you'd have to set up your interface to use the *minimum* I limit / MTU of any of the stations with which you were communicating directly (or via digipeat) at the AX.25 level.

If I recall correctly, IP is not limited to a 1500-byte MTU. That limitation is set by standard 10-base-whatever Ethernet. It's possible to set up a larger IP MTU for other sorts of links.

So, there are a couple of ways that things can go, packet-wise:

- Set the AX.25 interface MTU to 255 (which seems to be the Linux default). Inbound and outbound connections from your own system will honor this limit. IP being forwarded through your system may either end up being fragmented (if the sender isn't doing MTU path discovery and if your system is configured to permit fragmentation to occur), or may be forced down to smaller IP packets via voluntary or involuntary "no fragmentation here" processing.

- Set the AX.25 MTU higher than 255, and make sure that every AX.25 node with which you're in contact on that interface / radio agrees with your higher limit.

Linux also allows you to play with some of the other TCP parameters in order to promote the reliability of IP-over-AX.25 operation. On my laptop (soundmodem) setup, I use /sbin/route to set up the route to the 44.* network with "irtt 3000 window 220". The irtt setting is particularly helpful, as it prevents TCP from doing a whole bunch of retries during the very early stages of connection setup and transmission. The "window 220" is a kluge I put in place to keep the laptop from ever sending two IP frames back-to-back in a single keydown, and was required to work around the fact that the TNC-X at my house becomes confused by the not-quite-AX.25- conformant inter-frame fill behavior of the user-mode soundmodem code.

Quoted 1 line

But I guess all this has been discussed years ago. :-)

Seems to have been! I'd suggest reading the AX.25 protocol specification, current revision (2.2, I think). It's normally available via www.tapr.org, but they've recently reorganized their site and the links to the spec seem to be broken.

#19 lore raw

Re: YAPP File Transfer with Linux

Quoted 6 lines · Dave Platt
Quoted 1 line

But I guess all this has been discussed years ago. :-)

Seems to have been! I'd suggest reading the AX.25 protocol specification, current revision (2.2, I think). It's normally available via www.tapr.org, but they've recently reorganized their site and the links to the spec seem to be broken.

Yeah tapr.org is on a new server and there are a few bugs which still need to be worked out.

Try <http://www.tapr.org/pdf/AX25.2.2.pdf>.

73, Bob N7XY

Signature · 2 lines
Bob Nielsen, N7XY                          n7xy (at) n7xy.net
Bainbridge Island, WA                      http://www.n7xy.net
#20 lore raw

Re: YAPP File Transfer with Linux

In reply to Bill Vodall
Quoted 6 lines · Bill Vodall
Quoted 3 lines
Quoted 3 lines

FTP (and other options <wink>) work fine but I'm looking for something that reduces the overhead to a minimum.

Hopefully it's per file and not per packet like TCP/IP.

Quoted 8 lines

I watched Airmail send a message (15k picture) over AX25
a couple weeks ago and it beautiful. 3 full packets
of compressed data followed by a single ACK. 3 more data
packets and one more ACK. A minute or so later and it
was done.

We should be able to do the same, or better (as we have better compression) with native system tools.

So what you seem to be looking for are tools that send and receive files using just AX.25. 'ax25send filename ve3tix' and 'ax25receive' running on the listening ("server") side.

I don't know of anything, but it wouldn't be that hard to write.

Maybe if I find some free time.

-ve3tix

#21 lore raw

Re: YAPP File Transfer with Linux

Quoted 6 lines

So what you seem to be looking for are tools that send and receive files using just AX.25. 'ax25send filename ve3tix' and 'ax25receive' running on the listening ("server") side.

I don't know of anything, but it wouldn't be that hard to write.

Exactly. Maybe a bit more then that if we have some scripting to navigate the connections through the nodes and digis. That wouldn't even be needed as we might be able to use Expect.

YAPP and the files Curt found might be a good starting place. Tieing it through the AX25 system could be a bit tricky. Also hopefully it doesn't have any extraneous overhead.

Quoted 1 line

Maybe if I find some free time.

It would be appreciated. I'm in a good situation here for a while with access to a parallel Linux box across town. That makes it easy to experiment and test new techniques.

Quoted 1 line

-ve3tix

Bill

#22 lore raw

Re: YAPP File Transfer with Linux

Quoted 15 lines · On 7/12/05, Bill - WA7NWP <[email protected]> wrote:
Quoted 6 lines

So what you seem to be looking for are tools that send and receive files using just AX.25. 'ax25send filename ve3tix' and 'ax25receive' running on the listening ("server") side.

I don't know of anything, but it wouldn't be that hard to write.

Exactly. Maybe a bit more then that if we have some scripting to navigate the connections through the nodes and digis. That wouldn't even be needed as we might be able to use Expect.

YAPP and the files Curt found might be a good starting place. Tieing it through the AX25 system could be a bit tricky. Also hopefully it doesn't have any extraneous overhead.

Quoted 7 lines
Quoted 1 line

Maybe if I find some free time.

It would be appreciated. I'm in a good situation here for a while with access to a parallel Linux box across town. That makes it easy to experiment and test new techniques.

Quoted 1 line

-ve3tix

Folks, I have not used it my self, but some of the fellows who maintain our FPAC network in Florida use YAPP to update the files on the switches. FPAC has YAPP built in, we use it with either one of the yapp programs of automated uploading using f6fbb BBS.

The move to fpac Linux on our network brings up the question of using other more efficient modes of sending files, so anything that will work better is most certainly welcome.

Signature · 5 lines
Chuck Hast 
To paraphrase my flight instructor;
"the only dumb question is the one you DID NOT ask resulting in my going
out and having to identify your bits and pieces in the midst of torn
and twisted metal."
#23 lore raw

RE: YAPP File Transfer with Linux

In reply to Bob Nielsen
Quoted 4 lines

If there is a way to use SSH without encryption (or if the FCC dropped the prohibition of encryption), scp could handle the file transfer and compression in one step.

scp is the encrypted version of rcp

Bob, LA6GHA

#24 lore raw

SSH and the NONE option

Quoted 2 lines

scp could handle the file transfer and compression in one step.

While I'm at it and on to a totally separate topic -- is anybody here acquainted with the folks at the openSsh project?

SSH (and all the 's' tools such as scp) used to have a valid encryption option of "none" which I believe has been removed.

It would be very good for us amateurs (at least we Americans living with regulations from the dark ages) if the "none" option on encryption
was still available. One of these days I plan to contact the openSSH
folks with this request -- unless somebody here has a better idea.

73,
Bill - WA7NWP

#25 lore raw

Re: SSH and the NONE option

Quoted 5 lines · Bill Vodall
Quoted 1 line

scp could handle the file transfer and compression in one step.

While I'm at it and on to a totally separate topic -- is anybody here acquainted with the folks at the openSsh project?

Quoted 8 lines

SSH (and all the 's' tools such as scp) used to have a valid encryption option of "none" which I believe has been removed.

It would be very good for us amateurs (at least we Americans living with regulations from the dark ages) if the "none" option on encryption
was still available. One of these days I plan to contact the openSSH
folks with this request -- unless somebody here has a better idea.

Last I checked available algorithems were a compile time option; it's also possible to further restrict the available cyphers on the server side in sshd_config.

73 de DL5RB op Ralf

--
Loc. JN47BS / CQ 14 / ITU 28 / DOK A21

#26 lore raw

Re: SSH and the NONE option

Quoted 13 lines
Quoted 4 lines

While I'm at it and on to a totally separate topic -- is anybody here acquainted with the folks at the openSsh project?

Quoted 8 lines

SSH (and all the 's' tools such as scp) used to have a valid encryption option of "none" which I believe has been removed.

It would be very good for us amateurs (at least we Americans living with regulations from the dark ages) if the "none" option on encryption
was still available. One of these days I plan to contact the openSSH
folks with this request -- unless somebody here has a better idea.

Quoted 3 lines

Last I checked available algorithems were a compile time option; it's also possible to further restrict the available cyphers on the server side in sshd_config.

When I first looked at this, about 3 years ago???, type NONE was a compile time option. Last I looked, it seems to have disappeared from the available choices.

Maybe we need to pull an really old version for our over the air use. I'd hate to do that as we'd lose bug fixes and other improvements.

73,
Bill

#27 lore raw

Re: SSH and the NONE option

In reply to Bill Vodall
Quoted 8 lines · Bill Vodall <wa7nwp <at> jnos.org> writes:

It would be very good for us amateurs (at least we Americans living with regulations from the dark ages) if the "none" option on encryption
was still available. One of these days I plan to contact the openSSH
folks with this request -- unless somebody here has a better idea.

73,
Bill - WA7NWP

Why not just use something like gzip on the standard output and pipe it over the network with netcat? I don't think something as robust and clunky (sort of) as ssh would be needed for copying files over the air where length is more important.
Just a thought.

Jonathan Lassoff (KG6THI)

#28 lore raw

Re: SSH and the NONE option

Quoted 3 lines

Why not just use something like gzip on the standard output and pipe it over the network with netcat?

That could be a very good thing for files. What does netcat use for authentication and access control?

Bill - WA7NWP

#29 lore raw

Re: SSH and the NONE option

Bill,

Maybe you could use samba and encrypt passwords?

Quoted 14 lines · On 7/12/05, Bill Vodall WA7NWP <[email protected]> wrote:
Quoted 4 lines

Why not just use something like gzip on the standard output and pipe it over the network with netcat?

That could be a very good thing for files. What does netcat use for authentication and access control?

Bill - WA7NWP
-
To unsubscribe from this list: send the line "unsubscribe linux-hams" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

Signature · 3 lines
'73'

Jim - KC9AOP
#30 lore raw

Re: SSH and the NONE option

Quoted 3 lines · Jim Bayer

Bill,

Maybe you could use samba and encrypt passwords?

(to the list this time)

SMB/CIFS (the protocols that samba implements) was designed for LAN usage. It is painful on high speed WANs (very chatty) I cannot imagine using it on AX.25 over the air.

#31 lore raw

Re: SSH and the NONE option

In reply to Bill Vodall WA7NWP
Quoted 7 lines · On Tue, Jul 12, 2005 at 12:08:30PM -0700, Bill Vodall WA7NWP wrote:
Quoted 4 lines

Why not just use something like gzip on the standard output and pipe it over the network with netcat?

That could be a very good thing for files. What does netcat use for authentication and access control?

Netcat has no authentication or access control itself. It's simply a network aware version of 'cat'.

#32 lore raw

Re: SSH and the NONE option

Quoted 4 lines

Netcat has no authentication or access control itself. It's simply a network aware version of 'cat'.

There's got to be something. If not, I'm going to save all my .tivo files on your servers. :-)

Bill

#33 lore raw

Re: SSH and the NONE option

In reply to Bill Vodall
Quoted 2 lines

SSH (and all the 's' tools such as scp) used to have a valid encryption option of "none" which I believe has been removed.

The Version 3.4 client on one of my older Debian boxes was perfectly happy to take "-c NONE". The server would have to be configured to accept NONE also, which I didn't try.

I see no code in the source for version 4.1 which would suggest it's been removed as an option, or that it's a conditionally compiled one.

De

#34 lore raw

Re: SSH and the NONE option

In reply to Bill Vodall
Quoted 5 lines · Bill Vodall

It would be very good for us amateurs (at least we Americans living with regulations from the dark ages) if the "none" option on encryption
was still available. One of these days I plan to contact the openSSH
folks with this request -- unless somebody here has a better idea.

It's not only the US that forbid encryption in amateur radio - it's the legislation of every country that I know of, based on international regulations. And I'm favor of that because otherwise amateur radio would probably turn into a fancy telephone & internet replacement.

The only exception I recall are encrypted transmission for the control of amateur satellites which were recently legalized in Germany and a transmission for comemoration of breaking the German ww2 encryption machine a while ago were a UK station was transmitting test encrypted with a single wheel enigma in cw and the receiving stations were supposed to break it which had to be approved by the British OFCOM first.

73 de DL5RB op Ralf

--
Loc. JN47BS / CQ 14 / ITU 28 / DOK A21

#35 lore raw

Re: SSH and the NONE option

Quoted 12 lines · Ralf Baechle DL5RB wrote:
Quoted 7 lines · Bill Vodall

It would be very good for us amateurs (at least we Americans living with regulations from the dark ages) if the "none" option on encryption
was still available. One of these days I plan to contact the openSSH
folks with this request -- unless somebody here has a better idea.

Quoted 7 lines

It's not only the US that forbid encryption in amateur radio - it's the legislation of every country that I know of, based on international regulations. And I'm favor of that because otherwise amateur radio would probably turn into a fancy telephone & internet replacement.

That used to be the case also here in Sweden but I can't find it any longer in the newer regulations. The transmission should be identified by using the callsign but that's really it.

73 de Pär/sm0rwo

-
To unsubscribe from this list: send the line "unsubscribe linux-hams" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#36 lore raw

Re: SSH and the NONE option

Quoted 25 lines · Per Crusefalk
Quoted 12 lines · Ralf Baechle DL5RB wrote:
Quoted 7 lines · Bill Vodall

It would be very good for us amateurs (at least we Americans living with regulations from the dark ages) if the "none" option on encryption
was still available. One of these days I plan to contact the openSSH
folks with this request -- unless somebody here has a better idea.

Quoted 7 lines

It's not only the US that forbid encryption in amateur radio - it's the legislation of every country that I know of, based on international regulations. And I'm favor of that because otherwise amateur radio would probably turn into a fancy telephone & internet replacement.

That used to be the case also here in Sweden but I can't find it any longer in the newer regulations. The transmission should be identified by using the callsign but that's really it.

Quoted 7 lines

73 de Pär/sm0rwo

-
To unsubscribe from this list: send the line "unsubscribe linux-hams" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

So it seems we've come full circle.

Everything in Amature Radio is clear text, so any protocol for authentication has to be OK. Your ID and password comes along in clear text and that's that. I guess frequent password changes are the only answer to comfort with security.

Seems like ftp and rcp may be the best bet.

Signature · 7 lines
'73'

Jim - KC9AOP
-
To unsubscribe from this list: send the line "unsubscribe linux-hams" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#37 lore raw

Re: SSH and the NONE option

Quoted 11 lines

So it seems we've come full circle.

Everything in Amature Radio is clear text, so any protocol for authentication has to be OK. Your ID and password comes along in clear text and that's that. I guess frequent password changes are the only answer to comfort with security.

Seems like ftp and rcp may be the best bet.

If a two factor authentication scheme could be used, then that's the ticket.... a challenge response authentication for example... more elegant would be something using a hashed password based on a passcode and revolving token. Let's be creative, there are more ways then just "ssh"

Andrew

#38 lore raw

Re: SSH and the NONE option

Quoted 6 lines
Quoted 6 lines

Everything in Amature Radio is clear text, so any protocol for authentication has to be OK. Your ID and password comes along in clear text and that's that. I guess frequent password changes are the only answer to comfort with security.

Quoted 8 lines
Quoted 2 lines

Seems like ftp and rcp may be the best bet.

If a two factor authentication scheme could be used, then that's the ticket.... a challenge response authentication for example... more elegant would be something using a hashed password based on a passcode and revolving token. Let's be creative, there are more ways then just "ssh"

I thought this issue through when I was setting up an SMTP/IMAP server for TCP/IP-over-AX.25. I came to the tentative conclusion that it would probably be OK to use authentication systems such as the CRAM-MD5 and similar hash-based schemes. These don't actually send the password over the air (encrypted or otherwise); rather, they're of the challenge/response sort, in which the client proves that s/he has a secret also known to the server, but the secret itself is not transmitted.

These algorithms do use a "large binary number to ASCII" encoding for transmitting the challenge from the server and the response by the client, but this is a publicly-documented algorithm and I think it can be argued that it doesn't obscure the meaning of the data being transmitted.

Another alternative, which would be entirely in clear text, would be a one-time password system based on S/Key. The standard Linux implementation for this would be OPIE ("One-Time Passwords in Everything"). There's an OPIE plugin for the Linux PAM (pluggable authentication module) system, which is or can be used by ssh, login, ftp, rcp/rsh, and so forth. An FTP session, or a simple login session which invoked netcat, might be a decent way to provide for in-the-clear data transfer to a system which still had a hard-to-crack access authentication.

An OPIE-based authentication system can have a place even in the wired-communication world where secure systems such as ssh are available. A server which runs ssh, and which will accept OPIE or other one-time passwords for access, is a convenient thing to have if you think you may have to use public-access computers (libraries, cybercafes) to access your system, and you're concerned about malware such as keystroke loggers which might have been installed on those systems.

#39 lore raw

Re: SSH and the NONE option

In reply to Jim Bayer
Quoted 4 lines · Jim Bayer

Everything in Amature Radio is clear text, so any protocol for authentication has to be OK. Your ID and password comes along in clear text and that's that. I guess frequent password changes are the only answer to comfort with security.

Don't forget that (at least in the US) the rules state you cannot obscure the meaning...

Section 97.113 (4) "...messages in codes or ciphers intended to obscure the meaning thereof, except as otherwise provided herein..."

The reason people are interested in ssh with "none" encryption is that it can authenticate a session securely without passing the password in plaintext. With public key cryptography, the authentication shouldn't present a problem, since authentication is generally done by one side sending over some random data as a token (which is plaintext; it means what it is) and the other side encrypts it with their private key and sends it back. Everyone listening knows a) the plain-text that is being encrypted, and b) the public key can be public, so anyone can decrypt it.

I'm not sure ssh signs the packets after the initial authentication when using none encryption. An alternative might be the Authentication Header portion of IPsec, which is designed for the case where you need to authenticate the validity of a packet without encrypting it. However, setting up IPsec AH is at least an order of magnitude harder than using ssh/none though.

Here's an interesting URL discussing some of the issues around ham authentication:
http://www.cc.gatech.edu/ugrads/r/rietta/AuthRadio/authenticated-radio-article.html

Bob N2KGO

#40 lore raw

Re: SSH and the NONE option

Quoted 6 lines · Bob Snyder

Don't forget that (at least in the US) the rules state you cannot obscure the meaning...

Section 97.113 (4) "...messages in codes or ciphers intended to obscure the meaning thereof, except as otherwise provided herein..." Bob N2KGO

Why not just have a challenge and response design like Andrew Bates suggested. For example, what if the server sent a challenge string, and the user concatenated their authentication string to the challenge and then made an md5 hash of the whole string and sent it for authentication. The server would then do the same and compare the strings. It's kind of how APOP and Yahoo! mail work. But, to any monitoring party, how would they know weather or not the md5 hash is your password, or a crypted authentication response? I'm not sure what obscuring the meaning really means. Since the user really means the md5sum to be sent, is that hiding the underlying authentication scheme?
Isn't phone and CW communication really obscuring what an operator means. When speaking over the radio, my brain takes concepts and expresses them in a crypted fashion called "language". To me, this is a more complex issue that isn't really explained well enough in 97.113(4). I think that, on a more ethical level, by using crypted authentication, nothing is really being hidden. It's just overhead data in the protocol. In which case, isn't AX.25 just crypted OSI layer 1 and 2 traffic? It's accepted because the standard is readily available to the public. So why couldn't a challenge and response authentication scheme that is available to the public be accepted as well?
Just my two cents.

Jonathan Lassoff (KG6THI)

#41 lore raw

Re: SSH and the NONE option

Quoted 2 lines · Jonathan Lassoff

Why not just have a challenge and response design like Andrew Bates suggested. For example, what if the server sent a challenge string,

I don't see a problem with challenge/response, since there's no obscured message there. The only issue I see is that you aren't protecting the session, so after you authenticate, someone closer/stronger than you could insert malicious commands into the stream. I've seen details of man-in-the-middle exploits on the Internet where commands were inserted in a telnet stream without the connecting station knowing by syncing up sequence numbers and the like.

IPsec AH would prevent this. SSH might, if it signs the content with encryption none, but my suspecion is that it doesn't, that it only beats telnet for this purpose by virtue of allowing more advanced authentication mechanisms.

Bob N2KGO

#42 lore raw

Re: SSH and the NONE option

Quoted 7 lines · Bob Snyder

I don't see a problem with challenge/response, since there's no obscured message there. The only issue I see is that you aren't protecting the session, so after you authenticate, someone closer/stronger than you could insert malicious commands into the stream. I've seen details of man-in-the-middle exploits on the Internet where commands were inserted in a telnet stream without the connecting station knowing by syncing up sequence numbers and the like.

While I can see this as possible on amateur radio data streams, I'd think it unlikely for someone to want to bother with it due to the speeds we use. If we're talking 802.11a/b/g/h though it might be of a bit more interest to the black-hats. Still, you're usually talking about hams here, and I'd think few if any would be interested in doing this sort of attack on RF.

On the internet there are a lot of bored individuals and commercial/ military/ government-sponsored hackers that would be more than happy to try to mess with you.

If we're talking about packets that gate from RF to the internet then at least part of the stream is in that no-mans land where anything goes. In that case we need as much protection for the session and for authentication as we can get that is legally allowed on the RF side of things.

--
Curt, WE7U. APRS Client Comparisons: http://www.eskimo.com/~archer
"Lotto: A tax on people who are bad at math." -- unknown
"Windows: Microsoft's tax on computer illiterates." -- WE7U "The world DOES revolve around me: I picked the coordinate system!"

#43 lore raw

Re: SSH and the NONE option

Quoted 6 lines · On Thu, Jul 14, 2005 at 12:28:02PM -0700, Curt, WE7U wrote:

While I can see this as possible on amateur radio data streams, I'd think it unlikely for someone to want to bother with it due to the speeds we use. If we're talking 802.11a/b/g/h though it might be of a bit more interest to the black-hats. Still, you're usually talking about hams here, and I'd think few if any would be interested in doing this sort of attack on RF.

If the system in question was an attractive target like a control system for a large popular repeater system, I could see it, although you'd generally have out of band access. I could definately see people attracted to trying to control a satellite, but that case is already covered by most countries' rules, I think.

Sorry, I used to do security consulting as part of my job, so I think of things like this. All security, though, is a trade off between improved protection and the pain it causes. At some point you hit the point where the pain of recovering from a security breach is less than the pain you suffer to prevent it from happening.

For a local system I could visit in 5 minutes and that no one cares if it goes down, I'm willing to do most any type of security. I care a lot more if I had a site up in the mountains where I had to get permission to enter the site to correct a problem, and might consider some of these solutions.

Bob N2KGO

#44 lore raw

Re: SSH and the NONE option - more

Suppose I captured all the packets of a SSH encrypted exchange. Would it be possible to decode the contents of the exchange IF one had both the public and private keys?

If so, then we hams should be able to use SSH for amateur radio operations as long as we publish the keys - no?

Bill - WA7NWP

#45 lore raw

Re: SSH and the NONE option - more

Quoted 2 lines · Bill - WA7NWP wrote:

Suppose I captured all the packets of a SSH encrypted exchange. Would it be possible to decode the contents of the exchange IF one had both the public and private keys?

If you published both, then yes, you could decrypt the exchange I believe. That's not what you want to do generally, since it negates the whole purpose of using it. With both keys public knowledge, then anyone could fake a session using them.

What was being discussed (I thought) was having the public key public and the private key, well, private. If you do a digital signature on packet/SSH rather then encryption by making a hash of the contents of the packet and encrypting it with your private key, then anyone can decrypt the hash to verify it came from the private key in question, but no one can duplicate it for any arbitrary packet.

This should be fine on two counts. a) The hash can be decrypted with a known key, and b) The contents of the hash can be computed by running the hash algorithm over the information in question. This is in fact how you verify the information: you compute the hash yourself, decrypt the one signed by the public key, and verify they are identical.

Bob N2KGO

#46 lore raw

Re: SSH and the NONE option - more

In reply to Bill - WA7NWP
Quoted 6 lines · On Fri, Jul 29, 2005 at 06:31:09PM -0700, Bill - WA7NWP wrote:

Suppose I captured all the packets of a SSH encrypted exchange. Would
it be possible to decode the contents of the exchange IF one had both the public and private keys?

If so, then we hams should be able to use SSH for amateur radio operations as long as we publish the keys - no?

ssh uses the Diffie-Hellman algorithm to exchange randomly generated session keys. These keys are generated on the fly and destroyed at the end of the session or replaced after a certain time with new keys. The special propertie of the Diffie-Hellman algorithm is that it permits the secure exchange of the session keys even if the session is being evedropped uppon. Diffie-Hellman is vulnerable against a man in the middle attack however, so the data packets used in the key exchange are secured against this kind of attach using public key cryptography. The bottom line of all this is no, publishing the RSA or DSA public keys is useless as they're not being used for cryptography nor can their knowledge be used to decrypt anything. Ssh is a pretty smart protocol :-)

Ralf

#47 lore raw

Re: SSH and the NONE option - more

Quoted 6 lines · On Mon, 1 Aug 2005, Ralf Baechle DL5RB wrote:
Quoted 3 lines · On Fri, Jul 29, 2005 at 06:31:09PM -0700, Bill - WA7NWP wrote:

Suppose I captured all the packets of a SSH encrypted exchange. Would
it be possible to decode the contents of the exchange IF one had both the public and private keys?

Quoted 11 lines

ssh uses the Diffie-Hellman algorithm to exchange randomly generated session keys. These keys are generated on the fly and destroyed at the end of the session or replaced after a certain time with new keys. The special propertie of the Diffie-Hellman algorithm is that it permits the secure exchange of the session keys even if the session is being evedropped uppon. Diffie-Hellman is vulnerable against a man in the middle attack however, so the data packets used in the key exchange are secured against this kind of attach using public key cryptography. The bottom line of all this is no, publishing the RSA or DSA public keys is useless as they're not being used for cryptography nor can their knowledge be used to decrypt anything. Ssh is a pretty smart protocol :-)

Thanks Ralf. It looks like it's back to getting encryption type NONE going in SSH for our amatuer activities.

It was a good try.

73,
Bill - WA7NWP

#48 lore raw

Re: SSH and the NONE option

In reply to Bob Snyder
Quoted 4 lines

could insert malicious commands into the stream. I've seen details of man-in-the-middle exploits on the Internet where commands were inserted in a telnet stream without the connecting station knowing by syncing up sequence numbers and the like.

Yes, this would be possible without having some sort of validation to ensure the packet is from the actual sender (like what IPsec offers). However, if this is happening then you have dishonest hams in your area, fox hunt them and report them to the FCC. We are self policing, remember?

I couldn't say as to the last time my netrom routing table was poisoned from a malicious radio operator.

Andrew

#49 lore raw

Re: SSH and the NONE option

In reply to Jim Bayer
Quoted 8 lines · Jim Bayer

So it seems we've come full circle.

Everything in Amature Radio is clear text, so any protocol for authentication has to be OK. Your ID and password comes along in clear text and that's that. I guess frequent password changes are the only answer to comfort with security.

Seems like ftp and rcp may be the best bet.

Not really. These laws forbid obscuring the content of amateur radio transmissions. By my interpretation authentication which is what is still provided by -c none is not affected by this.

73 de DL5RB op Ralf

--
Loc. JN47BS / CQ 14 / ITU 28 / DOK A21

#50 lore raw

Re: SSH and the NONE option

In reply to Jim Bayer
Quoted 8 lines · Jim Bayer

So it seems we've come full circle.

Everything in Amature Radio is clear text, so any protocol for authentication has to be OK. Your ID and password comes along in clear text and that's that. I guess frequent password changes are the only answer to comfort with security.

I didn't follow the complete thread so maybe this has been suggested before...
A one-Time-Password scheme like S/key could be used. It sends password in clear text. They are just valid once. I've been using this for year for sysop access to our local BBS/node.

Signature · 5 lines
73, PE1ICQ  Arno Verhoeven
--------------------------------
AX.25  pe1icq@pi8zaa.#nbo.nld.eu
smtp   [email protected]
inet   [email protected] 
#51 lore raw

Re: YAPP File Transfer with Linux

In reply to Bill Vodall
Quoted 9 lines · On Tue, 12 Jul 2005 09:13:40 -0500 (CDT) Bill Vodall wrote:
Quoted 9 lines
Quoted 2 lines · Bill Vodall WA7NWP wrote:

I'm looking for a command line YAPP file transfer
facility for Linux.

Linpac does yapp transfers. I use it, and can upload or download files from the local fbb bbs.

Quoted 7 lines
Quoted 2 lines

Linpac is a console packet terminal program. It seems like old dos baycom program. It's mail support is not that good, but I like it.

Thanks for the reply.

Linpac might work as the client IF it can be scripted to do the transfer as part of a script with no user intervention.

I guess this could be done with linpac daemon (linpacd). Or perhaps you could modify the call app to do a yapp transfer from the command line. This should be possible (it supports yapp transfers, by a command).