patch-2.1.22 linux/net/rose/af_rose.c

Next file: linux/net/rose/rose_dev.c
Previous file: linux/net/netsyms.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.21/linux/net/rose/af_rose.c linux/net/rose/af_rose.c
@@ -18,7 +18,7 @@
  *			Terry (VK2KTJ)	Added support for variable length
  * 					address masks.
  */
-  
+
 #include <linux/config.h>
 #if defined(CONFIG_ROSE) || defined(CONFIG_ROSE_MODULE)
 #include <linux/module.h>
@@ -67,6 +67,8 @@
 
 static struct proto_ops rose_proto_ops;
 
+ax25_address rose_callsign;
+
 /*
  *	Convert a Rose address into text.
  */
@@ -99,7 +101,7 @@
 	for (i = 0; i < 5; i++)
 		if (addr1->rose_addr[i] != addr2->rose_addr[i])
 			return 1;
-			
+
 	return 0;
 }
 
@@ -113,15 +115,15 @@
 	if (mask > 10)
 		return 1;
 
-	for (i = 0, j = 0; i < mask; i++) {
+	for (i = 0; i < mask; i++) {
 		j = i / 2;
 
-		if ((i % 2) != 0) {	/* odd place */
-			if ((addr1->rose_addr[j] & 0xF0) != (addr2->rose_addr[j] & 0xF0))
-				return 1;
-		} else {		/* even place */
+		if ((i % 2) != 0) {
 			if ((addr1->rose_addr[j] & 0x0F) != (addr2->rose_addr[j] & 0x0F))
 				return 1;
+		} else {
+			if ((addr1->rose_addr[j] & 0xF0) != (addr2->rose_addr[j] & 0xF0))
+				return 1;
 		}
 	}
 
@@ -151,7 +153,7 @@
 	}
 
 	MOD_INC_USE_COUNT;
-	
+
 	memset(rose, 0x00, sizeof(*rose));
 
 	sk->protinfo.rose = rose;
@@ -167,7 +169,7 @@
 {
 	struct sock *s;
 	unsigned long flags;
-	
+
 	save_flags(flags);
 	cli();
 
@@ -223,7 +225,7 @@
 	rose_kill_by_device(dev);
 	rose_rt_device_down(dev);
 	rose_link_device_down(dev);
-	
+
 	return NOTIFY_DONE;
 }
 
@@ -237,8 +239,8 @@
 	save_flags(flags);
 	cli();
 
-	sk->next = rose_list;
-	rose_list  = sk;
+	sk->next  = rose_list;
+	rose_list = sk;
 
 	restore_flags(flags);
 }
@@ -335,15 +337,15 @@
 {
 	struct sk_buff *skb;
 	unsigned long flags;
-	
+
 	save_flags(flags);
 	cli();
-	
+
 	del_timer(&sk->timer);
-	
+
 	rose_remove_socket(sk);
 	rose_clear_queues(sk);		/* Flush the queues */
-	
+
 	while ((skb = skb_dequeue(&sk->receive_queue)) != NULL) {
 		if (skb->sk != sk) {			/* A pending connection */
 			skb->sk->dead = 1;	/* Queue the unaccepted socket for death */
@@ -353,8 +355,8 @@
 
 		kfree_skb(skb, FREE_READ);
 	}
-	
-	if (sk->wmem_alloc || sk->rmem_alloc) { /* Defer: outstanding buffers */
+
+	if (sk->wmem_alloc || sk->rmem_alloc) {	/* Defer: outstanding buffers */
 		init_timer(&sk->timer);
 		sk->timer.expires  = jiffies + 10 * HZ;
 		sk->timer.function = rose_destroy_timer;
@@ -371,11 +373,6 @@
  *	Handling for system calls applied via the various interfaces to a
  *	Rose socket object.
  */
- 
-static int rose_fcntl(struct socket *sock, unsigned int cmd, unsigned long arg)
-{
-	return -EINVAL;
-}
 
 /*
  * dl1bke 960311: set parameters for existing Rose connections,
@@ -420,7 +417,7 @@
   				return -EINVAL;
   			if (sk->protinfo.rose->neighbour != NULL) {
 	  			save_flags(flags); cli();
-	  			sk->protinfo.rose->neighbour->t0 = rose_ctl.arg * PR_SLOWHZ;
+	  			sk->protinfo.rose->neighbour->t0 = rose_ctl.arg * ROSE_SLOWHZ;
 	  			restore_flags(flags);
 	  		}
   			break;
@@ -429,7 +426,7 @@
   			if (rose_ctl.arg < 1) 
   				return -EINVAL;
   			save_flags(flags); cli();
-  			sk->protinfo.rose->t1 = rose_ctl.arg * PR_SLOWHZ;
+  			sk->protinfo.rose->t1 = rose_ctl.arg * ROSE_SLOWHZ;
   			restore_flags(flags);
   			break;
 
@@ -437,7 +434,7 @@
 	  		if (rose_ctl.arg < 1) 
 	  			return -EINVAL;
 	  		save_flags(flags); cli();
-	  		sk->protinfo.rose->t2 = rose_ctl.arg * PR_SLOWHZ;
+	  		sk->protinfo.rose->t2 = rose_ctl.arg * ROSE_SLOWHZ;
 	  		restore_flags(flags);
 	  		break;
 
@@ -445,7 +442,7 @@
 	  		if (rose_ctl.arg < 1) 
 	  			return -EINVAL;
 	  		save_flags(flags); cli();
-	  		sk->protinfo.rose->t3 = rose_ctl.arg * PR_SLOWHZ;
+	  		sk->protinfo.rose->t3 = rose_ctl.arg * ROSE_SLOWHZ;
 	  		restore_flags(flags);
 	  		break;
 
@@ -453,7 +450,7 @@
 	  		if (rose_ctl.arg < 1) 
 	  			return -EINVAL;
 	  		save_flags(flags); cli();
-	  		sk->protinfo.rose->hb = rose_ctl.arg * PR_SLOWHZ;
+	  		sk->protinfo.rose->hb = rose_ctl.arg * ROSE_SLOWHZ;
 	  		restore_flags(flags);
 	  		break;
 
@@ -461,7 +458,7 @@
 	  		if (rose_ctl.arg < 1) 
 	  			return -EINVAL;
 	  		save_flags(flags); cli();
-	  		sk->protinfo.rose->idle = rose_ctl.arg * 60 * PR_SLOWHZ;
+	  		sk->protinfo.rose->idle = rose_ctl.arg * 60 * ROSE_SLOWHZ;
 	  		restore_flags(flags);
 	  		break;
 
@@ -475,11 +472,9 @@
 static int rose_setsockopt(struct socket *sock, int level, int optname,
 	char *optval, int optlen)
 {
-	struct sock *sk;
+	struct sock *sk = sock->sk;
 	int err, opt;
 
-	sk = (struct sock *)sock->sk;
-	
 	if (level != SOL_ROSE)
 		return -EOPNOTSUPP;
 
@@ -490,45 +485,45 @@
 		return err;
 
 	get_user(opt, (int *)optval);
-	
+
 	switch (optname) {
 		case ROSE_T0:
 			if (opt < 1)
 				return -EINVAL;
 			if (sk->protinfo.rose->neighbour != NULL)
-				sk->protinfo.rose->neighbour->t0 = opt * PR_SLOWHZ;
+				sk->protinfo.rose->neighbour->t0 = opt * ROSE_SLOWHZ;
 			return 0;
 
 		case ROSE_T1:
 			if (opt < 1)
 				return -EINVAL;
-			sk->protinfo.rose->t1 = opt * PR_SLOWHZ;
+			sk->protinfo.rose->t1 = opt * ROSE_SLOWHZ;
 			return 0;
 
 		case ROSE_T2:
 			if (opt < 1)
 				return -EINVAL;
-			sk->protinfo.rose->t2 = opt * PR_SLOWHZ;
+			sk->protinfo.rose->t2 = opt * ROSE_SLOWHZ;
 			return 0;
-			
+
 		case ROSE_T3:
 			if (opt < 1)
 				return -EINVAL;
-			sk->protinfo.rose->t3 = opt * PR_SLOWHZ;
+			sk->protinfo.rose->t3 = opt * ROSE_SLOWHZ;
 			return 0;
-			
+
 		case ROSE_HOLDBACK:
 			if (opt < 1)
 				return -EINVAL;
-			sk->protinfo.rose->hb = opt * PR_SLOWHZ;
+			sk->protinfo.rose->hb = opt * ROSE_SLOWHZ;
 			return 0;
-			
+
 		case ROSE_IDLE:
 			if (opt < 1)
 				return -EINVAL;
-			sk->protinfo.rose->idle = opt * 60 * PR_SLOWHZ;
+			sk->protinfo.rose->idle = opt * 60 * ROSE_SLOWHZ;
 			return 0;
-			
+
 		case ROSE_HDRINCL:
 			sk->protinfo.rose->hdrincl = opt ? 1 : 0;
 			return 0;
@@ -541,43 +536,41 @@
 static int rose_getsockopt(struct socket *sock, int level, int optname,
 	char *optval, int *optlen)
 {
-	struct sock *sk;
+	struct sock *sk = sock->sk;
 	int val = 0;
 	int err; 
 
-	sk = (struct sock *)sock->sk;
-	
 	if (level != SOL_ROSE)
 		return -EOPNOTSUPP;
 	
 	switch (optname) {
 		case ROSE_T0:
 			if (sk->protinfo.rose->neighbour != NULL)
-				val = sk->protinfo.rose->neighbour->t0 / PR_SLOWHZ;
+				val = sk->protinfo.rose->neighbour->t0 / ROSE_SLOWHZ;
 			else
-				val = sysctl_rose_restart_request_timeout / PR_SLOWHZ;
+				val = sysctl_rose_restart_request_timeout / ROSE_SLOWHZ;
 			break;
-			
+
 		case ROSE_T1:
-			val = sk->protinfo.rose->t1 / PR_SLOWHZ;
+			val = sk->protinfo.rose->t1 / ROSE_SLOWHZ;
 			break;
-			
+
 		case ROSE_T2:
-			val = sk->protinfo.rose->t2 / PR_SLOWHZ;
+			val = sk->protinfo.rose->t2 / ROSE_SLOWHZ;
 			break;
-			
+
 		case ROSE_T3:
-			val = sk->protinfo.rose->t3 / PR_SLOWHZ;
+			val = sk->protinfo.rose->t3 / ROSE_SLOWHZ;
 			break;
-						
+
 		case ROSE_HOLDBACK:
-			val = sk->protinfo.rose->hb / PR_SLOWHZ;
+			val = sk->protinfo.rose->hb / ROSE_SLOWHZ;
 			break;
-						
+
 		case ROSE_IDLE:
-			val = sk->protinfo.rose->idle / (PR_SLOWHZ * 60);
+			val = sk->protinfo.rose->idle / (ROSE_SLOWHZ * 60);
 			break;
-						
+
 		case ROSE_HDRINCL:
 			val = sk->protinfo.rose->hdrincl;
 			break;
@@ -601,7 +594,7 @@
 
 static int rose_listen(struct socket *sock, int backlog)
 {
-	struct sock *sk = (struct sock *)sock->sk;
+	struct sock *sk = sock->sk;
 
 	if (sk->state != TCP_LISTEN) {
 		sk->protinfo.rose->dest_ndigis = 0;
@@ -624,18 +617,17 @@
 
 static void def_callback2(struct sock *sk, int len)
 {
-	if (!sk->dead)
-	{
+	if (!sk->dead) {
 		wake_up_interruptible(sk->sleep);
-		sock_wake_async(sk->socket,1);
+		sock_wake_async(sk->socket, 1);
 	}
 }
-static void def_callback3(struct sock *sk, int len)
+
+static void def_callback3(struct sock *sk)
 {
-	if (!sk->dead)
-	{
+	if (!sk->dead) {
 		wake_up_interruptible(sk->sleep);
-		sock_wake_async(sk->socket,2); 
+		sock_wake_async(sk->socket, 2); 
 	}		
 }
 
@@ -652,35 +644,12 @@
 
 	rose = sk->protinfo.rose;
 
-	skb_queue_head_init(&sk->receive_queue);
-	skb_queue_head_init(&sk->write_queue);
-	skb_queue_head_init(&sk->back_log);
-
-	init_timer(&sk->timer);
-
+	sock_init_data(sock,sk);
+	
 	sock->ops	  = &rose_proto_ops;
-	sk->socket        = sock;
-	sk->type          = sock->type;
 	sk->protocol      = protocol;
-	sk->allocation	  = GFP_KERNEL;
-	sk->rcvbuf        = SK_RMEM_MAX;
-	sk->sndbuf        = SK_WMEM_MAX;
-	sk->state         = TCP_CLOSE;
-	sk->priority      = SOPRI_NORMAL;
 	sk->mtu           = ROSE_MTU;	/* 128 */
-	sk->zapped        = 1;
 
-	sk->state_change = def_callback1;
-	sk->data_ready   = def_callback2;
-	sk->write_space  = def_callback1;
-	sk->error_report = def_callback1;
-
-	if (sock != NULL) {
-		sock->sk  = sk;
-		sk->sleep = &sock->wait;
-	}
-
-	skb_queue_head_init(&rose->ack_queue);
 	skb_queue_head_init(&rose->frag_queue);
 
 	rose->t1    = sysctl_rose_call_request_timeout;
@@ -727,10 +696,9 @@
 
 	sk->state_change = def_callback1;
 	sk->data_ready   = def_callback2;
-	sk->write_space  = def_callback1;
+	sk->write_space  = def_callback3;
 	sk->error_report = def_callback1;
 
-	skb_queue_head_init(&rose->ack_queue);
 	skb_queue_head_init(&rose->frag_queue);
 
 	rose->t1      = osk->protinfo.rose->t1;
@@ -747,14 +715,17 @@
 
 static int rose_dup(struct socket *newsock, struct socket *oldsock)
 {
-	struct sock *sk = (struct sock *)oldsock->sk;
+	struct sock *sk = oldsock->sk;
+
+	if (sk == NULL || newsock == NULL)
+		return -EINVAL;
 
 	return rose_create(newsock, sk->protocol);
 }
 
 static int rose_release(struct socket *sock, struct socket *peer)
 {
-	struct sock *sk = (struct sock *)sock->sk;
+	struct sock *sk = sock->sk;
 
 	if (sk == NULL) return 0;
 
@@ -811,19 +782,20 @@
 
 static int rose_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
 {
-	struct sock *sk;
+	struct sock *sk = sock->sk;
 	struct sockaddr_rose *addr = (struct sockaddr_rose *)uaddr;
 	struct device *dev;
 	ax25_address *user, *source;
-	
-	sk = (struct sock *)sock->sk;
 
 	if (sk->zapped == 0)
 		return -EINVAL;
-		
+
 	if (addr_len != sizeof(struct sockaddr_rose))
 		return -EINVAL;
 
+	if (addr->srose_family != AF_ROSE)
+		return -EINVAL;
+
 	if ((dev = rose_dev_get(&addr->srose_addr)) == NULL) {
 		if (sk->debug)
 			printk("Rose: bind failed: invalid address\n");
@@ -859,30 +831,33 @@
 
 static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags)
 {
-	struct sock *sk = (struct sock *)sock->sk;
+	struct sock *sk = sock->sk;
 	struct sockaddr_rose *addr = (struct sockaddr_rose *)uaddr;
 	ax25_address *user;
 	struct device *dev;
-	
+
 	if (sk->state == TCP_ESTABLISHED && sock->state == SS_CONNECTING) {
 		sock->state = SS_CONNECTED;
 		return 0;	/* Connect completed during a ERESTARTSYS event */
 	}
-	
+
 	if (sk->state == TCP_CLOSE && sock->state == SS_CONNECTING) {
 		sock->state = SS_UNCONNECTED;
 		return -ECONNREFUSED;
 	}
-	
+
 	if (sk->state == TCP_ESTABLISHED)
 		return -EISCONN;	/* No reconnect on a seqpacket socket */
-		
+
 	sk->state   = TCP_CLOSE;	
 	sock->state = SS_UNCONNECTED;
 
 	if (addr_len != sizeof(struct sockaddr_rose))
 		return -EINVAL;
 
+	if (addr->srose_family != AF_ROSE)
+		return -EINVAL;
+
 	if ((sk->protinfo.rose->neighbour = rose_get_neigh(&addr->srose_addr)) == NULL)	
 		return -ENETUNREACH;
 
@@ -919,7 +894,7 @@
 	rose_write_internal(sk, ROSE_CALL_REQUEST);
 
 	rose_set_timer(sk);
-	
+
 	/* Now the loop */
 	if (sk->state != TCP_ESTABLISHED && (flags & O_NONBLOCK))
 		return -EINPROGRESS;
@@ -942,11 +917,11 @@
 		sock->state = SS_UNCONNECTED;
 		return sock_error(sk);	/* Always set at this point */
 	}
-	
+
 	sock->state = SS_CONNECTED;
 
 	sti();
-	
+
 	return 0;
 }
 	
@@ -961,19 +936,20 @@
 	struct sock *newsk;
 	struct sk_buff *skb;
 
-	if (newsock->sk)
-		sk_free(newsock->sk);
+	if (newsock->sk != NULL)
+		rose_destroy_socket(newsock->sk);
 
 	newsock->sk = NULL;
-	
-	sk = (struct sock *)sock->sk;
+
+	if ((sk = sock->sk) == NULL)
+		return -EINVAL;
 
 	if (sk->type != SOCK_SEQPACKET)
 		return -EOPNOTSUPP;
-	
+
 	if (sk->state != TCP_LISTEN)
 		return -EINVAL;
-		
+
 	/*
 	 *	The write queue this time is holding sockets ready to use
 	 *	hooked into the SABM we saved
@@ -983,7 +959,7 @@
 		if ((skb = skb_dequeue(&sk->receive_queue)) == NULL) {
 			if (flags & O_NONBLOCK) {
 				sti();
-				return 0;
+				return -EWOULDBLOCK;
 			}
 			interruptible_sleep_on(sk->sleep);
 			if (current->signal & ~current->blocked) {
@@ -1010,10 +986,8 @@
 	int *uaddr_len, int peer)
 {
 	struct sockaddr_rose *srose = (struct sockaddr_rose *)uaddr;
-	struct sock *sk;
-	
-	sk = (struct sock *)sock->sk;
-	
+	struct sock *sk = sock->sk;
+
 	if (peer != 0) {
 		if (sk->state != TCP_ESTABLISHED)
 			return -ENOTCONN;
@@ -1040,11 +1014,11 @@
 
 	return 0;
 }
- 
+
 int rose_rx_call_request(struct sk_buff *skb, struct device *dev, struct rose_neigh *neigh, unsigned int lci)
 {
 	struct sock *sk;
-	struct sock *make;	
+	struct sock *make;
 	rose_cb rose;
 
 	skb->sk = NULL;		/* Initially we don't know who it's for */
@@ -1059,7 +1033,7 @@
 	if (!rose_parse_facilities(skb, &rose)) {
 		return 0;
 	}
-		
+
 	sk = rose_find_listener(&rose.source_call);
 
 	/*
@@ -1084,7 +1058,7 @@
 	make->protinfo.rose->source_digi   = rose.source_digi;
 	make->protinfo.rose->neighbour     = neigh;
 	make->protinfo.rose->device        = dev;
-	
+
 	rose_write_internal(make, ROSE_CALL_ACCEPTED);
 
 	make->protinfo.rose->condition = 0x00;
@@ -1111,14 +1085,14 @@
 static int rose_sendmsg(struct socket *sock, struct msghdr *msg, int len, 
 				struct scm_cookie *scm)
 {
-	struct sock *sk = (struct sock *)sock->sk;
+	struct sock *sk = sock->sk;
 	struct sockaddr_rose *usrose = (struct sockaddr_rose *)msg->msg_name;
 	int err;
 	struct sockaddr_rose srose;
 	struct sk_buff *skb;
 	unsigned char *asmptr;
 	int size;
-	
+
 	if (msg->msg_flags & ~MSG_DONTWAIT)
 		return -EINVAL;
 
@@ -1132,7 +1106,7 @@
 
 	if (sk->protinfo.rose->device == NULL)
 		return -ENETUNREACH;
-		
+
 	if (usrose != NULL) {
 		if (msg->msg_namelen < sizeof(srose))
 			return -EINVAL;
@@ -1160,7 +1134,7 @@
 			srose.srose_digi   = sk->protinfo.rose->dest_digi;
 		}
 	}
-	
+
 	if (sk->debug)
 		printk("Rose: sendto: Addresses built.\n");
 
@@ -1173,11 +1147,10 @@
 	if ((skb = sock_alloc_send_skb(sk, size, 0, msg->msg_flags & MSG_DONTWAIT, &err)) == NULL)
 		return err;
 
-	skb->sk   = sk;
-	skb->arp  = 1;
+	skb->arp = 1;
 
 	skb_reserve(skb, size - len);
-	
+
 	/*
 	 *	Push down the Rose header
 	 */
@@ -1189,10 +1162,10 @@
 
 	/* Build a Rose Transport header */
 
-	*asmptr++ = ((sk->protinfo.rose->lci >> 8) & 0x0F) | GFI;
+	*asmptr++ = ((sk->protinfo.rose->lci >> 8) & 0x0F) | ROSE_GFI;
 	*asmptr++ = (sk->protinfo.rose->lci >> 0) & 0xFF;
 	*asmptr++ = ROSE_DATA;
-	
+
 	if (sk->debug)
 		printk("Built header.\n");
 
@@ -1203,7 +1176,7 @@
 	skb->h.raw = skb_put(skb, len);
 
 	asmptr = skb->h.raw;
-	
+
 	if (sk->debug)
 		printk("Rose: Appending user data\n");
 
@@ -1227,7 +1200,7 @@
 static int rose_recvmsg(struct socket *sock, struct msghdr *msg, int size, 
 		   int flags, struct scm_cookie *scm)
 {
-	struct sock *sk = (struct sock *)sock->sk;
+	struct sock *sk = sock->sk;
 	struct sockaddr_rose *srose = (struct sockaddr_rose *)msg->msg_name;
 	int copied;
 	struct sk_buff *skb;
@@ -1250,28 +1223,24 @@
 	}
 
 	copied = skb->len;
-	
+
 	if (copied > size) {
 		copied = size;
 		msg->msg_flags |= MSG_TRUNC;
 	}
-	
+
 	skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
-	
+
 	if (srose != NULL) {
-		struct sockaddr_rose addr;
-		
-		addr.srose_family = AF_ROSE;
-		addr.srose_addr   = sk->protinfo.rose->dest_addr;
-		addr.srose_call   = sk->protinfo.rose->dest_call;
-		addr.srose_ndigis = 0;
+		srose->srose_family = AF_ROSE;
+		srose->srose_addr   = sk->protinfo.rose->dest_addr;
+		srose->srose_call   = sk->protinfo.rose->dest_call;
+		srose->srose_ndigis = 0;
 
 		if (sk->protinfo.rose->dest_ndigis == 1) {
-			addr.srose_ndigis = 1;
-			addr.srose_digi   = sk->protinfo.rose->dest_digi;
+			srose->srose_ndigis = 1;
+			srose->srose_digi   = sk->protinfo.rose->dest_digi;
 		}
-
-		*srose = addr;
 	}
 
 	msg->msg_namelen = sizeof(struct sockaddr_rose);
@@ -1288,7 +1257,7 @@
 
 static int rose_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 {
-	struct sock *sk = (struct sock *)sock->sk;
+	struct sock *sk = sock->sk;
 	int err;
 	long amount = 0;
 
@@ -1341,11 +1310,22 @@
 			if (!suser()) return -EPERM;
 			return rose_rt_ioctl(cmd, (void *)arg);
 
- 		case SIOCRSCTLCON:
+		case SIOCRSCTLCON:
  			if (!suser()) return -EPERM;
  			return rose_ctl_ioctl(cmd, (void *)arg);
- 
- 		default:
+
+		case SIOCRSL2CALL:
+			if (!suser()) return -EPERM;
+			if ((err = verify_area(VERIFY_READ, (void *)arg, sizeof(ax25_address))) != 0)
+				return err;
+			if (ax25cmp(&rose_callsign, &null_ax25_address) != 0)
+				ax25_listen_release(&rose_callsign, NULL);
+			copy_from_user(&rose_callsign, (void *)arg, sizeof(ax25_address));
+			if (ax25cmp(&rose_callsign, &null_ax25_address) != 0)
+				ax25_listen_register(&rose_callsign, NULL);
+			return 0;
+
+		default:
 			return dev_ioctl(cmd, (void *)arg);
 	}
 
@@ -1361,10 +1341,10 @@
 	int len = 0;
 	off_t pos = 0;
 	off_t begin = 0;
-  
+
 	cli();
 
-	len += sprintf(buffer, "dest_addr  dest_call dest_digi src_addr   src_call  src_digi  dev   lci st vs vr va   t  t1  t2  t3  hb  Snd-Q Rcv-Q\n");
+	len += sprintf(buffer, "dest_addr  dest_call src_addr   src_call  dev   lci st vs vr va   t  t1  t2  t3  hb  Snd-Q Rcv-Q\n");
 
 	for (s = rose_list; s != NULL; s = s->next) {
 		if ((dev = s->protinfo.rose->device) == NULL)
@@ -1375,36 +1355,31 @@
 		len += sprintf(buffer + len, "%-10s %-9s ",
 			rose2asc(&s->protinfo.rose->dest_addr),
 			ax2asc(&s->protinfo.rose->dest_call));
-		len += sprintf(buffer + len, "%-9s ",
-			ax2asc(&s->protinfo.rose->dest_digi));
 
 		if (ax25cmp(&s->protinfo.rose->source_call, &null_ax25_address) == 0)
 			callsign = "??????-?";
 		else
 			callsign = ax2asc(&s->protinfo.rose->source_call);
 
-		len += sprintf(buffer + len, "%-10s %-9s ",
-			rose2asc(&s->protinfo.rose->source_addr),
-			callsign);
-		len += sprintf(buffer + len, "%-9s %-5s %3.3X  %d  %d  %d  %d %3d %3d %3d %3d %3d %5d %5d\n",
-			ax2asc(&s->protinfo.rose->source_digi),
+		len += sprintf(buffer + len, "%-10s %-9s %-5s %3.3X  %d  %d  %d  %d %3d %3d %3d %3d %3d %5d %5d\n",
+			rose2asc(&s->protinfo.rose->source_addr), callsign,
 			devname,  s->protinfo.rose->lci & 0x0FFF,
 			s->protinfo.rose->state,
 			s->protinfo.rose->vs, s->protinfo.rose->vr, s->protinfo.rose->va,
-			s->protinfo.rose->timer / PR_SLOWHZ,
-			s->protinfo.rose->t1    / PR_SLOWHZ,
-			s->protinfo.rose->t2    / PR_SLOWHZ,
-			s->protinfo.rose->t3    / PR_SLOWHZ,
-			s->protinfo.rose->hb    / PR_SLOWHZ,
+			s->protinfo.rose->timer / ROSE_SLOWHZ,
+			s->protinfo.rose->t1    / ROSE_SLOWHZ,
+			s->protinfo.rose->t2    / ROSE_SLOWHZ,
+			s->protinfo.rose->t3    / ROSE_SLOWHZ,
+			s->protinfo.rose->hb    / ROSE_SLOWHZ,
 			s->wmem_alloc, s->rmem_alloc);
-		
+
 		pos = begin + len;
 
 		if (pos < offset) {
 			len   = 0;
 			begin = pos;
 		}
-		
+
 		if (pos > offset + length)
 			break;
 	}
@@ -1426,7 +1401,7 @@
 
 static struct proto_ops rose_proto_ops = {
 	AF_ROSE,
-	
+
 	rose_dup,
 	rose_release,
 	rose_bind,
@@ -1440,7 +1415,7 @@
 	rose_shutdown,
 	rose_setsockopt,
 	rose_getsockopt,
-	rose_fcntl,
+	sock_no_fcntl,
 	rose_sendmsg,
 	rose_recvmsg
 };
@@ -1490,6 +1465,8 @@
 {
 	int i;
 
+	rose_callsign = null_ax25_address;
+
 	sock_register(&rose_family_ops);
 	register_netdevice_notifier(&rose_dev_notifier);
 	printk(KERN_INFO "G4KLX Rose for Linux. Version 0.1 for AX25.035 Linux 2.1\n");
@@ -1536,6 +1513,9 @@
 
 	ax25_protocol_release(AX25_P_ROSE);
 	ax25_linkfail_release(rose_link_failed);
+
+	if (ax25cmp(&rose_callsign, &null_ax25_address) != 0)
+		ax25_listen_release(&rose_callsign, NULL);
 
 	rose_unregister_sysctl();
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov