patch-2.1.15 linux/net/netbeui/netbeui_name.c

Next file: linux/net/netlink.c
Previous file: linux/net/netbeui/netbeui_llc.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.14/linux/net/netbeui/netbeui_name.c linux/net/netbeui/netbeui_name.c
@@ -0,0 +1,159 @@
+/*
+ *	NetBIOS name handler
+ */
+
+/*
+ *	You must hold the netbios name lock before using these.
+ */
+  
+struct nb_name *nb_name_find(struct device *dev,const char * name)
+{
+	struct nb_name *nb=nb_name_list;
+	while(nb!=NULL)
+	{
+		if((dev==NULL || dev==nb->dev) && 
+			strncmp(name,nb->name, NB_NAME_LEN)==0)
+			return nb;
+		nb=nb->next;
+	}
+	return NULL;
+}
+
+int nb_name_add(struct device *dev, const char *name, int ours, int pri)
+{
+	struct nb_name *nb=kmalloc(sizeof(*nb), pri);
+	if(nb==NULL)
+		return NULL;
+	nb->dev=dev;
+	strncpy(nb->name,name,NB_NAME_LEN);
+	nb->name[NB_NAME_LEN-1]=0;
+	nb->next=nb_name_list;
+	nb->ours=ours;
+	nb_name_list=nb;
+}
+
+void nb_name_delete(struct nb_name *nb)
+{
+	struct nb_name *i=&nb_name_list;
+	while((*i)!=NULL)
+	{
+		if(*i==nb)
+		{
+			*i=nb->next;
+			kfree_s(nb,sizeof(*nb));
+			return;
+		}
+		i=&((*i)->next);
+	}
+	printk(KERN_ERR "nb_name_delete: bad name pointer!\n");
+}
+
+/*
+ *	NETBIOS name handlers
+ */
+
+static void nb_defend(struct device *dev, const char *name)
+{
+	struct sk_buff *nskb=nb_alloc_skb(NB_CONTROL_LEN, GFP_ATOMIC);
+	if(nskb==NULL)
+		return;
+	/* Build a name defence packet */
+	dev_queue_xmit(nskb,dev,SOPRI_INTERACTIVE);
+}
+
+void netbeui_heard_name(struct device *dev, struct sk_buff *skb)
+{
+	struct nb_name *nb;
+	name=...
+	
+	if((nb=nb_name_find(dev,name))!=NULL)
+	{
+		/*
+		 *	If we own the name then defend it
+		 */
+		if(nb->our && !nb->state==NB_ACQUIRE)
+			nb_defend(dev,name);
+		/*
+		 *	A name has been resolved. Wake up pending
+		 *	connectors.
+		 */
+		if(nb->state==NB_QUERY)
+		{
+			nb->state=NB_OTHER;
+			nb_complete(nb,skb);
+		}
+	}
+	kfree_skb(skb, FREE_READ);
+	return 0;
+}
+
+/*
+ *	Handle incoming name defences
+ */
+ 
+void netbeui_name_defence(struct dev *dev, struct sk_buff *skb)
+{
+	struct nb_name *name;
+	name=
+	
+	if((nb=nb_name_find(dev,name))!=NULL)
+	{
+		if(nb->ours)
+		{
+			/*	
+			 *	We wanted it, we got told its used
+			 */
+			if(nb->state==NB_ACQUIRE)
+			{
+				/*
+				 *	Fill in the record for its true
+				 *	owner. Set the state first as
+				 *	nb_complete may well delete the
+				 *	record.
+				 */
+				nb->state=NB_OTHER;
+				nb_complete(nb,skb);
+				nb_wakeup();
+			}
+			/*
+			 *	We own it we got told its used. This is
+			 *	a deep cack even that can only occur when
+			 *	a bridge comes back and the net was split.
+			 *	Make sure both sides lose.
+			 */
+			if(nb->state==NB_OURS || nb->state==NB_COLLIDE)
+			{
+				nb->state=NR_COLLIDE;
+				nb_wakeup();
+				/*
+				 *	Kill the other copy too
+				 */
+				nb_defend(dev,name);	
+				/*
+				 *	Timer expiry will delete our
+				 *	record.
+				 */	
+				nb_start_timer(nb, NB_TIME_COLLIDED);
+			}		
+		}
+	}
+	kfree_skb(skb, FREE_READ);
+}
+
+void netbeui_name_query(struct dev *dev, struct sk_buff *skb)
+{
+	char *name=...
+	struct nb_name *nb=nb_find_name(dev,name);
+	
+	if(nb!=NULL && nb->ours)
+	{
+		struct sk_buff *nskb=nb_alloc_skb(NB_CONTROL_LEN, GFP_ATOMIC);
+		if(nskb!=NULL)
+		{
+			/* Build a name reply packet */
+			dev_queue_xmit(nskb,dev,SOPRI_INTERACTIVE);
+		}
+	}
+	kfree_skb(skb, FREE_READ);
+}
+

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