1/*
2 * Copyright (C) NEC Europe Ltd., 2003
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the project nor the names of its contributors
14 *    may be used to endorse or promote products derived from this software
15 *    without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <stdlib.h>
31#include <string.h>
32
33#include "relay6_parser.h"
34#include "relay6_database.h"
35
36struct msg_parser *create_parser_obj()
37{
38	struct msg_parser *msg;
39
40	msg = (struct msg_parser *) malloc (sizeof(struct msg_parser));
41	if (msg == NULL) {
42		printf("create_parser_obj()--> NO MORE MEMORY AVAILABLE\n");
43		exit(1);
44	}
45
46	msg->buffer = (uint8_t *) malloc(MAX_DHCP_MSG_LENGTH*sizeof(uint8_t));
47	if (msg->buffer == NULL) {
48		printf("create_parser_obj()--> NO MORE MEMORY AVAILABLE\n");
49		exit(1);
50	}
51
52	memcpy(msg->buffer, recvsock->databuf, MAX_DHCP_MSG_LENGTH);
53
54	msg->sent = 0;
55	msg->if_index = 0;
56
57	msg->interface_in = recvsock->pkt_interface;
58	memcpy(msg->src_addr, recvsock->src_addr, sizeof(recvsock->src_addr));
59	msg->datalength = recvsock->buflength;
60	msg->pointer_start = msg->buffer;
61	msg->dst_addr_type = recvsock->dst_addr_type;
62
63	msg->prev = &msg_parser_list;
64	msg->next =  msg_parser_list.next;
65	msg->prev->next = msg;
66	msg->next->prev = msg;
67
68	TRACE(dump, "\n%s - RECEIVED NEW MESSAGE ON INTERFACE: %d,  SOURCE: %s\n",
69	      dhcp6r_clock(), msg->interface_in, msg->src_addr);
70
71	return msg;
72}
73
74int
75check_buffer(ref, mesg)
76	int ref;
77	struct msg_parser *mesg;
78{
79	int diff;
80	diff =(int) (mesg->pstart - mesg->pointer_start);
81
82	if ((((int) mesg->datalength) - diff) >= ref)
83		return 1;
84	else
85		return 0;
86}
87
88int
89put_msg_in_store(mesg)
90	struct msg_parser *mesg;
91{
92	uint32_t msg_type;
93	uint8_t *hop, msg;
94
95	/* --------------------------- */
96	mesg->pstart = mesg->buffer;
97
98	if (check_buffer(MESSAGE_HEADER_LENGTH, mesg) == 0) {
99		printf("put_msg_in_store()--> opt_length has 0 value for "
100		       "MESSAGE_HEADER_LENGTH, DROPING... \n");
101		return 0;
102	}
103	msg_type = *((uint32_t *) mesg->pstart);
104	msg_type =  (ntohl(msg_type) & 0xFF000000)>>24;
105
106	if (msg_type == SOLICIT) {
107		if (check_interface_semafor(mesg->interface_in) == 0)
108			return 0;
109		TRACE(dump, "%s - %s", dhcp6r_clock(),
110		      "GOT MESSAGE 'SOLICIT' FROM CLIENT---> IS TO BE RELAYED\n");
111		mesg->isRF = 0;
112		if (process_RELAY_FORW(mesg) == 0)
113			return 0;
114
115		return 1;
116	}
117	else if (msg_type == REBIND) {
118		if (check_interface_semafor(mesg->interface_in) == 0)
119			return 0;
120
121		TRACE(dump, "%s - %s", dhcp6r_clock(),
122		      "GOT MESSAGE 'REBIND' FROM CLIENT---> IS TO BE RELAYED\n");
123		mesg->isRF = 0;
124		if (process_RELAY_FORW(mesg) == 0)
125			return 0;
126
127		return 1;
128	}
129	else if (msg_type == INFORMATION_REQUEST) {
130		if (check_interface_semafor(mesg->interface_in) == 0)
131			return 0;
132
133		TRACE(dump, "%s - %s", dhcp6r_clock(),
134		      "GOT MESSAGE 'INFORMATION_REQUEST' FROM CLIENT---> "
135		      "IS TO BE RELAYED\n");
136		mesg->isRF = 0;
137		if (process_RELAY_FORW(mesg) == 0)
138			return 0;
139
140		return 1;
141	}
142	else if (msg_type == REQUEST) {
143		if (check_interface_semafor(mesg->interface_in) == 0)
144			return 0;
145
146		TRACE(dump, "%s - %s", dhcp6r_clock(),
147		      "GOT MESSAGE 'REQUEST' FROM CLIENT---> IS TO BE RELAYED\n");
148		mesg->isRF = 0;
149		if (process_RELAY_FORW(mesg) == 0)
150			return 0;
151
152		return 1;
153	}
154	else if (msg_type == REPLY) {
155		if (check_interface_semafor(mesg->interface_in) == 0)
156			return 0;
157
158		TRACE(dump, "%s - %s", dhcp6r_clock(),
159		      "GOT MESSAGE 'REPLY' FROM CLIENT---> IS TO BE RELAYED\n");
160		mesg->isRF = 0;
161		if (process_RELAY_FORW(mesg) == 0)
162			return 0;
163
164		return 1;
165	}
166	else if (msg_type == RENEW) {
167		if (check_interface_semafor(mesg->interface_in) == 0)
168			return 0;
169
170		TRACE(dump, "%s - %s", dhcp6r_clock(),
171		      "GOT MESSAGE 'RENEW' FROM CLIENT---> IS TO BE RELAYED\n");
172		mesg->isRF = 0;
173		if (process_RELAY_FORW(mesg) == 0)
174			return 0;
175
176		return 1;
177	}
178	else if (msg_type == RECONFIGURE) {
179		if (check_interface_semafor(mesg->interface_in) == 0)
180			return 0;
181
182		TRACE(dump, "%s - %s", dhcp6r_clock(),
183		      "GOT MESSAGE 'RECONFIGURE' FROM CLIENT---> IS TO BE RELAYED\n");
184		mesg->isRF = 0;
185		if (process_RELAY_FORW(mesg) == 0)
186			return 0;
187
188		return 1;
189	}
190	else if (msg_type == CONFIRM) {
191		if (check_interface_semafor(mesg->interface_in) == 0)
192			return 0;
193
194		TRACE(dump, "%s - %s", dhcp6r_clock(),
195		      "GOT MESSAGE 'CONFIRM' FROM CLIENT---> IS TO BE RELAYED\n");
196		mesg->isRF = 0;
197		if (process_RELAY_FORW(mesg) == 0)
198			return 0;
199
200		return 1;
201	}
202	else if (msg_type == ADVERTISE) {
203		if (check_interface_semafor(mesg->interface_in) == 0)
204			return 0;
205
206		TRACE(dump, "%s - %s", dhcp6r_clock(),
207		      "GOT MESSAGE 'ADVERTISE' FROM CLIENT---> IS TO BE RELAYED\n");
208		mesg->isRF = 0;
209		if (process_RELAY_FORW(mesg) == 0)
210			return 0;
211
212		return 1;
213	}
214	else if (msg_type == DECLINE) {
215		if (check_interface_semafor(mesg->interface_in) == 0)
216			return 0;
217
218		TRACE(dump, "%s - %s", dhcp6r_clock(),
219		      "GOT MESSAGE 'DECLINE' FROM CLIENT---> IS TO BE RELAYED\n");
220		mesg->isRF = 0;
221		if (process_RELAY_FORW(mesg) == 0)
222			return 0;
223
224		return 1;
225	}
226	else if (msg_type == RELEASE) {
227		if (check_interface_semafor(mesg->interface_in) == 0)
228			return 0;
229
230		TRACE(dump, "%s - %s", dhcp6r_clock(),
231		      "GOT MESSAGE 'RELEASE' FROM CLIENT---> IS TO BE RELAYED\n");
232		mesg->isRF = 0;
233		if (process_RELAY_FORW(mesg) == 0)
234			return 0;
235
236		return 1;
237	}
238	msg = *mesg->pstart;
239
240	if (msg == RELAY_FORW) {
241		if (check_interface_semafor(mesg->interface_in) == 0)
242			return 0;
243
244		TRACE(dump, "%s - %s", dhcp6r_clock(),
245		      "GOT MESSAGE 'RELAY_FORW' FROM RELAY AGENT---> "
246		      "IS TO BE FURTHER RELAYED\n");
247		hop = (mesg->pstart + 1);
248		if (*hop >= HOP_COUNT_LIMIT) {
249			TRACE(dump, "%s - %s", dhcp6r_clock(),
250			      "HOP COUNT EXCEEDED, PACKET WILL BE DROPED...\n");
251			return 0;
252		}
253
254		mesg->hop_count = *hop;
255		mesg->isRF = 1;
256
257		if (process_RELAY_FORW(mesg) == 0)
258			return 0;
259
260		return 1;
261	}
262
263	if (msg == RELAY_REPL) {
264		TRACE(dump, "%s - %s", dhcp6r_clock(),
265		      "GOT MESSAGE 'RELAY_REPL' FROM RELAY AGENT OR SERVER---> "
266		      "IS TO BE FURTHER RELAYED\n");
267
268		if (process_RELAY_REPL(mesg) == 0)
269			return 0;
270
271		return 1;
272	}
273
274	TRACE(dump, "%s - %s", dhcp6r_clock(),
275	      "put_msg_in_store()--> ERROR GOT UNKNOWN MESSAGE DROPING IT......\n");
276
277	return 0;
278}
279