]> git.sesse.net Git - nbtscanner/blob - id_list.c
Import nbtscanner 0.1.0.
[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_free(struct id_entry *i)
59 {
60         struct id_list_entry *ie = (struct id_list_entry *)malloc(sizeof(struct id_list_entry));
61
62         if (ie == NULL) {
63                 perror("malloc()");
64                 exit(1);
65         }
66
67         i->in_use = 0;
68         ie->id = i;
69
70         /* insert at the beginning of the linked list */
71         ie->next = head_free_id;
72         head_free_id = ie;
73
74         num_free_ids++;
75 }
76
77 /* mark as free, but don't delete until desperation cleanup */
78 void id_mark_free(struct id_entry *i)
79 {
80         i->in_use = 2;
81         num_free_ids++;
82 }
83
84 struct id_entry *id_get_free_id()
85 {
86         struct id_list_entry *ie = head_free_id;
87         struct id_entry *i;
88
89         if (ie == NULL) {
90                 return NULL;
91         } else {
92                 i = ie->id;
93                 head_free_id = ie->next;
94                 free(ie);
95
96                 i->in_use = 1;
97                 num_free_ids--;
98                 
99                 return i;
100         }
101 }
102
103 /* desperation time :-) */
104 int id_cleanup(int timeout_ms)
105 {
106         int i;
107         int num_freed = 0;
108         struct timeval now;
109         gettimeofday(&now, NULL);
110
111         for (i = 0; i < 65536; i++) {
112                 if (ids[i].in_use == 2) {
113                         id_free(&ids[i]);
114                         num_freed++;
115                         num_free_ids--;         /* was already counted */
116
117                         continue;
118                 }
119                 if (mydifftime(ids[i].timestamp, now) > timeout_ms &&
120                     ids[i].retries == num_retries) {
121                         id_free(&ids[i]);
122                         num_freed++;
123
124                         continue;
125                 }
126         }
127
128         return num_freed;
129 }
130
131 int get_num_free_ids()
132 {
133         return num_free_ids;
134 }