Incorporate rosapps. 0.3.15 was branched somewhat incorrectly so rosapps is not synce...
[reactos.git] / modules / rosapps / applications / net / dhcpd / src / parsing / parser.c
1 #include <headers.h>
2 #include <datatypes.h>
3 #include <display.h>
4 #include <parser.h>
5 #include <leases.h>
6 #include <options.h>
7
8 int parse_dhcp_options( DHCPMESSAGE *dhcpm, DHCPOPTIONS *dhcpo )
9 {
10 int pointer, opointer;
11 int olength;
12
13 pointer = 0;
14
15 fprintf( stdout, "parse_dhcp_options [begin]!\n");
16
17 /* Options Initialization */
18 /* No message type */
19 dhcpo->type = 0;
20 /* No ip address, 0.0.0.0 */
21 dhcpo->r_ip = 0;
22 /* No mask address, 0.0.0.0 */
23 dhcpo->r_mask = 0;
24 /* No router, 0.0.0.0 */
25 dhcpo->r_router = 0;
26 /* No lease 0 */
27 dhcpo->r_lease = 0;
28 /* No name '\n' */
29 dhcpo->hostname = NULL;
30
31 while( pointer< 312 )
32 {
33 if(( dhcpm->options[0] != 99 ) && (dhcpm->options[1]!=130) && (dhcpm->options[2]!=83) && (dhcpm->options[3]!= 99))
34 {
35 fprintf( stdout, "No magic cookie! Aborting! \n" );
36 return -1;
37 }
38 switch( dhcpm->options[pointer] ){
39 case PAD:
40 pointer++;
41 break;
42 case MESSAGETYPE:
43 /* Try to figure out the kind of message and start the configuring process */
44 pointer += 2;
45 dhcpo->type = dhcpm->options[pointer++];
46 break;
47 case PREQUEST:
48 /* Take note of the requested parameters */
49 opointer = pointer + 2;
50 olength = pointer + dhcpm->options[pointer + 1];
51 while( opointer < olength )
52 {
53 switch( dhcpm->options[opointer] ){
54 case IP:
55 /* Take note of the requested ip */
56 opointer += 2;
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++];
64 break;
65 case MASK:
66 /* Take note of the requested mask */
67 opointer += 2;
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++];
75 break;
76 case ROUTER:
77 /* Take note of the requested router */
78 opointer += 2;
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++];
86 break;
87 case LEASE:
88 opointer += 2;
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++];
96 break;
97 case HOSTNAME:
98 opointer += 1;
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;
102 default:
103 /* Ignore option */
104 opointer++;
105 break;
106 }
107 }
108 pointer = opointer;
109 break;
110 case TOFFSET:
111 case TIMESERVER:
112 case NS:
113 case DNS:
114 case LOGSERVER:
115 case COOKIESERVER:
116 case LPRSERVER:
117 case IMPSERVER:
118 case RESLOCSERVER:
119 case BOOTFILESIZE:
120 case MERITDUMPFILE:
121 case DOMAINNAME:
122 case SWAPSERVER:
123 case ROOTPATH:
124 case EXTENSIONPATH:
125 case IPFORWARD:
126 case NONLOCAL:
127 case POLICYFILTER:
128 case MAXIMUMDATAG:
129 case DEFAULTTTL:
130 case PATHMTUATO:
131 case PATHMTUPTO:
132 case IMTU:
133 case ALLSUBLOCAL:
134 case BROADCAST:
135 case PMASKDISCOVERY:
136 case MASKSUPPLIER:
137 case PROUTERDISCOVE:
138 case RSOLICIADDRESS:
139 case STATICROUTE:
140 case TENCAPSULATION:
141 case ARPCACHE:
142 case ETHENCAPSUL:
143 case TCPDEFTTL:
144 case TCPKAI:
145 case TCPKAG:
146 case NISDOMAIN:
147 case NISSERVER:
148 case NTPSERVER:
149 case VENDORSP:
150 case NBTCPIPNS:
151 case NBTCPIPDDS:
152 case NBTCPIPNT:
153 case NBTCPIPSC:
154 case XWINFONTSERVER:
155 case XWINDISPLAY:
156 case OVERLOAD:
157 case SERVER:
158 case MESSAGE:
159 case MAXIMUMDHCP:
160 case RENEWALTIME:
161 case REBINDING:
162 case VENDORCLASS:
163 case NISPLUSDOMAIN:
164 case NISPLUSSERVER:
165 case TFTPSERVER:
166 case BOOTFILE:
167 case MOBILEIP:
168 case SMTPSERVER:
169 case POP3SERVER:
170 case NNTPSERVER:
171 case HTTPSERVER:
172 case FINGERSERVER:
173 case IRCSERVER:
174 case STREETTALKSE:
175 case STREETTALKDA:
176 case CLIENT:
177 pointer++;
178 pointer += dhcpm->options[pointer];
179 case END:
180 /* return to the calling functions because this is over */
181 fprintf( stdout, "parse_dhcp_options: END option found! [end]!\n");
182 return 0;
183 default:
184 /* ignored */
185 pointer++;
186 break;
187 }
188 }
189 fprintf( stdout, "parse_dhcp_options [end]!\n");
190 return 0;
191 }
192
193 int process_dhcp_packet( DHCPMESSAGE *dhcpm, DHCPOPTIONS *dhcpo )
194 {
195 int pointer = 4;
196 DHCPLEASE dhcpl;
197 char *name;
198
199 fprintf( stdout, "process_dhcp_packet [begin]!\n");
200
201 if( (!dhcpm) || (!dhcpo) )
202 return -1;
203
204 name = (char *)malloc( 16 );
205 switch( dhcpo->type ){
206
207 case DHCPDISCOVER:
208 /* We need to send a DHCPOFFER */
209 if( find_lease( &dhcpl, dhcpm->xid, dhcpm->chaddr ) < 0 )
210 {
211 fprintf( stdout, "No free leases! \n" );
212 return -1;
213 }
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" );
265 break;
266
267 case DHCPREQUEST:
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)
273 {
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 );
284 return -1;
285 }
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));
334 break;
335
336 default:
337 break;
338 }
339 display_dhcp_packet( dhcpm, dhcpo );
340 write_packet( dhcpm, name );
341 fprintf( stdout, "process_dhcp_packet [end]!\n");
342 return 0;
343 }
344
345 int write_packet( DHCPMESSAGE *dhcpm, char *name )
346 {
347 int sockfd;
348 struct sockaddr_in their_addr; // connector's address information
349 struct hostent *he;
350 int numbytes;
351 int enable = 1;
352
353 fprintf( stdout, "write_packet [begin]\n" );
354
355 if( !dhcpm )
356 return -1;
357
358 if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
359 perror("socket");
360 exit(1);
361 }
362
363 if( setsockopt( sockfd, SOL_SOCKET, SO_BROADCAST, &enable, sizeof( enable )) == -1 )
364 {
365 perror("setsockopt");
366 exit(1);
367 }
368
369 if( strcmp( "255.255.255.255", name ) )
370 {
371 if ((he=gethostbyname(name)) == NULL) { // get the host info
372 perror("gethostbyname");
373 fprintf( stdout, "Unknown host %s \n", name );
374 return -1;
375 }
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);
379 } else {
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;
383 }
384
385 fprintf( stdout, "IP a buscar: %s \n", name );
386 memset(&(their_addr.sin_zero), '\0', 8); // zero the rest of the struct
387
388 if ((numbytes=sendto(sockfd, dhcpm, sizeof(DHCPMESSAGE), 0,
389 (struct sockaddr *)&their_addr, sizeof(struct sockaddr))) == -1) {
390 perror("sendto");
391 exit(1);
392 }
393
394 printf("sent %d bytes to %s\n", numbytes,
395 inet_ntoa(their_addr.sin_addr));
396
397 close(sockfd);
398
399 fprintf( stdout, "write_packet [end]\n" );
400
401 return 0;
402 }