1 /*
2  * DHCP library functions
3  * Copyright (C) 2003, 2004, 2005 Mondru AB.
4  * Copyright (c) 2007 David Bird <david@coova.com>
5  *
6  * The contents of this file may be used under the terms of the GNU
7  * General Public License Version 2, provided that the above copyright
8  * notice and this permission notice is included in all copies or
9  * substantial portions of the software.
10  *
11  * The initial developer of the original code is
12  * Jens Jakobsen <jj@chillispot.org>
13  *
14  */
15 
16 
17 #ifndef _DHCP_H
18 #define _DHCP_H
19 
20 #include "pkt.h"
21 #include "garden.h"
22 #include "net.h"
23 
24 /* Option constants */
25 #define DHCP_OPTION_MAGIC_LEN       4
26 
27 #define DHCP_OPTION_PAD             0
28 #define DHCP_OPTION_SUBNET_MASK     1
29 #define DHCP_OPTION_ROUTER_OPTION   3
30 #define DHCP_OPTION_DNS             6
31 #define DHCP_OPTION_HOSTNAME       12
32 #define DHCP_OPTION_DOMAIN_NAME    15
33 #define DHCP_OPTION_INTERFACE_MTU  26
34 #define DHCP_OPTION_REQUESTED_IP   50
35 #define DHCP_OPTION_LEASE_TIME     51
36 #define DHCP_OPTION_MESSAGE_TYPE   53
37 #define DHCP_OPTION_SERVER_ID      54
38 #define DHCP_OPTION_PARAMETER_REQUEST_LIST 55
39 #define DHCP_OPTION_VENDOR_CLASS_IDENTIFIER 60
40 #define DHCP_OPTION_CLIENT_IDENTIFIER 61
41 #define DHCP_OPTION_CLIENT_FQDN    81
42 
43 /* !!highly experimental!! */
44 #define DHCP_OPTION_CALLED_STATION_ID  197
45 #define DHCP_OPTION_CAPTIVE_PORTAL_ACL 198
46 #define DHCP_OPTION_CAPTIVE_PORTAL_URL 199
47 
48 #define DHCP_OPTION_END           255
49 
50 /* BOOTP Message Types */
51 #define DHCP_BOOTREQUEST  1
52 #define DHCP_BOOTREPLY    2
53 
54 /* DHCP Message Types */
55 #define DHCPDISCOVER      1
56 #define DHCPOFFER         2
57 #define DHCPREQUEST       3
58 #define DHCPDECLINE       4
59 #define DHCPACK           5
60 #define DHCPNAK           6
61 #define DHCPRELEASE       7
62 #define DHCPINFORM        8
63 
64 /* UDP Ports */
65 #define DHCP_BOOTPS 67
66 #define DHCP_BOOTPC 68
67 #define DHCP_DNS    53
68 
69 /* TCP Ports */
70 #define DHCP_HTTP   80
71 #define DHCP_HTTPS 443
72 
73 
74 #define DHCP_ARP_REQUEST 1
75 #define DHCP_ARP_REPLY   2
76 
77 #define DHCP_DNS_HLEN  12
78 
79 struct dhcp_t; /* Forward declaration */
80 
81 /* Authentication states */
82 #define DHCP_AUTH_NONE        0
83 #define DHCP_AUTH_DROP        1
84 #define DHCP_AUTH_PASS        2
85 #define DHCP_AUTH_UNAUTH_TOS  3
86 #define DHCP_AUTH_AUTH_TOS    4
87 #define DHCP_AUTH_DNAT        5
88 #define DHCP_AUTH_SPLASH      6
89 
90 #define DHCP_DOMAIN_LEN      30
91 
92 #define DHCP_DNAT_MAX        64
93 
94 struct dhcp_conn_t {
95   int inuse;                    /* Free = 0; Inuse = 1 */
96   time_t lasttime;      /* Last time we heard anything from client */
97   struct dhcp_conn_t *nexthash; /* Linked list part of hash table */
98   struct dhcp_conn_t *next;    /* Next in linked list. 0: Last */
99   struct dhcp_conn_t *prev;    /* Previous in linked list. 0: First */
100   struct dhcp_t *parent;       /* Parent of all connections */
101   void *peer;                  /* Peer protocol handler */
102   uint8_t ourmac[PKT_ETH_ALEN];    /* Our MAC address */
103   uint8_t hismac[PKT_ETH_ALEN];    /* Peer's MAC address */
104   struct in_addr ourip;        /* IP address to listen to */
105   struct in_addr hisip;        /* Client IP address */
106   struct in_addr hismask;      /* Client Network Mask */
107   struct in_addr dns1;         /* Client DNS address */
108   struct in_addr dns2;         /* Client DNS address */
109   char domain[DHCP_DOMAIN_LEN];/* Domain name to use for DNS lookups */
110   int authstate;               /* 0: Unauthenticated, 1: Authenticated */
111   uint8_t unauth_cp;           /* Unauthenticated codepoint */
112   uint8_t auth_cp;             /* Authenticated codepoint */
113   int nextdnat;                /* Next location to use for DNAT */
114   uint32_t dnatip[DHCP_DNAT_MAX]; /* Destination NAT destination IP address */
115   uint16_t dnatport[DHCP_DNAT_MAX]; /* Destination NAT source port */
116   uint8_t dnatmac[DHCP_DNAT_MAX][PKT_ETH_ALEN]; /* Destination NAT source mac */
117 /*  uint16_t mtu;                 Maximum transfer unit */
118 
119   /*XXX: optional*/
120   struct {
121     uint8_t sname[DHCP_SNAME_LEN];     /* 64 Optional server host name, null terminated string.*/
122     uint8_t file[DHCP_FILE_LEN];       /* 128 Boot file name, null terminated string; "generic" name */
123     uint8_t options[DHCP_OPTIONS_LEN]; /* var Optional parameters field. */
124     size_t option_length;
125   } dhcp_opts;
126 };
127 
128 
129 /* ***********************************************************
130  * Information storage for each dhcp instance
131  *
132  * Normally each instance of the application corresponds to
133  * one instance of a dhcp instance.
134  *
135  *************************************************************/
136 
137 struct dhcp_t {
138 
139   /* network interfaces */
140   struct _net_interface ipif, arpif, eapif;
141 
142   int numconn;          /* Maximum number of connections */
143 #if defined(__FreeBSD__) || defined (__APPLE__) || defined (__OpenBSD__)
144   char *rbuf;
145   size_t rbuf_max;
146   size_t rbuf_offset;
147   size_t rbuf_len;
148 #endif
149 
150   int debug;            /* Set to print debug messages */
151   struct in_addr ourip; /* IP address to listen to */
152   int mtu;              /* Maximum transfer unit */
153   uint32_t lease;       /* Seconds before reneval */
154   int usemac;           /* Use given mac address */
155   int promisc;          /* Set interface in promisc mode */
156   int allowdyn;         /* Allow allocation of IP address on DHCP request */
157   struct in_addr uamlisten; /* IP address to redirect HTTP requests to */
158   uint16_t uamport;     /* TCP port to redirect HTTP requests to */
159   struct in_addr *authip; /* IP address of authentication server */
160   int authiplen;        /* Number of authentication server IP addresses */
161   int anydns;           /* Allow any dns server */
162 
163   int relayfd;          /* DHCP relay socket, 0 if not relaying */
164 
165   /* Connection management */
166   struct dhcp_conn_t *conn;
167   struct dhcp_conn_t *firstfreeconn; /* First free in linked list */
168   struct dhcp_conn_t *lastfreeconn;  /* Last free in linked list */
169   struct dhcp_conn_t *firstusedconn; /* First used in linked list */
170   struct dhcp_conn_t *lastusedconn;  /* Last used in linked list */
171 
172   /* Hash related parameters */
173   int hashsize;                 /* Size of hash table */
174   int hashlog;                  /* Log2 size of hash table */
175   int hashmask;                 /* Bitmask for calculating hash */
176   struct dhcp_conn_t **hash;    /* Hashsize array of pointer to member */
177 
178   pass_through pass_throughs[MAX_PASS_THROUGHS];
179   size_t num_pass_throughs;
180 
181   /* Call back functions */
182   int (*cb_data_ind) (struct dhcp_conn_t *conn, void *pack, size_t len);
183   int (*cb_eap_ind)  (struct dhcp_conn_t *conn, void *pack, size_t len);
184   int (*cb_request) (struct dhcp_conn_t *conn, struct in_addr *addr, struct dhcp_fullpacket_t *pack, size_t len);
185   int (*cb_connect) (struct dhcp_conn_t *conn);
186   int (*cb_disconnect) (struct dhcp_conn_t *conn, int term_cause);
187   int (*cb_getinfo) (struct dhcp_conn_t *conn, bstring b, int fmt);
188 };
189 
190 
191 const char* dhcp_version();
192 
193 int dhcp_new(struct dhcp_t **dhcp, int numconn, char *interface,
194 	 int usemac, uint8_t *mac, int promisc,
195 	 struct in_addr *listen, int lease, int allowdyn,
196 	 struct in_addr *uamlisten, uint16_t uamport,
197 	 int useeapol);
198 
199 int dhcp_set(struct dhcp_t *dhcp, int debug);
200 
201 int dhcp_free(struct dhcp_t *dhcp);
202 
203 int dhcp_timeout(struct dhcp_t *this);
204 
205 struct timeval * dhcp_timeleft(struct dhcp_t *this, struct timeval *tvp);
206 
207 
208 int dhcp_validate(struct dhcp_t *this);
209 
210 int dhcp_set_addrs(struct dhcp_conn_t *conn,
211 	       struct in_addr *hisip, struct in_addr *hismask,
212 	       struct in_addr *ourip, struct in_addr *ourmask,
213 	       struct in_addr *dns1, struct in_addr *dns2, char *domain);
214 
215 
216 /* Called whenever a packet arrives */
217 int dhcp_decaps(struct dhcp_t *this);
218 int dhcp_relay_decaps(struct dhcp_t *this);
219 int dhcp_data_req(struct dhcp_conn_t *conn, void *pack, size_t len, int ethhdr);
220 
221 int dhcp_set_cb_data_ind(struct dhcp_t *this,
222   int (*cb_data_ind) (struct dhcp_conn_t *conn, void *pack, size_t len));
223 
224 int dhcp_set_cb_request(struct dhcp_t *this,
225   int (*cb_request) (struct dhcp_conn_t *conn, struct in_addr *addr, struct dhcp_fullpacket_t *pack, size_t len));
226 
227 int dhcp_set_cb_disconnect(struct dhcp_t *this,
228   int (*cb_disconnect) (struct dhcp_conn_t *conn, int term_cause));
229 
230 int dhcp_set_cb_connect(struct dhcp_t *this,
231   int (*cb_connect) (struct dhcp_conn_t *conn));
232 
233 int dhcp_set_cb_eap_ind(struct dhcp_t *this,
234   int (*cb_eap_ind) (struct dhcp_conn_t *conn, void *pack, size_t len));
235 
236 int dhcp_set_cb_getinfo(struct dhcp_t *this,
237   int (*cb_getinfo) (struct dhcp_conn_t *conn, bstring b, int fmt));
238 
239 int dhcp_hashget(struct dhcp_t *this, struct dhcp_conn_t **conn, uint8_t *hwaddr);
240 
241 int dhcp_newconn(struct dhcp_t *this, struct dhcp_conn_t **conn, uint8_t *hwaddr);
242 
243 int dhcp_freeconn(struct dhcp_conn_t *conn, int term_cause);
244 
245 
246 int dhcp_arp_ind(struct dhcp_t *this);  /* ARP Indication */
247 
248 int dhcp_sendEAP(struct dhcp_conn_t *conn, void *pack, size_t len);
249 
250 int dhcp_sendEAPreject(struct dhcp_conn_t *conn, void *pack, size_t len);
251 
252 int dhcp_eapol_ind(struct dhcp_t *this);
253 
254 void dhcp_release_mac(struct dhcp_t *this, uint8_t *hwaddr, int term_cause);
255 
256 #define LIST_SHORT_FMT 0
257 #define LIST_LONG_FMT  1
258 #define LIST_JSON_FMT  2
259 
260 void dhcp_list(struct dhcp_t *this, bstring s, bstring pre, bstring post, int listfmt);
261 
262 void dhcp_print(struct dhcp_t *this, bstring s, int listfmt, struct dhcp_conn_t *conn);
263 
264 int dhcp_filterDNS(struct dhcp_conn_t *conn,
265 		   struct pkt_ippacket_t *pack,
266 		   size_t *plen);
267 
268 int dhcp_gettag(struct dhcp_packet_t *pack, size_t length,
269 		struct dhcp_tag_t **tag, uint8_t tagtype);
270 
271 #endif	/* !_DHCP_H */
272