patch-2.1.20 linux/net/netbeui/netbeui.c
Next file: linux/net/netbeui/netbeui_llc.c
Previous file: linux/net/lapb/lapb_timer.c
Back to the patch index
Back to the overall index
- Lines: 320
- Date:
Thu Jan 2 15:13:29 1997
- Orig file:
v2.1.19/linux/net/netbeui/netbeui.c
- Orig date:
Mon Dec 30 15:39:17 1996
diff -u --recursive --new-file v2.1.19/linux/net/netbeui/netbeui.c linux/net/netbeui/netbeui.c
@@ -49,7 +49,7 @@
* *
\***********************************************************************************************************************/
-static netbeui_socket *volatile netbeui_socket_list=NULL;
+static netbeui_socket *netbeui_socket_list=NULL;
/*
* Note: Sockets may not be removed _during_ an interrupt or inet_bh
@@ -57,91 +57,42 @@
* use this facility.
*/
-static void netbeui_remove_socket(netbeui_socket *sk)
+extern inline void netbeui_remove_socket(netbeui_socket *sk)
{
- unsigned long flags;
- netbeui_socket *s;
-
- save_flags(flags);
- cli();
-
- s=netbeui_socket_list;
- if(s==sk)
- {
- netbeui_socket_list=s->next;
- restore_flags(flags);
- return;
- }
- while(s && s->next)
- {
- if(s->next==sk)
- {
- s->next=sk->next;
- restore_flags(flags);
- return;
- }
- s=s->next;
- }
- restore_flags(flags);
+ sklist_remove_socket(&netbeui_socket_list,sk);
}
-static void netbeui_insert_socket(netbeui_socket *sk)
+extenr inline void netbeui_insert_socket(netbeui_socket *sk)
{
- unsigned long flags;
- save_flags(flags);
- cli();
- sk->next=netbeui_socket_list;
+ sklist_insert_socket(&netbeui_socket_list,sk);
netbeui_socket_list=sk;
restore_flags(flags);
}
-/*
- * This is only called from user mode. Thus it protects itself against
- * interrupt users but doesn't worry about being called during work.
- * Once it is removed from the queue no interrupt or bottom half will
- * touch it and we are (fairly 8-) ) safe.
- */
-
-static void netbeui_destroy_socket(netbeui_socket *sk);
-
-/*
- * Handler for deferred kills.
- */
-
-static void netbeui_destroy_timer(unsigned long data)
-{
- netbeui_destroy_socket((netbeui_socket *)data);
-}
-
static void netbeui_destroy_socket(netbeui_socket *sk)
{
- struct sk_buff *skb;
- netbeui_remove_socket(sk);
-
- while((skb=skb_dequeue(&sk->receive_queue))!=NULL)
+ /*
+ * Release netbios logical channels first
+ */
+ if(sk->af_nb.nb_link)
{
- kfree_skb(skb,FREE_READ);
+ netbeui_delete_channel(sk->af_nb.nb_link);
+ sk->af_nb.nb_link=NULL;
}
-
- if(sk->wmem_alloc == 0 && sk->rmem_alloc == 0 && sk->dead)
+ if(sk->af_nb.src_name)
{
- sk_free(sk);
- MOD_DEC_USE_COUNT;
+ netbeui_release_name(sk->af_nb.src_name);
+ sk->af_nb.src_name=NULL;
}
- else
+ if(sk->af_nb.dst_name)
{
- /*
- * Someone is using our buffers still.. defer
- */
- init_timer(&sk->timer);
- sk->timer.expires=jiffies+10*HZ;
- sk->timer.function=netbeui_destroy_timer;
- sk->timer.data = (unsigned long)sk;
- add_timer(&sk->timer);
+ netbeui_release_name(sk->af_nb.dst_name);
+ sk->af_nb.dst_name=NULL;
}
+ netbeui_remove_listener(sk);
+ sklist_destroy_socket(&netbeui_socket,sk);
}
-
/*
* Called from proc fs
*/
@@ -161,14 +112,10 @@
for (s = netbeui_socket_list; s != NULL; s = s->next)
{
len += sprintf (buffer+len,"%02X ", s->type);
- len += sprintf (buffer+len,"%04X:%02X:%02X ",
- ntohs(s->protinfo.af_at.src_net),
- s->protinfo.af_at.src_node,
- s->protinfo.af_at.src_port);
- len += sprintf (buffer+len,"%04X:%02X:%02X ",
- ntohs(s->protinfo.af_at.dest_net),
- s->protinfo.af_at.dest_node,
- s->protinfo.af_at.dest_port);
+ len += sprintf (buffer+len,"%s ",
+ s->af_nb.src_name->text);
+ len += sprintf (buffer+len,"%s ",
+ s->af_nb.dst_name->text);
len += sprintf (buffer+len,"%08X:%08X ", s->wmem_alloc, s->rmem_alloc);
len += sprintf (buffer+len,"%02X %d\n", s->state, SOCK_INODE(s->socket)->i_uid);
@@ -258,9 +205,6 @@
}
break;
- case SOL_SOCKET:
- return sock_setsockopt(sk,level,optname,optval,optlen);
-
default:
return -EOPNOTSUPP;
}
@@ -291,9 +235,6 @@
}
break;
- case SOL_SOCKET:
- return sock_getsockopt(sk,level,optname,optval,optlen);
-
default:
return -EOPNOTSUPP;
}
@@ -320,7 +261,7 @@
sk->backlog=128;
sk->state=TCP_LISTEN;
sk->state_change(sk);
- netbeui_llc_listen(sk);
+ netbeui_add_listener(sk);
return 0;
}
@@ -339,7 +280,16 @@
if(!sk->dead)
{
wake_up_interruptible(sk->sleep);
- sock_wake_async(sk->socket,0);
+ sock_wake_async(sk->socket,1);
+ }
+}
+
+static void def_callback3(struct sock *sk, int len)
+{
+ if(!sk->dead)
+ {
+ wake_up_interruptible(sk->sleep);
+ sock_wake_async(sk->socket,2);
}
}
@@ -365,13 +315,6 @@
return(-ESOCKTNOSUPPORT);
}
- sk->llc802=llc_alloc(GFP_KERNEL);
- if(sk->llc802==NULL)
- {
- sk_free((void *)sk);
- return -ENOBUFS:
- }
-
MOD_INC_USE_COUNT;
sk->allocation=GFP_KERNEL;
@@ -395,7 +338,7 @@
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;
sk->zapped=1;
return(0);
@@ -435,21 +378,40 @@
{
netbeui_socket *sk;
struct sockaddr_netbeui *addr=(struct sockaddr_netbeui *)uaddr;
+ int err;
sk=(netbeui_socket *)sock->data;
if(sk->zapped==0)
return(-EINVAL);
- if(addr_len!=sizeof(struct sockaddr_at))
+ if(addr_len!=sizeof(struct sockaddr_netbeui))
return -EINVAL;
- if(addr->sat_family!=AF_NETBEUI)
+ if(addr->snb_family!=AF_NETBEUI)
return -EAFNOSUPPORT;
- if(netbeui_find_socket(addr)!=NULL)
- return -EADDRINUSE;
-
+ /*
+ * This will sleep. To meet POSIX it is non interruptible.
+ * Someone should give the 1003.1g authors an injection of
+ * imagination...
+ */
+
+ if(sk->af_nb.src_name!=NULL)
+ return -EINVAL;
+
+ /*
+ * Try and get the name. It may return various 'invalid' name
+ * problem reports or EADDRINUSE if we or another node holds
+ * the desired name.
+ */
+
+ sk->af_nb.src_name=netbeui_alloc_name(addr, &err);
+ if(sk->af_nb.src_name==NULL)
+ return err;
+ /*
+ * Add us to the active socket list
+ */
netbeui_insert_socket(sk);
sk->zapped=0;
return(0);
@@ -463,28 +425,44 @@
size_t addr_len, int flags)
{
netbeui_socket *sk=(netbeui_socket *)sock->data;
- struct sockaddr_netbeui *addr;
-
- sk->state = TCP_CLOSE;
- sock->state = SS_UNCONNECTED;
-
- if(addr_len!=sizeof(*addr))
- return(-EINVAL);
- addr=(struct sockaddr_netbeui *)uaddr;
-
- if(addr->sat_family!=AF_NETBEUI)
- return -EAFNOSUPPORT;
-
-/* FIXME - Netbios broadcast semantics ?? */
- if(addr->sat_addr.s_node==ATADDR_BCAST && !sk->broadcast)
- return -EACCES;
-
- if(sk->zapped)
- return -EINVAL;
-
- if(atrtr_get_dev(&addr->sat_addr)==NULL)
- return -ENETUNREACH;
+ struct sockaddr_netbeui *addr=(struct sockaddr_netbeui *)uaddr;
+ /*
+ * Check pending operations
+ */
+
+ if(sk->state==TCP_ESTABLISHED && sock->state == SS_CONNECTING)
+ {
+ sock->state==SS_CONNECTED;
+ return 0;
+ }
+
+ if(sk->state == TCP_CLOSE & sock->state == SS_CONNECTING)
+ {
+ sock->state==SS_UNCONNECTED;
+ return -ECONNREFUSED;
+ }
+
+ if(sock->state == SS_CONNECTING && (flags & O_NONBLOCK))
+ return -EINPROGRESS;
+
+ if(sk->state==TCP_ESTABLISHED)
+ return -EISCONN;
+
+ /*
+ * If this is new it must really be new...
+ */
+
+ if(sk->af_nb.dst_name==NULL)
+ {
+ if(addr_len != sizeof(struct sockaddr_nb))
+ return -EINVAL;
+ if(addr->snb_family!=AF_NETBEUI)
+ return -EAFNOSUPPORT;
+ /*
+ * Try and find the name
+ */
+ }
}
/*
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov