perl -i -npe "s/[ \t]+$//g" `find src -name "*.[ch]" -print`
[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 ((fp = fopen(file, "r")) == NULL) {
73                 /* The naslist file is no longer required.  All configuration
74                    information comes from radiusd.conf.  If naslist exists it
75                    will be used, but if it doesn't exist it will be silently
76                    ignored. */
77                 return 0;
78         }
79         radlog(L_INFO, "Using deprecated naslist file.  Support for this will go away soon.");
80         while(fgets(buffer, 256, fp) != NULL) {
81                 lineno++;
82                 if (!feof(fp) && (strchr(buffer, '\n') == NULL)) {
83                         radlog(L_ERR, "%s[%d]: line too long", file, lineno);
84                         return -1;
85                 }
86                 if (buffer[0] == '#' || buffer[0] == '\n')
87                         continue;
88
89                 p = buffer;
90                 if (!getword(&p, hostnm, sizeof(hostnm)) ||
91                     !getword(&p, shortnm, sizeof(shortnm))) {
92                         radlog(L_ERR, "%s[%d]: unexpected end of line",
93                                file, lineno);
94                         continue;
95                 }
96                 (void)getword(&p, nastype, sizeof(nastype));
97
98                 /*
99                  *      Double-check lengths to be sure they're sane
100                  */
101                 if (strlen(hostnm) >= sizeof(nas->longname)) {
102                         radlog(L_ERR, "%s[%d]: host name of length %d is greater than the allowed maximum of %d.",
103                                file, lineno,
104                                (int) strlen(hostnm),
105                                (int) sizeof(nas->longname) - 1);
106                         return -1;
107                 }
108                 if (strlen(shortnm) > sizeof(nas->shortname)) {
109                         radlog(L_ERR, "%s[%d]: short name of length %d is greater than the allowed maximum of %d.",
110                                file, lineno,
111                                (int) strlen(shortnm),
112                                (int) sizeof(nas->shortname) - 1);
113                         return -1;
114                 }
115                 if (strlen(nastype) >= sizeof(nas->nastype)) {
116                         radlog(L_ERR, "%s[%d]: NAS type of length %d is greater than the allowed maximum of %d.",
117                                file, lineno,
118                                (int) strlen(nastype),
119                                (int) sizeof(nas->nastype) - 1);
120                         return -1;
121                 }
122
123                 /*
124                  *      It should be OK now, let's create the buffer.
125                  */
126                 nas = rad_malloc(sizeof(NAS));
127                 memset(nas, 0, sizeof(*nas));
128
129                 strcpy(nas->nastype, nastype);
130                 strcpy(nas->shortname, shortnm);
131
132                 if (strcmp(hostnm, "DEFAULT") == 0) {
133                         nas->ipaddr = 0;
134                         strcpy(nas->longname, hostnm);
135                 } else {
136                         nas->ipaddr = ip_getaddr(hostnm);
137                         ip_hostname(nas->longname, sizeof(nas->longname),
138                                         nas->ipaddr);
139                 }
140
141                 nas->next = naslist;
142                 naslist = nas;
143         }
144         fclose(fp);
145
146         return 0;
147 }
148
149
150 /*
151  *      Find a nas by IP address.
152  *      If it can't be found, return the DEFAULT nas, instead.
153  */
154 NAS *nas_find(uint32_t ipaddr)
155 {
156         NAS *nas;
157         NAS *default_nas;
158
159         default_nas = NULL;
160
161         for (nas = naslist; nas; nas = nas->next) {
162                 if (ipaddr == nas->ipaddr)
163                         return nas;
164                 if (strcmp(nas->longname, "DEFAULT") == 0)
165                         default_nas = nas;
166         }
167
168         return default_nas;
169 }
170
171
172 /*
173  *      Find a nas by name.
174  *      If it can't be found, return the DEFAULT nas, instead.
175  */
176 NAS *nas_findbyname(char *nasname)
177 {
178         NAS     *nas;
179         NAS     *default_nas;
180
181         default_nas = NULL;
182
183         for (nas = naslist; nas; nas = nas->next) {
184                 if (strcmp(nasname, nas->shortname) == 0 ||
185                                 strcmp(nasname, nas->longname) == 0)
186                         return nas;
187                 if (strcmp(nas->longname, "DEFAULT") == 0)
188                         default_nas = nas;
189         }
190
191         return default_nas;
192 }
193
194
195 /*
196  *      Find the name of a nas (prefer short name).
197  */
198 const char *nas_name(uint32_t ipaddr)
199 {
200         NAS *nas;
201
202         if ((nas = nas_find(ipaddr)) != NULL) {
203                 if (nas->shortname[0])
204                         return nas->shortname;
205                 else
206                         return nas->longname;
207         }
208
209         return "UNKNOWN-NAS";
210 }
211
212 /*
213  *      Find the name of a nas (prefer short name) based on the request.
214  */
215 const char *nas_name2(RADIUS_PACKET *packet)
216 {
217         NAS *nas;
218
219         if ((nas = nas_find(packet->src_ipaddr)) != NULL) {
220                 if (nas->shortname[0])
221                         return nas->shortname;
222                 else
223                         return nas->longname;
224         }
225
226         return "UNKNOWN-NAS";
227 }
228
229 /*
230  *      Find the name of a nas (prefer short name) based on ipaddr,
231  *      store in passed buffer.  If NAS is unknown, return dotted quad.
232  */
233 char * nas_name3(char *buf, size_t buflen, uint32_t ipaddr)
234 {
235         NAS *nas;
236
237         if ((nas = nas_find(ipaddr)) != NULL) {
238                 if (nas->shortname[0]) {
239                         strNcpy(buf, (char *)nas->shortname, buflen);
240                         return buf;
241                 }
242                 else {
243                         strNcpy(buf, (char *)nas->longname, buflen);
244                         return buf;
245                 }
246         }
247         ip_ntoa(buf, ipaddr);
248         return buf;
249 }
250
251