ed3d794f52b728f556844f6e8d89d2f612629e66
[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 von 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                 radlog(L_CONS|L_ERR, "cannot open %s", file);
74                 return -1;
75         }
76         while(fgets(buffer, 256, fp) != NULL) {
77                 lineno++;
78                 if (strchr(buffer, '\n') == NULL) {
79                         radlog(L_ERR, "%s[%d]: line too long", file, lineno);
80                         return -1;
81                 }
82                 if (buffer[0] == '#' || buffer[0] == '\n')
83                         continue;
84
85                 p = buffer;
86                 if (!getword(&p, hostnm, sizeof(hostnm)) ||
87                     !getword(&p, shortnm, sizeof(shortnm))) {
88                         radlog(L_ERR, "%s[%d]: unexpected end of line", file, lineno);
89                         continue;
90                 }
91                 (void)getword(&p, nastype, sizeof(nastype));
92
93                 /*
94                  *      Double-check lengths to be sure they're sane
95                  */
96                 if (strlen(hostnm) >= sizeof(nas->longname)) {
97                         radlog(L_ERR, "%s[%d]: host name of length %d is greater than the allowed maximum of %d.",
98                             file, lineno,
99                             strlen(hostnm), sizeof(nas->longname) - 1);
100                         return -1;
101                 }
102                 if (strlen(shortnm) > sizeof(nas->shortname)) {
103                         radlog(L_ERR, "%s[%d]: short name of length %d is greater than the allowed maximum of %d.",
104                             file, lineno,
105                             strlen(shortnm), sizeof(nas->shortname) - 1);
106                         return -1;
107                 }
108                 if (strlen(nastype) >= sizeof(nas->nastype)) {
109                         radlog(L_ERR, "%s[%d]: NAS type of length %d is greater than the allowed maximum of %d.",
110                             file, lineno,
111                             strlen(nastype), sizeof(nas->nastype) - 1);
112                         return -1;
113                 }
114                 
115                 /*
116                  *      It should be OK now, let's create the buffer.
117                  */
118                 nas = rad_malloc(sizeof(NAS));
119
120                 strcpy(nas->nastype, nastype);
121                 strcpy(nas->shortname, shortnm);
122
123                 if (strcmp(hostnm, "DEFAULT") == 0) {
124                         nas->ipaddr = 0;
125                         strcpy(nas->longname, hostnm);
126                 } else {
127                         nas->ipaddr = ip_getaddr(hostnm);
128                         ip_hostname(nas->longname, sizeof(nas->longname),
129                                     nas->ipaddr);
130                 }
131
132                 nas->next = naslist;
133                 naslist = nas;
134         }
135         fclose(fp);
136
137         return 0;
138 }
139
140
141 /*
142  *      Find a nas by IP address.
143  *      If it can't be found, return the DEFAULT nas, instead.
144  */
145 NAS *nas_find(uint32_t ipaddr)
146 {
147         NAS *nas;
148         NAS *default_nas;
149
150         default_nas = NULL;
151
152         for (nas = naslist; nas; nas = nas->next) {
153                 if (ipaddr == nas->ipaddr)
154                         return nas;
155                 if (strcmp(nas->longname, "DEFAULT") == 0)
156                         default_nas = nas;
157         }
158
159         return default_nas;
160 }
161
162
163 /*
164  *      Find a nas by name.
165  *      If it can't be found, return the DEFAULT nas, instead.
166  */
167 NAS *nas_findbyname(char *nasname)
168 {
169         NAS     *nas;
170         NAS     *default_nas;
171
172         default_nas = NULL;
173
174         for (nas = naslist; nas; nas = nas->next) {
175                 if (strcmp(nasname, nas->shortname) == 0 ||
176                     strcmp(nasname, nas->longname) == 0)
177                         return nas;
178                 if (strcmp(nas->longname, "DEFAULT") == 0)
179                         default_nas = nas;
180         }
181
182         return default_nas;
183 }
184
185
186 /*
187  *      Find the name of a nas (prefer short name).
188  */
189 const char *nas_name(uint32_t ipaddr)
190 {
191         NAS *nas;
192
193         if ((nas = nas_find(ipaddr)) != NULL) {
194                 if (nas->shortname[0])
195                         return nas->shortname;
196                 else
197                         return nas->longname;
198         }
199
200         return client_name(ipaddr);
201 }
202
203 /*
204  *      Find the name of a nas (prefer short name) based on the request.
205  */
206 const char *nas_name2(RADIUS_PACKET *packet)
207 {
208         NAS             *nas;
209
210         if ((nas = nas_find(packet->src_ipaddr)) != NULL) {
211                 if (nas->shortname[0])
212                         return nas->shortname;
213                 else
214                         return nas->longname;
215         }
216
217         return client_name(packet->src_ipaddr);
218 }
219