1*c2c66affSColin Finck #include <headers.h>
2*c2c66affSColin Finck #include <datatypes.h>
3*c2c66affSColin Finck #include <display.h>
4*c2c66affSColin Finck #include <parser.h>
5*c2c66affSColin Finck #include <leases.h>
6*c2c66affSColin Finck #include <options.h>
7*c2c66affSColin Finck 
parse_dhcp_options(DHCPMESSAGE * dhcpm,DHCPOPTIONS * dhcpo)8*c2c66affSColin Finck int parse_dhcp_options( DHCPMESSAGE *dhcpm, DHCPOPTIONS *dhcpo )
9*c2c66affSColin Finck {
10*c2c66affSColin Finck   int pointer, opointer;
11*c2c66affSColin Finck   int olength;
12*c2c66affSColin Finck 
13*c2c66affSColin Finck   pointer = 0;
14*c2c66affSColin Finck 
15*c2c66affSColin Finck   fprintf( stdout, "parse_dhcp_options [begin]!\n");
16*c2c66affSColin Finck 
17*c2c66affSColin Finck   /* Options Initialization */
18*c2c66affSColin Finck   /* No message type */
19*c2c66affSColin Finck   dhcpo->type = 0;
20*c2c66affSColin Finck   /* No ip address, 0.0.0.0 */
21*c2c66affSColin Finck   dhcpo->r_ip = 0;
22*c2c66affSColin Finck   /* No mask address, 0.0.0.0 */
23*c2c66affSColin Finck   dhcpo->r_mask = 0;
24*c2c66affSColin Finck   /* No router, 0.0.0.0 */
25*c2c66affSColin Finck   dhcpo->r_router = 0;
26*c2c66affSColin Finck   /* No lease 0 */
27*c2c66affSColin Finck   dhcpo->r_lease = 0;
28*c2c66affSColin Finck   /* No name '\n' */
29*c2c66affSColin Finck   dhcpo->hostname = NULL;
30*c2c66affSColin Finck 
31*c2c66affSColin Finck   while( pointer< 312 )
32*c2c66affSColin Finck     {
33*c2c66affSColin Finck       if(( dhcpm->options[0] != 99 ) && (dhcpm->options[1]!=130) && (dhcpm->options[2]!=83) && (dhcpm->options[3]!= 99))
34*c2c66affSColin Finck 	{
35*c2c66affSColin Finck 	  fprintf( stdout, "No magic cookie! Aborting! \n" );
36*c2c66affSColin Finck 	  return -1;
37*c2c66affSColin Finck 	}
38*c2c66affSColin Finck       switch( dhcpm->options[pointer] ){
39*c2c66affSColin Finck       case PAD:
40*c2c66affSColin Finck 	pointer++;
41*c2c66affSColin Finck 	break;
42*c2c66affSColin Finck       case MESSAGETYPE:
43*c2c66affSColin Finck 	/* Try to figure out the kind of message and start the configuring process */
44*c2c66affSColin Finck 	pointer += 2;
45*c2c66affSColin Finck 	dhcpo->type = dhcpm->options[pointer++];
46*c2c66affSColin Finck 	break;
47*c2c66affSColin Finck       case PREQUEST:
48*c2c66affSColin Finck 	/* Take note of the requested parameters */
49*c2c66affSColin Finck 	opointer = pointer + 2;
50*c2c66affSColin Finck 	olength = pointer + dhcpm->options[pointer + 1];
51*c2c66affSColin Finck 	while( opointer < olength )
52*c2c66affSColin Finck 	  {
53*c2c66affSColin Finck 	    switch( dhcpm->options[opointer] ){
54*c2c66affSColin Finck 	    case IP:
55*c2c66affSColin Finck 	      /* Take note of the requested ip */
56*c2c66affSColin Finck 	      opointer += 2;
57*c2c66affSColin Finck 	      dhcpo->r_ip += dhcpm->options[opointer++];
58*c2c66affSColin Finck 	      dhcpo->r_ip = dhcpo->r_ip << 8;
59*c2c66affSColin Finck 	      dhcpo->r_ip += dhcpm->options[opointer++];
60*c2c66affSColin Finck 	      dhcpo->r_ip = dhcpo->r_ip << 8;
61*c2c66affSColin Finck 	      dhcpo->r_ip += dhcpm->options[opointer++];
62*c2c66affSColin Finck 	      dhcpo->r_ip = dhcpo->r_ip << 8;
63*c2c66affSColin Finck 	      dhcpo->r_ip += dhcpm->options[opointer++];
64*c2c66affSColin Finck 	      break;
65*c2c66affSColin Finck 	    case MASK:
66*c2c66affSColin Finck 	      /* Take note of the requested mask */
67*c2c66affSColin Finck 	      opointer += 2;
68*c2c66affSColin Finck 	      dhcpo->r_mask += dhcpm->options[opointer++];
69*c2c66affSColin Finck 	      dhcpo->r_mask = dhcpo->r_ip << 8;
70*c2c66affSColin Finck 	      dhcpo->r_mask += dhcpm->options[opointer++];
71*c2c66affSColin Finck 	      dhcpo->r_mask = dhcpo->r_ip << 8;
72*c2c66affSColin Finck 	      dhcpo->r_mask += dhcpm->options[opointer++];
73*c2c66affSColin Finck 	      dhcpo->r_mask = dhcpo->r_ip << 8;
74*c2c66affSColin Finck 	      dhcpo->r_mask += dhcpm->options[opointer++];
75*c2c66affSColin Finck 	      break;
76*c2c66affSColin Finck 	    case ROUTER:
77*c2c66affSColin Finck 	      /* Take note of the requested router */
78*c2c66affSColin Finck 	      opointer += 2;
79*c2c66affSColin Finck 	      dhcpo->r_router += dhcpm->options[opointer++];
80*c2c66affSColin Finck 	      dhcpo->r_router = dhcpo->r_ip << 8;
81*c2c66affSColin Finck 	      dhcpo->r_router += dhcpm->options[opointer++];
82*c2c66affSColin Finck 	      dhcpo->r_router = dhcpo->r_ip << 8;
83*c2c66affSColin Finck 	      dhcpo->r_router += dhcpm->options[opointer++];
84*c2c66affSColin Finck 	      dhcpo->r_router = dhcpo->r_ip << 8;
85*c2c66affSColin Finck 	      dhcpo->r_router += dhcpm->options[opointer++];
86*c2c66affSColin Finck 	      break;
87*c2c66affSColin Finck 	    case LEASE:
88*c2c66affSColin Finck 	      opointer += 2;
89*c2c66affSColin Finck 	      dhcpo->r_lease += dhcpm->options[opointer++];
90*c2c66affSColin Finck 	      dhcpo->r_lease = dhcpo->r_ip << 8;
91*c2c66affSColin Finck 	      dhcpo->r_lease += dhcpm->options[opointer++];
92*c2c66affSColin Finck 	      dhcpo->r_lease = dhcpo->r_ip << 8;
93*c2c66affSColin Finck 	      dhcpo->r_lease += dhcpm->options[opointer++];
94*c2c66affSColin Finck 	      dhcpo->r_lease = dhcpo->r_ip << 8;
95*c2c66affSColin Finck 	      dhcpo->r_lease += dhcpm->options[opointer++];
96*c2c66affSColin Finck 	      break;
97*c2c66affSColin Finck 	    case HOSTNAME:
98*c2c66affSColin Finck 	      opointer += 1;
99*c2c66affSColin Finck 	      dhcpo->hostname = (char *)malloc( dhcpm->options[opointer] + 1);
100*c2c66affSColin Finck 	      strncpy( dhcpo->hostname, &dhcpm->options[opointer+1], dhcpm->options[opointer] );
101*c2c66affSColin Finck 	      opointer += dhcpm->options[opointer] + 1;
102*c2c66affSColin Finck 	    default:
103*c2c66affSColin Finck 	      /* Ignore option */
104*c2c66affSColin Finck 	      opointer++;
105*c2c66affSColin Finck 	      break;
106*c2c66affSColin Finck 	    }
107*c2c66affSColin Finck 	  }
108*c2c66affSColin Finck 	pointer = opointer;
109*c2c66affSColin Finck 	break;
110*c2c66affSColin Finck       case  TOFFSET:
111*c2c66affSColin Finck       case  TIMESERVER:
112*c2c66affSColin Finck       case  NS:
113*c2c66affSColin Finck       case  DNS:
114*c2c66affSColin Finck       case  LOGSERVER:
115*c2c66affSColin Finck       case  COOKIESERVER:
116*c2c66affSColin Finck       case  LPRSERVER:
117*c2c66affSColin Finck       case  IMPSERVER:
118*c2c66affSColin Finck       case  RESLOCSERVER:
119*c2c66affSColin Finck       case  BOOTFILESIZE:
120*c2c66affSColin Finck       case  MERITDUMPFILE:
121*c2c66affSColin Finck       case  DOMAINNAME:
122*c2c66affSColin Finck       case  SWAPSERVER:
123*c2c66affSColin Finck       case  ROOTPATH:
124*c2c66affSColin Finck       case  EXTENSIONPATH:
125*c2c66affSColin Finck       case  IPFORWARD:
126*c2c66affSColin Finck       case  NONLOCAL:
127*c2c66affSColin Finck       case  POLICYFILTER:
128*c2c66affSColin Finck       case  MAXIMUMDATAG:
129*c2c66affSColin Finck       case  DEFAULTTTL:
130*c2c66affSColin Finck       case  PATHMTUATO:
131*c2c66affSColin Finck       case  PATHMTUPTO:
132*c2c66affSColin Finck       case  IMTU:
133*c2c66affSColin Finck       case  ALLSUBLOCAL:
134*c2c66affSColin Finck       case  BROADCAST:
135*c2c66affSColin Finck       case  PMASKDISCOVERY:
136*c2c66affSColin Finck       case  MASKSUPPLIER:
137*c2c66affSColin Finck       case  PROUTERDISCOVE:
138*c2c66affSColin Finck       case  RSOLICIADDRESS:
139*c2c66affSColin Finck       case  STATICROUTE:
140*c2c66affSColin Finck       case  TENCAPSULATION:
141*c2c66affSColin Finck       case  ARPCACHE:
142*c2c66affSColin Finck       case  ETHENCAPSUL:
143*c2c66affSColin Finck       case  TCPDEFTTL:
144*c2c66affSColin Finck       case  TCPKAI:
145*c2c66affSColin Finck       case  TCPKAG:
146*c2c66affSColin Finck       case  NISDOMAIN:
147*c2c66affSColin Finck       case  NISSERVER:
148*c2c66affSColin Finck       case  NTPSERVER:
149*c2c66affSColin Finck       case  VENDORSP:
150*c2c66affSColin Finck       case  NBTCPIPNS:
151*c2c66affSColin Finck       case  NBTCPIPDDS:
152*c2c66affSColin Finck       case  NBTCPIPNT:
153*c2c66affSColin Finck       case  NBTCPIPSC:
154*c2c66affSColin Finck       case  XWINFONTSERVER:
155*c2c66affSColin Finck       case  XWINDISPLAY:
156*c2c66affSColin Finck       case  OVERLOAD:
157*c2c66affSColin Finck       case  SERVER:
158*c2c66affSColin Finck       case  MESSAGE:
159*c2c66affSColin Finck       case  MAXIMUMDHCP:
160*c2c66affSColin Finck       case  RENEWALTIME:
161*c2c66affSColin Finck       case  REBINDING:
162*c2c66affSColin Finck       case  VENDORCLASS:
163*c2c66affSColin Finck       case  NISPLUSDOMAIN:
164*c2c66affSColin Finck       case  NISPLUSSERVER:
165*c2c66affSColin Finck       case  TFTPSERVER:
166*c2c66affSColin Finck       case  BOOTFILE:
167*c2c66affSColin Finck       case  MOBILEIP:
168*c2c66affSColin Finck       case  SMTPSERVER:
169*c2c66affSColin Finck       case  POP3SERVER:
170*c2c66affSColin Finck       case  NNTPSERVER:
171*c2c66affSColin Finck       case  HTTPSERVER:
172*c2c66affSColin Finck       case  FINGERSERVER:
173*c2c66affSColin Finck       case  IRCSERVER:
174*c2c66affSColin Finck       case  STREETTALKSE:
175*c2c66affSColin Finck       case  STREETTALKDA:
176*c2c66affSColin Finck       case CLIENT:
177*c2c66affSColin Finck 	pointer++;
178*c2c66affSColin Finck 	pointer += dhcpm->options[pointer];
179*c2c66affSColin Finck       case END:
180*c2c66affSColin Finck 	/* return to the calling functions because this is over */
181*c2c66affSColin Finck 	fprintf( stdout, "parse_dhcp_options: END option found! [end]!\n");
182*c2c66affSColin Finck 	return 0;
183*c2c66affSColin Finck       default:
184*c2c66affSColin Finck 	/* ignored */
185*c2c66affSColin Finck 	pointer++;
186*c2c66affSColin Finck 	break;
187*c2c66affSColin Finck       }
188*c2c66affSColin Finck     }
189*c2c66affSColin Finck   fprintf( stdout, "parse_dhcp_options [end]!\n");
190*c2c66affSColin Finck   return 0;
191*c2c66affSColin Finck }
192*c2c66affSColin Finck 
process_dhcp_packet(DHCPMESSAGE * dhcpm,DHCPOPTIONS * dhcpo)193*c2c66affSColin Finck int process_dhcp_packet( DHCPMESSAGE *dhcpm, DHCPOPTIONS *dhcpo )
194*c2c66affSColin Finck {
195*c2c66affSColin Finck   int pointer = 4;
196*c2c66affSColin Finck   DHCPLEASE dhcpl;
197*c2c66affSColin Finck   char *name;
198*c2c66affSColin Finck 
199*c2c66affSColin Finck   fprintf( stdout, "process_dhcp_packet [begin]!\n");
200*c2c66affSColin Finck 
201*c2c66affSColin Finck   if( (!dhcpm) || (!dhcpo) )
202*c2c66affSColin Finck     return -1;
203*c2c66affSColin Finck 
204*c2c66affSColin Finck   name = (char *)malloc( 16 );
205*c2c66affSColin Finck   switch( dhcpo->type ){
206*c2c66affSColin Finck 
207*c2c66affSColin Finck   case DHCPDISCOVER:
208*c2c66affSColin Finck     /* We need to send a DHCPOFFER */
209*c2c66affSColin Finck     if( find_lease( &dhcpl, dhcpm->xid, dhcpm->chaddr ) < 0 )
210*c2c66affSColin Finck       {
211*c2c66affSColin Finck 	fprintf( stdout, "No free leases! \n" );
212*c2c66affSColin Finck 	free( name );
213*c2c66affSColin Finck 	return -1;
214*c2c66affSColin Finck       }
215*c2c66affSColin Finck     dhcpm->op = BOOTREPLY;
216*c2c66affSColin Finck     dhcpm->yiaddr = dhcpl.ip;
217*c2c66affSColin Finck     dhcpm->siaddr = dhcpl.siaddr;
218*c2c66affSColin Finck     strcpy(dhcpm->sname, VERSION);
219*c2c66affSColin Finck     dhcpm->options[pointer++] = MESSAGETYPE;
220*c2c66affSColin Finck     dhcpm->options[pointer++] = 1;
221*c2c66affSColin Finck     dhcpm->options[pointer++] = DHCPOFFER;
222*c2c66affSColin Finck     dhcpm->options[pointer++] = ROUTER;
223*c2c66affSColin Finck     dhcpm->options[pointer++] = 4;
224*c2c66affSColin Finck     dhcpm->options[pointer++] = (dhcpl.router & 0xFF);
225*c2c66affSColin Finck     dhcpm->options[pointer++] = ((dhcpl.router >> 8) & 0xFF);
226*c2c66affSColin Finck     dhcpm->options[pointer++] = ((dhcpl.router >> 16) &0xFF);
227*c2c66affSColin Finck     dhcpm->options[pointer++] = (dhcpl.router >> 24);
228*c2c66affSColin Finck     dhcpm->options[pointer++] = MASK;
229*c2c66affSColin Finck     dhcpm->options[pointer++] = 4;
230*c2c66affSColin Finck     dhcpm->options[pointer++] = (dhcpl.mask & 0xFF);
231*c2c66affSColin Finck     dhcpm->options[pointer++] = ((dhcpl.mask >> 8) & 0xFF);
232*c2c66affSColin Finck     dhcpm->options[pointer++] = ((dhcpl.mask >> 16) & 0xFF);
233*c2c66affSColin Finck     dhcpm->options[pointer++] = (dhcpl.mask >> 24);
234*c2c66affSColin Finck     dhcpm->options[pointer++] = SERVER;
235*c2c66affSColin Finck     dhcpm->options[pointer++] = 4;
236*c2c66affSColin Finck     dhcpm->options[pointer++] = (dhcpl.siaddr & 0xFF);
237*c2c66affSColin Finck     dhcpm->options[pointer++] = ((dhcpl.siaddr >> 8) & 0xFF);
238*c2c66affSColin Finck     dhcpm->options[pointer++] = ((dhcpl.siaddr >> 16) & 0xFF);
239*c2c66affSColin Finck     dhcpm->options[pointer++] = (dhcpl.siaddr >> 24);
240*c2c66affSColin Finck     dhcpm->options[pointer++] = LEASE;
241*c2c66affSColin Finck     dhcpm->options[pointer++] = 4;
242*c2c66affSColin Finck     dhcpm->options[pointer++] = (dhcpl.lease >> 24);
243*c2c66affSColin Finck     dhcpm->options[pointer++] = ((dhcpl.lease >> 16) & 0xFF);
244*c2c66affSColin Finck     dhcpm->options[pointer++] = ((dhcpl.lease >> 8) & 0xFF);
245*c2c66affSColin Finck     dhcpm->options[pointer++] = (dhcpl.lease & 0xFF);
246*c2c66affSColin Finck     dhcpm->options[pointer++] = REBINDING;
247*c2c66affSColin Finck     dhcpm->options[pointer++] = 4;
248*c2c66affSColin Finck     dhcpm->options[pointer++] = (dhcpl.lease >> 24);
249*c2c66affSColin Finck     dhcpm->options[pointer++] = ((dhcpl.lease >> 16) & 0xFF);
250*c2c66affSColin Finck     dhcpm->options[pointer++] = ((dhcpl.lease >> 8) & 0xFF);
251*c2c66affSColin Finck     dhcpm->options[pointer++] = (dhcpl.lease & 0xFF) - 5;
252*c2c66affSColin Finck     dhcpm->options[pointer++] = RENEWALTIME;
253*c2c66affSColin Finck     dhcpm->options[pointer++] = 4;
254*c2c66affSColin Finck     dhcpm->options[pointer++] = (dhcpl.lease >> 24);
255*c2c66affSColin Finck     dhcpm->options[pointer++] = ((dhcpl.lease >> 16) & 0xFF);
256*c2c66affSColin Finck     dhcpm->options[pointer++] = ((dhcpl.lease >> 8) & 0xFF);
257*c2c66affSColin Finck     dhcpm->options[pointer++] = (dhcpl.lease & 0xFF) - 5;
258*c2c66affSColin Finck     dhcpm->options[pointer++] = PAD;
259*c2c66affSColin Finck     dhcpm->options[pointer++] = PAD;
260*c2c66affSColin Finck     dhcpm->options[pointer++] = PAD;
261*c2c66affSColin Finck     dhcpm->options[pointer++] = END;
262*c2c66affSColin Finck     for( ; pointer < 312; pointer++ )
263*c2c66affSColin Finck       dhcpm->options[pointer] = PAD;
264*c2c66affSColin Finck     dhcpo->type = DHCPOFFER;
265*c2c66affSColin Finck     strcpy( name, "255.255.255.255" );
266*c2c66affSColin Finck     break;
267*c2c66affSColin Finck 
268*c2c66affSColin Finck   case DHCPREQUEST:
269*c2c66affSColin Finck     /* We need to send an DHCPACK */
270*c2c66affSColin Finck     dhcpm->op = BOOTREPLY;
271*c2c66affSColin Finck     dhcpm->yiaddr = dhcpm->ciaddr;
272*c2c66affSColin Finck     strcpy(dhcpm->sname, VERSION);
273*c2c66affSColin Finck     if( confirm_lease( &dhcpl, dhcpm->xid ) < 0)
274*c2c66affSColin Finck       {
275*c2c66affSColin Finck 	dhcpm->options[pointer++] = MESSAGETYPE;
276*c2c66affSColin Finck 	dhcpm->options[pointer++] = 1;
277*c2c66affSColin Finck 	dhcpm->options[pointer++] = DHCPNAK;
278*c2c66affSColin Finck 	dhcpm->options[pointer++] = PAD;
279*c2c66affSColin Finck 	dhcpm->options[pointer++] = END;
280*c2c66affSColin Finck 	for( ; pointer < 312; pointer++ )
281*c2c66affSColin Finck 	  dhcpm->options[pointer] = PAD;
282*c2c66affSColin Finck 	sprintf( name, "%u.%u.%u.%u", (dhcpm->ciaddr &0xFF), ((dhcpm->ciaddr>>8)&0xFF), ((dhcpm->ciaddr>>16)&0xFF), ((dhcpm->ciaddr>>24)&0xFF));
283*c2c66affSColin Finck 	display_dhcp_packet( dhcpm, dhcpo );
284*c2c66affSColin Finck 	write_packet( dhcpm, name );
285*c2c66affSColin Finck 	free( name );
286*c2c66affSColin Finck 	return -1;
287*c2c66affSColin Finck       }
288*c2c66affSColin Finck     dhcpm->siaddr = dhcpl.siaddr;
289*c2c66affSColin Finck     dhcpm->options[pointer++] = MESSAGETYPE;
290*c2c66affSColin Finck     dhcpm->options[pointer++] = 1;
291*c2c66affSColin Finck     dhcpm->options[pointer++] = DHCPACK;
292*c2c66affSColin Finck     dhcpm->options[pointer++] = ROUTER;
293*c2c66affSColin Finck     dhcpm->options[pointer++] = 4;
294*c2c66affSColin Finck     dhcpm->options[pointer++] = (dhcpl.router >> 24);
295*c2c66affSColin Finck     dhcpm->options[pointer++] = ((dhcpl.router >> 16) & 0xFF);
296*c2c66affSColin Finck     dhcpm->options[pointer++] = ((dhcpl.router >> 8) &0xFF);
297*c2c66affSColin Finck     dhcpm->options[pointer++] = (dhcpl.router & 0xFF);
298*c2c66affSColin Finck     dhcpm->options[pointer++] = MASK;
299*c2c66affSColin Finck     dhcpm->options[pointer++] = 4;
300*c2c66affSColin Finck     dhcpm->options[pointer++] = (dhcpl.mask >> 24);
301*c2c66affSColin Finck     dhcpm->options[pointer++] = ((dhcpl.mask >> 16) & 0xFF);
302*c2c66affSColin Finck     dhcpm->options[pointer++] = ((dhcpl.mask >> 8) & 0xFF);
303*c2c66affSColin Finck     dhcpm->options[pointer++] = (dhcpl.mask & 0xFF);
304*c2c66affSColin Finck     dhcpm->options[pointer++] = SERVER;
305*c2c66affSColin Finck     dhcpm->options[pointer++] = 4;
306*c2c66affSColin Finck     dhcpm->options[pointer++] = dhcpl.siaddr >> 24;
307*c2c66affSColin Finck     dhcpm->options[pointer++] = ((dhcpl.siaddr >> 16) & 0xFF);
308*c2c66affSColin Finck     dhcpm->options[pointer++] = ((dhcpl.siaddr >> 8) & 0xFF);
309*c2c66affSColin Finck     dhcpm->options[pointer++] = (dhcpl.siaddr & 0xFF);
310*c2c66affSColin Finck     dhcpm->options[pointer++] = LEASE;
311*c2c66affSColin Finck     dhcpm->options[pointer++] = 4;
312*c2c66affSColin Finck     dhcpm->options[pointer++] = (dhcpl.lease >> 24);
313*c2c66affSColin Finck     dhcpm->options[pointer++] = ((dhcpl.lease >> 16) & 0xFF);
314*c2c66affSColin Finck     dhcpm->options[pointer++] = ((dhcpl.lease >> 8) & 0xFF);
315*c2c66affSColin Finck     dhcpm->options[pointer++] = (dhcpl.lease & 0xFF);
316*c2c66affSColin Finck     dhcpm->options[pointer++] = REBINDING;
317*c2c66affSColin Finck     dhcpm->options[pointer++] = 4;
318*c2c66affSColin Finck     dhcpm->options[pointer++] = (dhcpl.lease >> 24);
319*c2c66affSColin Finck     dhcpm->options[pointer++] = ((dhcpl.lease >> 16) & 0xFF);
320*c2c66affSColin Finck     dhcpm->options[pointer++] = ((dhcpl.lease >> 8) & 0xFF);
321*c2c66affSColin Finck     dhcpm->options[pointer++] = (dhcpl.lease & 0xFF);
322*c2c66affSColin Finck     dhcpm->options[pointer++] = RENEWALTIME;
323*c2c66affSColin Finck     dhcpm->options[pointer++] = 4;
324*c2c66affSColin Finck     dhcpm->options[pointer++] = (dhcpl.lease >> 24);
325*c2c66affSColin Finck     dhcpm->options[pointer++] = ((dhcpl.lease >> 16) & 0xFF);
326*c2c66affSColin Finck     dhcpm->options[pointer++] = ((dhcpl.lease >> 8) & 0xFF);
327*c2c66affSColin Finck     dhcpm->options[pointer++] = (dhcpl.lease & 0xFF);
328*c2c66affSColin Finck     dhcpm->options[pointer++] = PAD;
329*c2c66affSColin Finck     dhcpm->options[pointer++] = PAD;
330*c2c66affSColin Finck     dhcpm->options[pointer++] = PAD;
331*c2c66affSColin Finck     dhcpm->options[pointer++] = END;
332*c2c66affSColin Finck     for( ; pointer < 312; pointer++ )
333*c2c66affSColin Finck       dhcpm->options[pointer] = PAD;
334*c2c66affSColin Finck     dhcpo->type = DHCPACK;
335*c2c66affSColin Finck     sprintf( name, "%u.%u.%u.%u", (dhcpl.ip & 0xFF), ((dhcpl.ip>>8) & 0xFF), ((dhcpl.ip>>16)&0xFF), (dhcpl.ip>>24));
336*c2c66affSColin Finck     break;
337*c2c66affSColin Finck 
338*c2c66affSColin Finck   default:
339*c2c66affSColin Finck     break;
340*c2c66affSColin Finck   }
341*c2c66affSColin Finck   display_dhcp_packet( dhcpm, dhcpo );
342*c2c66affSColin Finck   write_packet( dhcpm, name );
343*c2c66affSColin Finck   fprintf( stdout, "process_dhcp_packet [end]!\n");
344*c2c66affSColin Finck   free( name );
345*c2c66affSColin Finck   return 0;
346*c2c66affSColin Finck }
347*c2c66affSColin Finck 
write_packet(DHCPMESSAGE * dhcpm,char * name)348*c2c66affSColin Finck int write_packet( DHCPMESSAGE *dhcpm, char *name )
349*c2c66affSColin Finck {
350*c2c66affSColin Finck   int sockfd;
351*c2c66affSColin Finck   struct sockaddr_in their_addr; // connector's address information
352*c2c66affSColin Finck   struct hostent *he;
353*c2c66affSColin Finck   int numbytes;
354*c2c66affSColin Finck   int enable = 1;
355*c2c66affSColin Finck 
356*c2c66affSColin Finck   fprintf( stdout, "write_packet [begin]\n" );
357*c2c66affSColin Finck 
358*c2c66affSColin Finck   if( !dhcpm )
359*c2c66affSColin Finck     return -1;
360*c2c66affSColin Finck 
361*c2c66affSColin Finck   if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
362*c2c66affSColin Finck     perror("socket");
363*c2c66affSColin Finck     exit(1);
364*c2c66affSColin Finck   }
365*c2c66affSColin Finck 
366*c2c66affSColin Finck   if( setsockopt( sockfd, SOL_SOCKET, SO_BROADCAST, &enable, sizeof( enable )) == -1 )
367*c2c66affSColin Finck     {
368*c2c66affSColin Finck       perror("setsockopt");
369*c2c66affSColin Finck       exit(1);
370*c2c66affSColin Finck     }
371*c2c66affSColin Finck 
372*c2c66affSColin Finck   if( strcmp( "255.255.255.255", name ) )
373*c2c66affSColin Finck     {
374*c2c66affSColin Finck       if ((he=gethostbyname(name)) == NULL) {  // get the host info
375*c2c66affSColin Finck 	perror("gethostbyname");
376*c2c66affSColin Finck 	fprintf( stdout, "Unknown host %s \n", name );
377*c2c66affSColin Finck 	return -1;
378*c2c66affSColin Finck       }
379*c2c66affSColin Finck       their_addr.sin_family = AF_INET;     // host byte order
380*c2c66affSColin Finck       their_addr.sin_port = htons(68); // short, network byte order
381*c2c66affSColin Finck       their_addr.sin_addr = *((struct in_addr *)he->h_addr);
382*c2c66affSColin Finck     } else {
383*c2c66affSColin Finck       their_addr.sin_family = AF_INET;     // host byte order
384*c2c66affSColin Finck       their_addr.sin_port = htons(68); // short, network byte order
385*c2c66affSColin Finck       their_addr.sin_addr.s_addr = 0xFFFFFFFF;
386*c2c66affSColin Finck     }
387*c2c66affSColin Finck 
388*c2c66affSColin Finck   fprintf( stdout, "IP a buscar: %s \n", name );
389*c2c66affSColin Finck   memset(&(their_addr.sin_zero), '\0', 8); // zero the rest of the struct
390*c2c66affSColin Finck 
391*c2c66affSColin Finck   if ((numbytes=sendto(sockfd, dhcpm, sizeof(DHCPMESSAGE), 0,
392*c2c66affSColin Finck 		       (struct sockaddr *)&their_addr, sizeof(struct sockaddr))) == -1) {
393*c2c66affSColin Finck     perror("sendto");
394*c2c66affSColin Finck     exit(1);
395*c2c66affSColin Finck   }
396*c2c66affSColin Finck 
397*c2c66affSColin Finck   printf("sent %d bytes to %s\n", numbytes,
398*c2c66affSColin Finck 	 inet_ntoa(their_addr.sin_addr));
399*c2c66affSColin Finck 
400*c2c66affSColin Finck   close(sockfd);
401*c2c66affSColin Finck 
402*c2c66affSColin Finck   fprintf( stdout, "write_packet [end]\n" );
403*c2c66affSColin Finck 
404*c2c66affSColin Finck   return 0;
405*c2c66affSColin Finck }
406