8 int parse_dhcp_options( DHCPMESSAGE
*dhcpm
, DHCPOPTIONS
*dhcpo
)
10 int pointer
, opointer
;
15 fprintf( stdout
, "parse_dhcp_options [begin]!\n");
17 /* Options Initialization */
20 /* No ip address, 0.0.0.0 */
22 /* No mask address, 0.0.0.0 */
24 /* No router, 0.0.0.0 */
29 dhcpo
->hostname
= NULL
;
33 if(( dhcpm
->options
[0] != 99 ) && (dhcpm
->options
[1]!=130) && (dhcpm
->options
[2]!=83) && (dhcpm
->options
[3]!= 99))
35 fprintf( stdout
, "No magic cookie! Aborting! \n" );
38 switch( dhcpm
->options
[pointer
] ){
43 /* Try to figure out the kind of message and start the configuring process */
45 dhcpo
->type
= dhcpm
->options
[pointer
++];
48 /* Take note of the requested parameters */
49 opointer
= pointer
+ 2;
50 olength
= pointer
+ dhcpm
->options
[pointer
+ 1];
51 while( opointer
< olength
)
53 switch( dhcpm
->options
[opointer
] ){
55 /* Take note of the requested ip */
57 dhcpo
->r_ip
+= dhcpm
->options
[opointer
++];
58 dhcpo
->r_ip
= dhcpo
->r_ip
<< 8;
59 dhcpo
->r_ip
+= dhcpm
->options
[opointer
++];
60 dhcpo
->r_ip
= dhcpo
->r_ip
<< 8;
61 dhcpo
->r_ip
+= dhcpm
->options
[opointer
++];
62 dhcpo
->r_ip
= dhcpo
->r_ip
<< 8;
63 dhcpo
->r_ip
+= dhcpm
->options
[opointer
++];
66 /* Take note of the requested mask */
68 dhcpo
->r_mask
+= dhcpm
->options
[opointer
++];
69 dhcpo
->r_mask
= dhcpo
->r_ip
<< 8;
70 dhcpo
->r_mask
+= dhcpm
->options
[opointer
++];
71 dhcpo
->r_mask
= dhcpo
->r_ip
<< 8;
72 dhcpo
->r_mask
+= dhcpm
->options
[opointer
++];
73 dhcpo
->r_mask
= dhcpo
->r_ip
<< 8;
74 dhcpo
->r_mask
+= dhcpm
->options
[opointer
++];
77 /* Take note of the requested router */
79 dhcpo
->r_router
+= dhcpm
->options
[opointer
++];
80 dhcpo
->r_router
= dhcpo
->r_ip
<< 8;
81 dhcpo
->r_router
+= dhcpm
->options
[opointer
++];
82 dhcpo
->r_router
= dhcpo
->r_ip
<< 8;
83 dhcpo
->r_router
+= dhcpm
->options
[opointer
++];
84 dhcpo
->r_router
= dhcpo
->r_ip
<< 8;
85 dhcpo
->r_router
+= dhcpm
->options
[opointer
++];
89 dhcpo
->r_lease
+= dhcpm
->options
[opointer
++];
90 dhcpo
->r_lease
= dhcpo
->r_ip
<< 8;
91 dhcpo
->r_lease
+= dhcpm
->options
[opointer
++];
92 dhcpo
->r_lease
= dhcpo
->r_ip
<< 8;
93 dhcpo
->r_lease
+= dhcpm
->options
[opointer
++];
94 dhcpo
->r_lease
= dhcpo
->r_ip
<< 8;
95 dhcpo
->r_lease
+= dhcpm
->options
[opointer
++];
99 dhcpo
->hostname
= (char *)malloc( dhcpm
->options
[opointer
] + 1);
100 strncpy( dhcpo
->hostname
, &dhcpm
->options
[opointer
+1], dhcpm
->options
[opointer
] );
101 opointer
+= dhcpm
->options
[opointer
] + 1;
178 pointer
+= dhcpm
->options
[pointer
];
180 /* return to the calling functions because this is over */
181 fprintf( stdout
, "parse_dhcp_options: END option found! [end]!\n");
189 fprintf( stdout
, "parse_dhcp_options [end]!\n");
193 int process_dhcp_packet( DHCPMESSAGE
*dhcpm
, DHCPOPTIONS
*dhcpo
)
199 fprintf( stdout
, "process_dhcp_packet [begin]!\n");
201 if( (!dhcpm
) || (!dhcpo
) )
204 name
= (char *)malloc( 16 );
205 switch( dhcpo
->type
){
208 /* We need to send a DHCPOFFER */
209 if( find_lease( &dhcpl
, dhcpm
->xid
, dhcpm
->chaddr
) < 0 )
211 fprintf( stdout
, "No free leases! \n" );
215 dhcpm
->op
= BOOTREPLY
;
216 dhcpm
->yiaddr
= dhcpl
.ip
;
217 dhcpm
->siaddr
= dhcpl
.siaddr
;
218 strcpy(dhcpm
->sname
, VERSION
);
219 dhcpm
->options
[pointer
++] = MESSAGETYPE
;
220 dhcpm
->options
[pointer
++] = 1;
221 dhcpm
->options
[pointer
++] = DHCPOFFER
;
222 dhcpm
->options
[pointer
++] = ROUTER
;
223 dhcpm
->options
[pointer
++] = 4;
224 dhcpm
->options
[pointer
++] = (dhcpl
.router
& 0xFF);
225 dhcpm
->options
[pointer
++] = ((dhcpl
.router
>> 8) & 0xFF);
226 dhcpm
->options
[pointer
++] = ((dhcpl
.router
>> 16) &0xFF);
227 dhcpm
->options
[pointer
++] = (dhcpl
.router
>> 24);
228 dhcpm
->options
[pointer
++] = MASK
;
229 dhcpm
->options
[pointer
++] = 4;
230 dhcpm
->options
[pointer
++] = (dhcpl
.mask
& 0xFF);
231 dhcpm
->options
[pointer
++] = ((dhcpl
.mask
>> 8) & 0xFF);
232 dhcpm
->options
[pointer
++] = ((dhcpl
.mask
>> 16) & 0xFF);
233 dhcpm
->options
[pointer
++] = (dhcpl
.mask
>> 24);
234 dhcpm
->options
[pointer
++] = SERVER
;
235 dhcpm
->options
[pointer
++] = 4;
236 dhcpm
->options
[pointer
++] = (dhcpl
.siaddr
& 0xFF);
237 dhcpm
->options
[pointer
++] = ((dhcpl
.siaddr
>> 8) & 0xFF);
238 dhcpm
->options
[pointer
++] = ((dhcpl
.siaddr
>> 16) & 0xFF);
239 dhcpm
->options
[pointer
++] = (dhcpl
.siaddr
>> 24);
240 dhcpm
->options
[pointer
++] = LEASE
;
241 dhcpm
->options
[pointer
++] = 4;
242 dhcpm
->options
[pointer
++] = (dhcpl
.lease
>> 24);
243 dhcpm
->options
[pointer
++] = ((dhcpl
.lease
>> 16) & 0xFF);
244 dhcpm
->options
[pointer
++] = ((dhcpl
.lease
>> 8) & 0xFF);
245 dhcpm
->options
[pointer
++] = (dhcpl
.lease
& 0xFF);
246 dhcpm
->options
[pointer
++] = REBINDING
;
247 dhcpm
->options
[pointer
++] = 4;
248 dhcpm
->options
[pointer
++] = (dhcpl
.lease
>> 24);
249 dhcpm
->options
[pointer
++] = ((dhcpl
.lease
>> 16) & 0xFF);
250 dhcpm
->options
[pointer
++] = ((dhcpl
.lease
>> 8) & 0xFF);
251 dhcpm
->options
[pointer
++] = (dhcpl
.lease
& 0xFF) - 5;
252 dhcpm
->options
[pointer
++] = RENEWALTIME
;
253 dhcpm
->options
[pointer
++] = 4;
254 dhcpm
->options
[pointer
++] = (dhcpl
.lease
>> 24);
255 dhcpm
->options
[pointer
++] = ((dhcpl
.lease
>> 16) & 0xFF);
256 dhcpm
->options
[pointer
++] = ((dhcpl
.lease
>> 8) & 0xFF);
257 dhcpm
->options
[pointer
++] = (dhcpl
.lease
& 0xFF) - 5;
258 dhcpm
->options
[pointer
++] = PAD
;
259 dhcpm
->options
[pointer
++] = PAD
;
260 dhcpm
->options
[pointer
++] = PAD
;
261 dhcpm
->options
[pointer
++] = END
;
262 for( ; pointer
< 312; pointer
++ )
263 dhcpm
->options
[pointer
] = PAD
;
264 dhcpo
->type
= DHCPOFFER
;
265 strcpy( name
, "255.255.255.255" );
269 /* We need to send an DHCPACK */
270 dhcpm
->op
= BOOTREPLY
;
271 dhcpm
->yiaddr
= dhcpm
->ciaddr
;
272 strcpy(dhcpm
->sname
, VERSION
);
273 if( confirm_lease( &dhcpl
, dhcpm
->xid
) < 0)
275 dhcpm
->options
[pointer
++] = MESSAGETYPE
;
276 dhcpm
->options
[pointer
++] = 1;
277 dhcpm
->options
[pointer
++] = DHCPNAK
;
278 dhcpm
->options
[pointer
++] = PAD
;
279 dhcpm
->options
[pointer
++] = END
;
280 for( ; pointer
< 312; pointer
++ )
281 dhcpm
->options
[pointer
] = PAD
;
282 sprintf( name
, "%u.%u.%u.%u", (dhcpm
->ciaddr
&0xFF), ((dhcpm
->ciaddr
>>8)&0xFF), ((dhcpm
->ciaddr
>>16)&0xFF), ((dhcpm
->ciaddr
>>24)&0xFF));
283 display_dhcp_packet( dhcpm
, dhcpo
);
284 write_packet( dhcpm
, name
);
288 dhcpm
->siaddr
= dhcpl
.siaddr
;
289 dhcpm
->options
[pointer
++] = MESSAGETYPE
;
290 dhcpm
->options
[pointer
++] = 1;
291 dhcpm
->options
[pointer
++] = DHCPACK
;
292 dhcpm
->options
[pointer
++] = ROUTER
;
293 dhcpm
->options
[pointer
++] = 4;
294 dhcpm
->options
[pointer
++] = (dhcpl
.router
>> 24);
295 dhcpm
->options
[pointer
++] = ((dhcpl
.router
>> 16) & 0xFF);
296 dhcpm
->options
[pointer
++] = ((dhcpl
.router
>> 8) &0xFF);
297 dhcpm
->options
[pointer
++] = (dhcpl
.router
& 0xFF);
298 dhcpm
->options
[pointer
++] = MASK
;
299 dhcpm
->options
[pointer
++] = 4;
300 dhcpm
->options
[pointer
++] = (dhcpl
.mask
>> 24);
301 dhcpm
->options
[pointer
++] = ((dhcpl
.mask
>> 16) & 0xFF);
302 dhcpm
->options
[pointer
++] = ((dhcpl
.mask
>> 8) & 0xFF);
303 dhcpm
->options
[pointer
++] = (dhcpl
.mask
& 0xFF);
304 dhcpm
->options
[pointer
++] = SERVER
;
305 dhcpm
->options
[pointer
++] = 4;
306 dhcpm
->options
[pointer
++] = dhcpl
.siaddr
>> 24;
307 dhcpm
->options
[pointer
++] = ((dhcpl
.siaddr
>> 16) & 0xFF);
308 dhcpm
->options
[pointer
++] = ((dhcpl
.siaddr
>> 8) & 0xFF);
309 dhcpm
->options
[pointer
++] = (dhcpl
.siaddr
& 0xFF);
310 dhcpm
->options
[pointer
++] = LEASE
;
311 dhcpm
->options
[pointer
++] = 4;
312 dhcpm
->options
[pointer
++] = (dhcpl
.lease
>> 24);
313 dhcpm
->options
[pointer
++] = ((dhcpl
.lease
>> 16) & 0xFF);
314 dhcpm
->options
[pointer
++] = ((dhcpl
.lease
>> 8) & 0xFF);
315 dhcpm
->options
[pointer
++] = (dhcpl
.lease
& 0xFF);
316 dhcpm
->options
[pointer
++] = REBINDING
;
317 dhcpm
->options
[pointer
++] = 4;
318 dhcpm
->options
[pointer
++] = (dhcpl
.lease
>> 24);
319 dhcpm
->options
[pointer
++] = ((dhcpl
.lease
>> 16) & 0xFF);
320 dhcpm
->options
[pointer
++] = ((dhcpl
.lease
>> 8) & 0xFF);
321 dhcpm
->options
[pointer
++] = (dhcpl
.lease
& 0xFF);
322 dhcpm
->options
[pointer
++] = RENEWALTIME
;
323 dhcpm
->options
[pointer
++] = 4;
324 dhcpm
->options
[pointer
++] = (dhcpl
.lease
>> 24);
325 dhcpm
->options
[pointer
++] = ((dhcpl
.lease
>> 16) & 0xFF);
326 dhcpm
->options
[pointer
++] = ((dhcpl
.lease
>> 8) & 0xFF);
327 dhcpm
->options
[pointer
++] = (dhcpl
.lease
& 0xFF);
328 dhcpm
->options
[pointer
++] = PAD
;
329 dhcpm
->options
[pointer
++] = PAD
;
330 dhcpm
->options
[pointer
++] = PAD
;
331 dhcpm
->options
[pointer
++] = END
;
332 for( ; pointer
< 312; pointer
++ )
333 dhcpm
->options
[pointer
] = PAD
;
334 dhcpo
->type
= DHCPACK
;
335 sprintf( name
, "%u.%u.%u.%u", (dhcpl
.ip
& 0xFF), ((dhcpl
.ip
>>8) & 0xFF), ((dhcpl
.ip
>>16)&0xFF), (dhcpl
.ip
>>24));
341 display_dhcp_packet( dhcpm
, dhcpo
);
342 write_packet( dhcpm
, name
);
343 fprintf( stdout
, "process_dhcp_packet [end]!\n");
348 int write_packet( DHCPMESSAGE
*dhcpm
, char *name
)
351 struct sockaddr_in their_addr
; // connector's address information
356 fprintf( stdout
, "write_packet [begin]\n" );
361 if ((sockfd
= socket(AF_INET
, SOCK_DGRAM
, 0)) == -1) {
366 if( setsockopt( sockfd
, SOL_SOCKET
, SO_BROADCAST
, &enable
, sizeof( enable
)) == -1 )
368 perror("setsockopt");
372 if( strcmp( "255.255.255.255", name
) )
374 if ((he
=gethostbyname(name
)) == NULL
) { // get the host info
375 perror("gethostbyname");
376 fprintf( stdout
, "Unknown host %s \n", name
);
379 their_addr
.sin_family
= AF_INET
; // host byte order
380 their_addr
.sin_port
= htons(68); // short, network byte order
381 their_addr
.sin_addr
= *((struct in_addr
*)he
->h_addr
);
383 their_addr
.sin_family
= AF_INET
; // host byte order
384 their_addr
.sin_port
= htons(68); // short, network byte order
385 their_addr
.sin_addr
.s_addr
= 0xFFFFFFFF;
388 fprintf( stdout
, "IP a buscar: %s \n", name
);
389 memset(&(their_addr
.sin_zero
), '\0', 8); // zero the rest of the struct
391 if ((numbytes
=sendto(sockfd
, dhcpm
, sizeof(DHCPMESSAGE
), 0,
392 (struct sockaddr
*)&their_addr
, sizeof(struct sockaddr
))) == -1) {
397 printf("sent %d bytes to %s\n", numbytes
,
398 inet_ntoa(their_addr
.sin_addr
));
402 fprintf( stdout
, "write_packet [end]\n" );