corrected typo
[freeradius.git] / src / main / nas.c
1 /*
2  * nas.c        Functions to do with a NASLIST. This is here because
3  *              radzap needs it as well.
4  *
5  * Version:     $Id$
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
21  * Copyright 2000  The FreeRADIUS server project
22  * Copyright 2000  Miquel van Smoorenburg <miquels@cistron.nl>
23  * Copyright 2000  Alan DeKok <aland@ox.org>
24  */
25
26 static const char rcsid[] = "$Id$";
27
28 #include "autoconf.h"
29 #include "libradius.h"
30
31 #include <sys/stat.h>
32
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36
37 #include "radiusd.h"
38
39 static NAS *naslist = NULL;
40
41 /*
42  *      Free a NAS list.
43  */
44 static void nas_free(NAS *cl)
45 {
46         NAS *next;
47
48         while(cl) {
49                 next = cl->next;
50                 free(cl);
51                 cl = next;
52         }
53 }
54
55 /*
56  *      Read the nas file.
57  */
58 int read_naslist_file(char *file)
59 {
60         FILE *fp;
61         char buffer[256];
62         char hostnm[256];
63         char shortnm[256];
64         char nastype[256];
65         int lineno = 0;
66         char *p;
67         NAS *nas;
68
69         nas_free(naslist);
70         naslist = NULL;
71
72         if (!file) return 0;
73
74         if ((fp = fopen(file, "r")) == NULL) {
75                 /* The naslist file is no longer required.  All configuration
76                    information comes from radiusd.conf.  If naslist exists it
77                    will be used, but if it doesn't exist it will be silently
78                    ignored. */
79                 return 0;
80         }
81         radlog(L_INFO, "Using deprecated naslist file.  Support for this will go away soon.");
82         while(fgets(buffer, 256, fp) != NULL) {
83                 lineno++;
84                 if (!feof(fp) && (strchr(buffer, '\n') == NULL)) {
85                         radlog(L_ERR, "%s[%d]: line too long", file, lineno);
86                         return -1;
87                 }
88                 if (buffer[0] == '#' || buffer[0] == '\n')
89                         continue;
90
91                 p = buffer;
92                 if (!getword(&p, hostnm, sizeof(hostnm)) ||
93                     !getword(&p, shortnm, sizeof(shortnm))) {
94                         radlog(L_ERR, "%s[%d]: unexpected end of line",
95                                file, lineno);
96                         continue;
97                 }
98                 (void)getword(&p, nastype, sizeof(nastype));
99
100                 /*
101                  *      Double-check lengths to be sure they're sane
102                  */
103                 if (strlen(hostnm) >= sizeof(nas->longname)) {
104                         radlog(L_ERR, "%s[%d]: host name of length %d is greater than the allowed maximum of %d.",
105                                file, lineno,
106                                (int) strlen(hostnm),
107                                (int) sizeof(nas->longname) - 1);
108                         return -1;
109                 }
110                 if (strlen(shortnm) > sizeof(nas->shortname)) {
111                         radlog(L_ERR, "%s[%d]: short name of length %d is greater than the allowed maximum of %d.",
112                                file, lineno,
113                                (int) strlen(shortnm),
114                                (int) sizeof(nas->shortname) - 1);
115                         return -1;
116                 }
117                 if (strlen(nastype) >= sizeof(nas->nastype)) {
118                         radlog(L_ERR, "%s[%d]: NAS type of length %d is greater than the allowed maximum of %d.",
119                                file, lineno,
120                                (int) strlen(nastype),
121                                (int) sizeof(nas->nastype) - 1);
122                         return -1;
123                 }
124
125                 /*
126                  *      It should be OK now, let's create the buffer.
127                  */
128                 nas = rad_malloc(sizeof(NAS));
129                 memset(nas, 0, sizeof(*nas));
130
131                 strcpy(nas->nastype, nastype);
132                 strcpy(nas->shortname, shortnm);
133
134                 if (strcmp(hostnm, "DEFAULT") == 0) {
135                         nas->ipaddr = 0;
136                         strcpy(nas->longname, hostnm);
137                 } else {
138                         nas->ipaddr = ip_getaddr(hostnm);
139                         ip_hostname(nas->longname, sizeof(nas->longname),
140                                         nas->ipaddr);
141                 }
142
143                 nas->next = naslist;
144                 naslist = nas;
145         }
146         fclose(fp);
147
148         return 0;
149 }
150
151
152 /*
153  *      Find a nas by IP address.
154  *      If it can't be found, return the DEFAULT nas, instead.
155  */
156 NAS *nas_find(uint32_t ipaddr)
157 {
158         NAS *nas;
159         NAS *default_nas;
160
161         default_nas = NULL;
162
163         for (nas = naslist; nas; nas = nas->next) {
164                 if (ipaddr == nas->ipaddr)
165                         return nas;
166                 if (strcmp(nas->longname, "DEFAULT") == 0)
167                         default_nas = nas;
168         }
169
170         return default_nas;
171 }
172
173
174 /*
175  *      Find a nas by name.
176  *      If it can't be found, return the DEFAULT nas, instead.
177  */
178 NAS *nas_findbyname(char *nasname)
179 {
180         NAS     *nas;
181         NAS     *default_nas;
182
183         default_nas = NULL;
184
185         for (nas = naslist; nas; nas = nas->next) {
186                 if (strcmp(nasname, nas->shortname) == 0 ||
187                                 strcmp(nasname, nas->longname) == 0)
188                         return nas;
189                 if (strcmp(nas->longname, "DEFAULT") == 0)
190                         default_nas = nas;
191         }
192
193         return default_nas;
194 }
195
196
197 /*
198  *      Find the name of a nas (prefer short name).
199  */
200 const char *nas_name(uint32_t ipaddr)
201 {
202         NAS *nas;
203
204         if ((nas = nas_find(ipaddr)) != NULL) {
205                 if (nas->shortname[0])
206                         return nas->shortname;
207                 else
208                         return nas->longname;
209         }
210
211         return "UNKNOWN-NAS";
212 }
213
214 /*
215  *      Find the name of a nas (prefer short name) based on the request.
216  */
217 const char *nas_name2(RADIUS_PACKET *packet)
218 {
219         NAS *nas;
220
221         if ((nas = nas_find(packet->src_ipaddr)) != NULL) {
222                 if (nas->shortname[0])
223                         return nas->shortname;
224                 else
225                         return nas->longname;
226         }
227
228         return "UNKNOWN-NAS";
229 }
230
231 /*
232  *      Find the name of a nas (prefer short name) based on ipaddr,
233  *      store in passed buffer.  If NAS is unknown, return dotted quad.
234  */
235 char * nas_name3(char *buf, size_t buflen, uint32_t ipaddr)
236 {
237         NAS *nas;
238
239         if ((nas = nas_find(ipaddr)) != NULL) {
240                 if (nas->shortname[0]) {
241                         strNcpy(buf, (char *)nas->shortname, buflen);
242                         return buf;
243                 }
244                 else {
245                         strNcpy(buf, (char *)nas->longname, buflen);
246                         return buf;
247                 }
248         }
249         ip_ntoa(buf, ipaddr);
250         return buf;
251 }
252
253