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
- Lines: 832
- Date:
Sun Jan 19 15:47:29 1997
- Orig file:
v2.1.21/linux/net/rose/af_rose.c
- Orig date:
Thu Jan 2 15:55:28 1997
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