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" );
214 dhcpm
->op
= BOOTREPLY
;
215 dhcpm
->yiaddr
= dhcpl
.ip
;
216 dhcpm
->siaddr
= dhcpl
.siaddr
;
217 strcpy(dhcpm
->sname
, VERSION
);
218 dhcpm
->options
[pointer
++] = MESSAGETYPE
;
219 dhcpm
->options
[pointer
++] = 1;
220 dhcpm
->options
[pointer
++] = DHCPOFFER
;
221 dhcpm
->options
[pointer
++] = ROUTER
;
222 dhcpm
->options
[pointer
++] = 4;
223 dhcpm
->options
[pointer
++] = (dhcpl
.router
& 0xFF);
224 dhcpm
->options
[pointer
++] = ((dhcpl
.router
>> 8) & 0xFF);
225 dhcpm
->options
[pointer
++] = ((dhcpl
.router
>> 16) &0xFF);
226 dhcpm
->options
[pointer
++] = (dhcpl
.router
>> 24);
227 dhcpm
->options
[pointer
++] = MASK
;
228 dhcpm
->options
[pointer
++] = 4;
229 dhcpm
->options
[pointer
++] = (dhcpl
.mask
& 0xFF);
230 dhcpm
->options
[pointer
++] = ((dhcpl
.mask
>> 8) & 0xFF);
231 dhcpm
->options
[pointer
++] = ((dhcpl
.mask
>> 16) & 0xFF);
232 dhcpm
->options
[pointer
++] = (dhcpl
.mask
>> 24);
233 dhcpm
->options
[pointer
++] = SERVER
;
234 dhcpm
->options
[pointer
++] = 4;
235 dhcpm
->options
[pointer
++] = (dhcpl
.siaddr
& 0xFF);
236 dhcpm
->options
[pointer
++] = ((dhcpl
.siaddr
>> 8) & 0xFF);
237 dhcpm
->options
[pointer
++] = ((dhcpl
.siaddr
>> 16) & 0xFF);
238 dhcpm
->options
[pointer
++] = (dhcpl
.siaddr
>> 24);
239 dhcpm
->options
[pointer
++] = LEASE
;
240 dhcpm
->options
[pointer
++] = 4;
241 dhcpm
->options
[pointer
++] = (dhcpl
.lease
>> 24);
242 dhcpm
->options
[pointer
++] = ((dhcpl
.lease
>> 16) & 0xFF);
243 dhcpm
->options
[pointer
++] = ((dhcpl
.lease
>> 8) & 0xFF);
244 dhcpm
->options
[pointer
++] = (dhcpl
.lease
& 0xFF);
245 dhcpm
->options
[pointer
++] = REBINDING
;
246 dhcpm
->options
[pointer
++] = 4;
247 dhcpm
->options
[pointer
++] = (dhcpl
.lease
>> 24);
248 dhcpm
->options
[pointer
++] = ((dhcpl
.lease
>> 16) & 0xFF);
249 dhcpm
->options
[pointer
++] = ((dhcpl
.lease
>> 8) & 0xFF);
250 dhcpm
->options
[pointer
++] = (dhcpl
.lease
& 0xFF) - 5;
251 dhcpm
->options
[pointer
++] = RENEWALTIME
;
252 dhcpm
->options
[pointer
++] = 4;
253 dhcpm
->options
[pointer
++] = (dhcpl
.lease
>> 24);
254 dhcpm
->options
[pointer
++] = ((dhcpl
.lease
>> 16) & 0xFF);
255 dhcpm
->options
[pointer
++] = ((dhcpl
.lease
>> 8) & 0xFF);
256 dhcpm
->options
[pointer
++] = (dhcpl
.lease
& 0xFF) - 5;
257 dhcpm
->options
[pointer
++] = PAD
;
258 dhcpm
->options
[pointer
++] = PAD
;
259 dhcpm
->options
[pointer
++] = PAD
;
260 dhcpm
->options
[pointer
++] = END
;
261 for( ; pointer
< 312; pointer
++ )
262 dhcpm
->options
[pointer
] = PAD
;
263 dhcpo
->type
= DHCPOFFER
;
264 strcpy( name
, "255.255.255.255" );
268 /* We need to send an DHCPACK */
269 dhcpm
->op
= BOOTREPLY
;
270 dhcpm
->yiaddr
= dhcpm
->ciaddr
;
271 strcpy(dhcpm
->sname
, VERSION
);
272 if( confirm_lease( &dhcpl
, dhcpm
->xid
) < 0)
274 dhcpm
->options
[pointer
++] = MESSAGETYPE
;
275 dhcpm
->options
[pointer
++] = 1;
276 dhcpm
->options
[pointer
++] = DHCPNAK
;
277 dhcpm
->options
[pointer
++] = PAD
;
278 dhcpm
->options
[pointer
++] = END
;
279 for( ; pointer
< 312; pointer
++ )
280 dhcpm
->options
[pointer
] = PAD
;
281 sprintf( name
, "%u.%u.%u.%u", (dhcpm
->ciaddr
&0xFF), ((dhcpm
->ciaddr
>>8)&0xFF), ((dhcpm
->ciaddr
>>16)&0xFF), ((dhcpm
->ciaddr
>>24)&0xFF));
282 display_dhcp_packet( dhcpm
, dhcpo
);
283 write_packet( dhcpm
, name
);
286 dhcpm
->siaddr
= dhcpl
.siaddr
;
287 dhcpm
->options
[pointer
++] = MESSAGETYPE
;
288 dhcpm
->options
[pointer
++] = 1;
289 dhcpm
->options
[pointer
++] = DHCPACK
;
290 dhcpm
->options
[pointer
++] = ROUTER
;
291 dhcpm
->options
[pointer
++] = 4;
292 dhcpm
->options
[pointer
++] = (dhcpl
.router
>> 24);
293 dhcpm
->options
[pointer
++] = ((dhcpl
.router
>> 16) & 0xFF);
294 dhcpm
->options
[pointer
++] = ((dhcpl
.router
>> 8) &0xFF);
295 dhcpm
->options
[pointer
++] = (dhcpl
.router
& 0xFF);
296 dhcpm
->options
[pointer
++] = MASK
;
297 dhcpm
->options
[pointer
++] = 4;
298 dhcpm
->options
[pointer
++] = (dhcpl
.mask
>> 24);
299 dhcpm
->options
[pointer
++] = ((dhcpl
.mask
>> 16) & 0xFF);
300 dhcpm
->options
[pointer
++] = ((dhcpl
.mask
>> 8) & 0xFF);
301 dhcpm
->options
[pointer
++] = (dhcpl
.mask
& 0xFF);
302 dhcpm
->options
[pointer
++] = SERVER
;
303 dhcpm
->options
[pointer
++] = 4;
304 dhcpm
->options
[pointer
++] = dhcpl
.siaddr
>> 24;
305 dhcpm
->options
[pointer
++] = ((dhcpl
.siaddr
>> 16) & 0xFF);
306 dhcpm
->options
[pointer
++] = ((dhcpl
.siaddr
>> 8) & 0xFF);
307 dhcpm
->options
[pointer
++] = (dhcpl
.siaddr
& 0xFF);
308 dhcpm
->options
[pointer
++] = LEASE
;
309 dhcpm
->options
[pointer
++] = 4;
310 dhcpm
->options
[pointer
++] = (dhcpl
.lease
>> 24);
311 dhcpm
->options
[pointer
++] = ((dhcpl
.lease
>> 16) & 0xFF);
312 dhcpm
->options
[pointer
++] = ((dhcpl
.lease
>> 8) & 0xFF);
313 dhcpm
->options
[pointer
++] = (dhcpl
.lease
& 0xFF);
314 dhcpm
->options
[pointer
++] = REBINDING
;
315 dhcpm
->options
[pointer
++] = 4;
316 dhcpm
->options
[pointer
++] = (dhcpl
.lease
>> 24);
317 dhcpm
->options
[pointer
++] = ((dhcpl
.lease
>> 16) & 0xFF);
318 dhcpm
->options
[pointer
++] = ((dhcpl
.lease
>> 8) & 0xFF);
319 dhcpm
->options
[pointer
++] = (dhcpl
.lease
& 0xFF);
320 dhcpm
->options
[pointer
++] = RENEWALTIME
;
321 dhcpm
->options
[pointer
++] = 4;
322 dhcpm
->options
[pointer
++] = (dhcpl
.lease
>> 24);
323 dhcpm
->options
[pointer
++] = ((dhcpl
.lease
>> 16) & 0xFF);
324 dhcpm
->options
[pointer
++] = ((dhcpl
.lease
>> 8) & 0xFF);
325 dhcpm
->options
[pointer
++] = (dhcpl
.lease
& 0xFF);
326 dhcpm
->options
[pointer
++] = PAD
;
327 dhcpm
->options
[pointer
++] = PAD
;
328 dhcpm
->options
[pointer
++] = PAD
;
329 dhcpm
->options
[pointer
++] = END
;
330 for( ; pointer
< 312; pointer
++ )
331 dhcpm
->options
[pointer
] = PAD
;
332 dhcpo
->type
= DHCPACK
;
333 sprintf( name
, "%u.%u.%u.%u", (dhcpl
.ip
& 0xFF), ((dhcpl
.ip
>>8) & 0xFF), ((dhcpl
.ip
>>16)&0xFF), (dhcpl
.ip
>>24));
339 display_dhcp_packet( dhcpm
, dhcpo
);
340 write_packet( dhcpm
, name
);
341 fprintf( stdout
, "process_dhcp_packet [end]!\n");
345 int write_packet( DHCPMESSAGE
*dhcpm
, char *name
)
348 struct sockaddr_in their_addr
; // connector's address information
353 fprintf( stdout
, "write_packet [begin]\n" );
358 if ((sockfd
= socket(AF_INET
, SOCK_DGRAM
, 0)) == -1) {
363 if( setsockopt( sockfd
, SOL_SOCKET
, SO_BROADCAST
, &enable
, sizeof( enable
)) == -1 )
365 perror("setsockopt");
369 if( strcmp( "255.255.255.255", name
) )
371 if ((he
=gethostbyname(name
)) == NULL
) { // get the host info
372 perror("gethostbyname");
373 fprintf( stdout
, "Unknown host %s \n", name
);
376 their_addr
.sin_family
= AF_INET
; // host byte order
377 their_addr
.sin_port
= htons(68); // short, network byte order
378 their_addr
.sin_addr
= *((struct in_addr
*)he
->h_addr
);
380 their_addr
.sin_family
= AF_INET
; // host byte order
381 their_addr
.sin_port
= htons(68); // short, network byte order
382 their_addr
.sin_addr
.s_addr
= 0xFFFFFFFF;
385 fprintf( stdout
, "IP a buscar: %s \n", name
);
386 memset(&(their_addr
.sin_zero
), '\0', 8); // zero the rest of the struct
388 if ((numbytes
=sendto(sockfd
, dhcpm
, sizeof(DHCPMESSAGE
), 0,
389 (struct sockaddr
*)&their_addr
, sizeof(struct sockaddr
))) == -1) {
394 printf("sent %d bytes to %s\n", numbytes
,
395 inet_ntoa(their_addr
.sin_addr
));
399 fprintf( stdout
, "write_packet [end]\n" );