massive conversion of types.
[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  */
8
9 static const char rcsid[] = "$Id$";
10
11 #include        "autoconf.h"
12
13 #include        <sys/types.h>
14 #include        <sys/stat.h>
15
16 #include        <stdio.h>
17 #include        <stdlib.h>
18 #include        <string.h>
19
20 #if HAVE_MALLOC_H
21 #  include      <malloc.h>
22 #endif
23
24 #include        "radiusd.h"
25
26 NAS             *naslist;
27
28 /*
29  *      Free a NAS list.
30  */
31 static void nas_free(NAS *cl)
32 {
33         NAS *next;
34
35         while(cl) {
36                 next = cl->next;
37                 free(cl);
38                 cl = next;
39         }
40 }
41
42 /*
43  *      Read the nas file.
44  */
45 int read_naslist_file(char *file)
46 {
47         FILE    *fp;
48         char    buffer[256];
49         char    hostnm[256];
50         char    shortnm[256];
51         char    nastype[256];
52         int     lineno = 0;
53         char    *p;
54         NAS     *c;
55
56         nas_free(naslist);
57         naslist = NULL;
58
59         if ((fp = fopen(file, "r")) == NULL) {
60                 log(L_CONS|L_ERR, "cannot open %s", file);
61                 return -1;
62         }
63         while(fgets(buffer, 256, fp) != NULL) {
64                 lineno++;
65                 if (strchr(buffer, '\n') == NULL) {
66                         log(L_ERR, "%s[%d]: line too long", file, lineno);
67                         return -1;
68                 }
69                 if (buffer[0] == '#' || buffer[0] == '\n')
70                         continue;
71
72                 p = buffer;
73                 if (!getword(&p, hostnm, sizeof(hostnm)) ||
74                     !getword(&p, shortnm, sizeof(shortnm))) {
75                         log(L_ERR, "%s[%d]: unexpected end of line", file, lineno);
76                         continue;
77                 }
78                 (void)getword(&p, nastype, sizeof(nastype));
79
80                 /*
81                  *      Double-check lengths to be sure they're sane
82                  */
83                 if (strlen(hostnm) >= sizeof(c->longname)) {
84                         log(L_ERR, "%s[%d]: host name of length %d is greater than the allowed maximum of %d.",
85                             file, lineno,
86                             strlen(hostnm), sizeof(c->longname) - 1);
87                         return -1;
88                 }
89                 if (strlen(shortnm) > sizeof(c->shortname)) {
90                         log(L_ERR, "%s[%d]: short name of length %d is greater than the allowed maximum of %d.",
91                             file, lineno,
92                             strlen(shortnm), sizeof(c->shortname) - 1);
93                         return -1;
94                 }
95                 if (strlen(nastype) >= sizeof(c->nastype)) {
96                         log(L_ERR, "%s[%d]: NAS type of length %d is greater than the allowed maximum of %d.",
97                             file, lineno,
98                             strlen(nastype), sizeof(c->nastype) - 1);
99                         return -1;
100                 }
101                 
102                 /*
103                  *      It should be OK now, let's create the buffer.
104                  */
105                 if ((c = malloc(sizeof(NAS))) == NULL) {
106                         log(L_CONS|L_ERR, "%s[%d]: out of memory",
107                                 file, lineno);
108                         return -1;
109                 }
110
111                 strcpy(c->nastype, nastype);
112                 strcpy(c->shortname, shortnm);
113
114                 if (strcmp(hostnm, "DEFAULT") == 0) {
115                         c->ipaddr = 0;
116                         strcpy(c->longname, hostnm);
117                 } else {
118                         c->ipaddr = ip_getaddr(hostnm);
119                         strcpy(c->longname, ip_hostname(c->ipaddr));
120                 }
121
122                 c->next = naslist;
123                 naslist = c;
124         }
125         fclose(fp);
126
127         return 0;
128 }
129
130
131 /*
132  *      Find a nas by IP address.
133  *      If it can't be found, return the DEFAULT nas, instead.
134  */
135 NAS *nas_find(uint32_t ipaddr)
136 {
137         NAS *nas;
138         NAS *default_nas;
139
140         default_nas = NULL;
141
142         for (nas = naslist; nas; nas = nas->next) {
143                 if (ipaddr == nas->ipaddr)
144                         return nas;
145                 if (strcmp(nas->longname, "DEFAULT") == 0)
146                         default_nas = nas;
147         }
148
149         return default_nas;
150 }
151
152
153 /*
154  *      Find a nas by name.
155  *      If it can't be found, return the DEFAULT nas, instead.
156  */
157 NAS *nas_findbyname(char *nasname)
158 {
159         NAS     *nas;
160         NAS     *default_nas;
161
162         default_nas = NULL;
163
164         for (nas = naslist; nas; nas = nas->next) {
165                 if (strcmp(nasname, nas->shortname) == 0 ||
166                     strcmp(nasname, nas->longname) == 0)
167                         return nas;
168                 if (strcmp(nas->longname, "DEFAULT") == 0)
169                         default_nas = nas;
170         }
171
172         return default_nas;
173 }
174
175
176 /*
177  *      Find the name of a nas (prefer short name).
178  */
179 char *nas_name(uint32_t ipaddr)
180 {
181         NAS *cl;
182
183         if ((cl = nas_find(ipaddr)) != NULL) {
184                 if (cl->shortname[0])
185                         return cl->shortname;
186                 else
187                         return cl->longname;
188         }
189         return ip_hostname(ipaddr);
190 }
191
192 /*
193  *      Find the name of a nas (prefer short name) based on the request.
194  */
195 char *nas_name2(RADIUS_PACKET *packet)
196 {
197         uint32_t        ipaddr;
198         NAS             *cl;
199         VALUE_PAIR      *pair;
200
201         if ((pair = pairfind(packet->vps, PW_NAS_IP_ADDRESS)) != NULL)
202                 ipaddr = pair->lvalue;
203         else
204                 ipaddr = packet->src_ipaddr;
205
206         if ((cl = nas_find(ipaddr)) != NULL) {
207                 if (cl->shortname[0])
208                         return cl->shortname;
209                 else
210                         return cl->longname;
211         }
212         return ip_hostname(ipaddr);
213 }
214