]> git.sesse.net Git - nbtscanner/blob - id_list.c
Import nbtscanner 0.1.2.
[nbtscanner] / id_list.c
1 /*
2  * nbtscanner -- a tool for scanning large networks for SMB servers.
3  *
4  * id_list.c: a singly linked list for keeping track of the packet IDs.
5  * Copyright (C) 2000 Steinar H. Gunderson
6  *
7  * Large amounts of code adapted from Samba (http://www.samba.org/)
8  * Copyright (C) Andrew Tridgell 1994-1998, and others.
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  */
24
25 #include "id_list.h"
26 #include "configfile.h"
27 #include "util.h"
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <unistd.h>
32 #include <sys/time.h>
33
34 struct id_entry ids[65536];
35 struct id_list_entry *head_free_id;
36 int num_free_ids;
37
38 void id_list_init()
39 {
40         int i, start_num;
41         
42         num_free_ids = 0;
43         head_free_id = NULL;
44
45         /* we want to start at some halfway random number instead of 0 */
46         start_num = (time(NULL) + getpid()) & 0xffff;
47
48         for (i = 65535; i >= 0; i--) {
49                 int ii = (i + start_num) & 0xffff;
50
51                 ids[ii].id = ii;
52                 ids[ii].in_use = 0;
53
54                 id_free(&ids[ii]);
55         }
56 }
57
58 void id_list_destroy()
59 {
60         while (head_free_id) {
61                 struct id_list_entry *next = head_free_id->next;
62                 free(head_free_id);
63                 head_free_id = next;
64         }
65         num_free_ids = 0;
66 }
67
68 void id_free(struct id_entry *i)
69 {
70         struct id_list_entry *ie = (struct id_list_entry *)malloc(sizeof(struct id_list_entry));
71
72         if (ie == NULL) {
73                 perror("malloc()");
74                 exit(1);
75         }
76
77         i->in_use = 0;
78         ie->id = i;
79
80         /* insert at the beginning of the linked list */
81         ie->next = head_free_id;
82         head_free_id = ie;
83
84         num_free_ids++;
85 }
86
87 /* mark as free, but don't delete until desperation cleanup */
88 void id_mark_free(struct id_entry *i)
89 {
90         i->in_use = 2;
91         num_free_ids++;
92 }
93
94 struct id_entry *id_get_free_id()
95 {
96         struct id_list_entry *ie = head_free_id;
97         struct id_entry *i;
98
99         if (ie == NULL) {
100                 return NULL;
101         } else {
102                 i = ie->id;
103                 head_free_id = ie->next;
104                 free(ie);
105
106                 i->in_use = 1;
107                 num_free_ids--;
108                 
109                 return i;
110         }
111 }
112
113 /* desperation time :-) */
114 int id_cleanup(int timeout_ms)
115 {
116         int i;
117         int num_freed = 0;
118         struct timeval now;
119         gettimeofday(&now, NULL);
120
121         for (i = 0; i < 65536; i++) {
122                 if (ids[i].in_use == 2) {
123                         id_free(&ids[i]);
124                         num_freed++;
125                         num_free_ids--;         /* was already counted */
126
127                         continue;
128                 }
129                 if (mydifftime(ids[i].timestamp, now) > timeout_ms &&
130                     ids[i].retries == num_retries) {
131                         id_free(&ids[i]);
132                         num_freed++;
133
134                         continue;
135                 }
136         }
137
138         return num_freed;
139 }
140
141 int get_num_free_ids()
142 {
143         return num_free_ids;
144 }