Line 0
Link Here
|
|
|
1 |
#include "dhcpd.h" |
2 |
|
3 |
void dhcpleasequery (packet, ms_nulltp) |
4 |
struct packet *packet; |
5 |
int ms_nulltp; |
6 |
{ |
7 |
|
8 |
//printf("Received LEASEQUERY message\n"); |
9 |
struct lease *lease = (struct lease *)0; |
10 |
struct iaddr cip; |
11 |
struct sockaddr_in to; |
12 |
//unsigned packet_length; |
13 |
unsigned char dhcpMsgType; |
14 |
struct dhcp_packet *raw = packet -> raw; |
15 |
struct option_state *options = (struct option_state *)0; |
16 |
struct option_cache *oc = (struct option_cache *)0; |
17 |
struct data_string prl; |
18 |
uint leaseTime; |
19 |
|
20 |
option_state_allocate (&options, MDL); |
21 |
cip.len = sizeof packet -> raw -> ciaddr; |
22 |
memcpy (cip.iabuf, &packet -> raw -> ciaddr, |
23 |
sizeof packet -> raw -> ciaddr); |
24 |
//TODO if IP is all zeros, then set dhcp message type to DHCPUNIMPLEMENTED |
25 |
find_lease_by_ip_addr (&lease, cip, MDL); |
26 |
|
27 |
if (!lease) { |
28 |
//printf("No lease found.\n"); |
29 |
dhcpMsgType = DHCPNAK; |
30 |
} else { |
31 |
if(lease -> binding_state == FTS_ACTIVE) { |
32 |
dhcpMsgType = DHCPACK; |
33 |
} else { |
34 |
dhcpMsgType = DHCPNAK; |
35 |
} |
36 |
//printf("Lease was found.\n"); |
37 |
|
38 |
/* |
39 |
char * pch = lease -> hardware_addr.hbuf; |
40 |
printf("MAC addr (len=%d): %02x:%02x:%02x:%02x:%02x:%02x\n", |
41 |
lease -> hardware_addr.hlen, pch[1], pch[2], pch[3], pch[4], |
42 |
pch[5], pch[6]); |
43 |
|
44 |
printf("Lease has agent options: %s\n", (lease -> agent_options ? "yes" |
45 |
: "no")); |
46 |
printf("Lease ends at %s\n", ctime(&(lease -> ends))); |
47 |
*/ |
48 |
|
49 |
|
50 |
// Set the hardware address fields |
51 |
memcpy (packet -> raw -> chaddr, |
52 |
&lease -> hardware_addr.hbuf [1], sizeof packet -> raw -> chaddr); |
53 |
packet -> raw -> hlen = lease -> hardware_addr.hlen - 1; |
54 |
packet -> raw -> htype = lease -> hardware_addr.hbuf [0]; |
55 |
|
56 |
// Set lease time option |
57 |
if(dhcpMsgType == DHCPACK && lease -> ends > cur_time) { |
58 |
if (!option_cache_allocate (&oc, MDL)) { |
59 |
log_error ("No memory for lease time option."); |
60 |
option_state_dereference (&options, MDL); |
61 |
return; |
62 |
} |
63 |
//printf("Current Time is %s\n", ctime(&cur_time)); |
64 |
leaseTime = htonl(lease -> ends - cur_time); |
65 |
if (!make_const_data (&oc -> expression, (char*)&leaseTime, sizeof |
66 |
leaseTime, 0, 0, MDL)) { |
67 |
log_error ("No memory for expr_const expression."); |
68 |
option_cache_dereference (&oc, MDL); |
69 |
option_state_dereference (&options, MDL); |
70 |
return; |
71 |
} |
72 |
oc -> option = dhcp_universe.options [DHO_DHCP_LEASE_TIME]; |
73 |
save_option (&dhcp_universe, options, oc); |
74 |
option_cache_dereference (&oc, MDL); |
75 |
} |
76 |
|
77 |
// Set the relay agent info. |
78 |
if(lease -> agent_options) { |
79 |
pair p; |
80 |
int len = 0; |
81 |
char agent_options[255]; |
82 |
for (p = lease -> agent_options -> first; p; p = p -> cdr) { |
83 |
oc = (struct option_cache *)p -> car; |
84 |
if (oc -> data.len) { |
85 |
memcpy(&agent_options[len], (char*)&oc->option->code, 1); |
86 |
memcpy(&agent_options[len+1], (char*)&oc->data.len, 1); |
87 |
memcpy(&agent_options[len+2], oc->data.data, oc->data.len); |
88 |
len += oc -> data.len + 2; |
89 |
} |
90 |
} |
91 |
oc = (struct option_cache *)0; |
92 |
if (!option_cache_allocate (&oc, MDL)) { |
93 |
log_error ("No memory for lease time option."); |
94 |
option_state_dereference (&options, MDL); |
95 |
return; |
96 |
} |
97 |
if (!make_const_data (&oc -> expression, (char*)&agent_options, len, |
98 |
0, 0, MDL)) { |
99 |
log_error ("No memory for expr_const expression."); |
100 |
option_cache_dereference (&oc, MDL); |
101 |
option_state_dereference (&options, MDL); |
102 |
return; |
103 |
} |
104 |
oc -> option = dhcp_universe.options [DHO_DHCP_AGENT_OPTIONS]; |
105 |
save_option(&dhcp_universe, options, oc); |
106 |
option_cache_dereference (&oc, MDL); |
107 |
} |
108 |
|
109 |
} |
110 |
|
111 |
// Set the message type |
112 |
packet -> raw -> op = BOOTREPLY; |
113 |
|
114 |
// Set dhcp message type |
115 |
if (!option_cache_allocate (&oc, MDL)) { |
116 |
log_error ("No memory for dhcp message type."); |
117 |
option_state_dereference (&options, MDL); |
118 |
return; |
119 |
} |
120 |
if (!make_const_data (&oc -> expression, &dhcpMsgType, sizeof dhcpMsgType, |
121 |
0, 0, MDL)) { |
122 |
log_error ("No memory for expr_const expression."); |
123 |
option_cache_dereference (&oc, MDL); |
124 |
option_state_dereference (&options, MDL); |
125 |
return; |
126 |
} |
127 |
oc -> option = dhcp_universe.options [DHO_DHCP_MESSAGE_TYPE]; |
128 |
save_option (&dhcp_universe, options, oc); |
129 |
option_cache_dereference (&oc, MDL); |
130 |
|
131 |
|
132 |
|
133 |
#if 0 |
134 |
memset (&prl, 0, sizeof prl); |
135 |
|
136 |
/* Use the parameter list from the scope if there is one. */ |
137 |
oc = lookup_option (&dhcp_universe, options, |
138 |
DHO_DHCP_PARAMETER_REQUEST_LIST); |
139 |
|
140 |
/* Otherwise, if the client has provided a list of options |
141 |
that it wishes returned, use it to prioritize. Otherwise, |
142 |
prioritize based on the default priority list. */ |
143 |
|
144 |
if (!oc) |
145 |
oc = lookup_option (&dhcp_universe, packet -> options, |
146 |
DHO_DHCP_PARAMETER_REQUEST_LIST); |
147 |
|
148 |
if (oc) |
149 |
evaluate_option_cache (&prl, packet, (struct lease *)0, |
150 |
(struct client_state *)0, |
151 |
packet -> options, options, |
152 |
&global_scope, oc, MDL); |
153 |
|
154 |
//printf("Parameter Request List length is %d: %d, %d\n", prl.len, prl.data[0], prl.data[1]); |
155 |
|
156 |
/* Set up the option buffer... */ |
157 |
packet -> packet_length = cons_options (packet, raw, lease, |
158 |
(struct client_state *)0, |
159 |
0, packet -> options, options, |
160 |
&global_scope, |
161 |
0, 0, 0, |
162 |
prl.len ? &prl : (struct |
163 |
data_string *)0, |
164 |
(char *)0); |
165 |
#endif |
166 |
|
167 |
/* Set up the option buffer... */ |
168 |
packet -> packet_length = cons_options (packet, raw, lease, |
169 |
(struct client_state *)0, |
170 |
0, packet -> options, options, |
171 |
&global_scope, |
172 |
0, 0, 0, |
173 |
(struct data_string *)0, |
174 |
(char *)0); |
175 |
option_state_dereference (&options, MDL); |
176 |
|
177 |
to.sin_family = AF_INET; |
178 |
#ifdef HAVE_SA_LEN |
179 |
to.sin_len = sizeof to; |
180 |
#endif |
181 |
memset (to.sin_zero, 0, sizeof to.sin_zero); |
182 |
|
183 |
|
184 |
/* LEASEQUERY packets must be sent to gateway address */ |
185 |
if (packet -> raw -> giaddr.s_addr) { |
186 |
to.sin_addr = packet -> raw -> giaddr; |
187 |
if (packet -> raw -> giaddr.s_addr != htonl (INADDR_LOOPBACK)) { |
188 |
to.sin_port = local_port; |
189 |
} else { |
190 |
to.sin_port = remote_port; /* For debugging. */ |
191 |
} |
192 |
|
193 |
if (fallback_interface) { |
194 |
send_packet (fallback_interface, |
195 |
(struct packet *)0, |
196 |
packet -> raw, packet -> packet_length, |
197 |
packet -> raw -> siaddr, &to, |
198 |
(struct hardware *)0); |
199 |
|
200 |
} |
201 |
} |
202 |
} |