Added ubi_sLinkList module which manages simple singly-linked lists.
[samba.git] / source3 / namedbresp.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    NBT netbios library routines
5    Copyright (C) Andrew Tridgell 1994-1997
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20    
21    Module name: namedbresp.c
22
23 */
24
25 #include "includes.h"
26
27 extern int ClientNMB;
28 extern int ClientDGRAM;
29
30 extern struct subnet_record *subnetlist;
31
32 extern int DEBUGLEVEL;
33
34 extern pstring scope;
35 extern pstring myname;
36 extern struct in_addr ipzero;
37
38 int num_response_packets = 0;
39
40 /***************************************************************************
41   add an expected response record into the list
42   **************************************************************************/
43 void add_response_record(struct subnet_record *d,
44                                 struct response_record *n)
45 {
46   struct response_record *n2;
47
48   if (!d) return;
49
50   num_response_packets++; /* count of total number of packets still around */
51
52   DEBUG(4,("adding response record id:%d num_records:%d\n",
53                    n->response_id, num_response_packets));
54
55   if (!d->responselist)
56     {
57       d->responselist = n;
58       n->prev = NULL;
59       n->next = NULL;
60       return;
61     }
62   
63   for (n2 = d->responselist; n2->next; n2 = n2->next) ;
64   
65   n2->next = n;
66   n->next = NULL;
67   n->prev = n2;
68 }
69
70
71 /***************************************************************************
72   remove an expected response record from the list
73   **************************************************************************/
74 void remove_response_record(struct subnet_record *d,
75                                 struct response_record *n)
76 {
77         if (!d) return;
78
79         if (n->prev) n->prev->next = n->next;
80         if (n->next) n->next->prev = n->prev;
81
82         if (d->responselist == n) d->responselist = n->next; 
83
84         free(n);
85
86         num_response_packets--; /* count of total number of packets still around */
87 }
88
89
90 /****************************************************************************
91   create a name query response record
92   **************************************************************************/
93 struct response_record *make_response_queue_record(enum state_type state,
94                                 int id,uint16 fd,
95                                 int quest_type, char *name,int type, int nb_flags, time_t ttl,
96                                 int server_type, char *my_name, char *my_comment,
97                                 BOOL bcast,BOOL recurse,
98                                 struct in_addr send_ip, struct in_addr reply_to_ip,
99                                 int reply_id)
100 {
101   struct response_record *n;
102         
103   if (!name || !name[0]) return NULL;
104         
105   if (!(n = (struct response_record *)malloc(sizeof(*n)))) 
106     return(NULL);
107
108   bzero((char *)n, sizeof(*n));
109
110   n->response_id = id;
111   n->state = state;
112   n->fd = fd;
113   n->quest_type = quest_type;
114   make_nmb_name(&n->name, name, type, scope);
115   n->nb_flags = nb_flags;
116   n->ttl = ttl;
117   n->server_type = server_type;
118   n->bcast = bcast;
119   n->recurse = recurse;
120   n->send_ip = send_ip;
121   n->reply_to_ip = reply_to_ip;
122   n->reply_id = reply_id;
123   if(my_name)
124     StrnCpy(n->my_name, my_name, sizeof(n->my_name)-1);
125   else
126     *n->my_name = 0;
127   if(my_comment)
128     StrnCpy(n->my_comment, my_comment, sizeof(n->my_comment)-1);
129   else
130     *n->my_comment = 0;
131   n->repeat_interval = 1; /* XXXX should be in ms */
132   n->repeat_count = 3; /* 3 retries */
133   n->repeat_time = time(NULL) + n->repeat_interval; /* initial retry time */
134
135   n->num_msgs = 0;
136
137   return n;
138 }
139
140
141 /****************************************************************************
142   find a response in a subnet's name query response list. 
143   **************************************************************************/
144 struct response_record *find_response_record(struct subnet_record **d,
145                                 uint16 id)
146 {  
147   struct response_record *n;
148
149   if (!d) return NULL;
150
151   for ((*d) = FIRST_SUBNET; (*d); (*d) = NEXT_SUBNET_INCLUDING_WINS(*d))
152   {
153     for (n = (*d)->responselist; n; n = n->next)
154     {
155       if (n->response_id == id) {
156          DEBUG(4, ("found response record on %s: %d\n",
157                                         inet_ntoa((*d)->bcast_ip), id));
158          return n;
159       }
160     }
161   }
162
163   *d = NULL;
164
165   return NULL;
166 }
167
168