2 * dhcp.c DHCP processing. Done poorly for now.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 * Copyright 2008 The FreeRADIUS server project
21 * Copyright 2008 Alan DeKok <aland@deployingradius.com>
26 static int dhcp_process(REQUEST *request)
31 vp = pairfind(request->packet->vps, DHCP2ATTR(53)); /* DHCP-Message-Type */
33 DICT_VALUE *dv = dict_valbyattr(DHCP2ATTR(53), vp->vp_integer);
34 DEBUG("Trying sub-section dhcp %s {...}",
35 dv->name ? dv->name : "<unknown>");
36 rcode = module_post_auth(vp->vp_integer, request);
38 DEBUG("DHCP: Failed to find DHCP-Message-Type in packet!");
39 rcode = RLM_MODULE_FAIL;
43 * Look for Relay attribute, and forward it if so...
48 case RLM_MODULE_UPDATED:
49 if (request->packet->code == (PW_DHCP_DISCOVER)) {
50 request->reply->code = PW_DHCP_OFFER;
53 } else if (request->packet->code == PW_DHCP_REQUEST) {
54 request->reply->code = PW_DHCP_ACK;
61 case RLM_MODULE_REJECT:
63 case RLM_MODULE_INVALID:
65 request->reply->code = PW_DHCP_NAK;
68 case RLM_MODULE_NOTFOUND:
69 request->reply->code = PW_DHCP_DECLINE;
72 case RLM_MODULE_HANDLED:
73 request->reply->code = PW_DHCP_NAK;
80 static int dhcp_socket_parse(CONF_SECTION *cs, rad_listen_t *this)
84 listen_socket_t *sock;
86 rcode = common_socket_parse(cs, this);
87 if (rcode != 0) return rcode;
92 * FIXME: Parse config file option for "do broadast = yes/no"
94 if (setsockopt(this->fd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0) {
95 radlog(L_ERR, "Can't set broadcast option: %s\n",
100 if (setsockopt(this->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
101 radlog(L_ERR, "Can't set re-use addres option: %s\n",
111 * Check if an incoming request is "ok"
113 * It takes packets, not requests. It sees if the packet looks
114 * OK. If so, it does a number of sanity checks on it.
116 static int dhcp_socket_recv(rad_listen_t *listener,
117 RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
119 RADIUS_PACKET *packet;
122 packet = fr_dhcp_recv(listener->fd);
124 radlog(L_ERR, "%s", librad_errstr);
128 if ((client = client_listener_find(listener,
129 &packet->src_ipaddr)) == NULL) {
131 radlog(L_ERR, "Ignoring request from unknown client %s port %d",
132 inet_ntop(packet->src_ipaddr.af,
133 &packet->src_ipaddr.ipaddr,
134 buffer, sizeof(buffer)),
140 if (!received_request(listener, packet, prequest, client)) {
145 *pfun = dhcp_process;
152 * Send an authentication response packet
154 static int dhcp_socket_send(rad_listen_t *listener, REQUEST *request)
156 rad_assert(request->listener == listener);
157 rad_assert(listener->send == dhcp_socket_send);
159 if (request->reply->code == 0) return 0; /* don't reply */
161 if (fr_dhcp_encode(request->reply, request->packet) < 0) {
165 return fr_dhcp_send(request->reply);
169 static int dhcp_socket_encode(UNUSED rad_listen_t *listener, REQUEST *request)
171 DEBUG2("NO ENCODE!");
173 return fr_dhcp_encode(request->reply, request->packet);
177 static int dhcp_socket_decode(UNUSED rad_listen_t *listener, REQUEST *request)
179 return fr_dhcp_decode(request->packet);
181 #endif /* WITH_DCHP */