From: Vasu Dasari <vdasari@gmail.com>
[mpls-ldp-portable.git] / ldp / ldp_buf.c
blobb87d3c4618a160993bea494cecb66209f6f1d60f
2 /*
3 * Copyright (C) James R. Leu 2000
4 * jleu@mindspring.com
6 * This software is covered under the LGPL, for more
7 * info check out http://www.gnu.org/copyleft/lgpl.html
8 */
10 #include <stdio.h>
11 #include <netinet/in.h>
12 #include "ldp_struct.h"
13 #include "ldp_nortel.h"
14 #include "ldp_buf.h"
15 #include "ldp_mesg.h"
16 #include "mpls_mm_impl.h"
17 #include "mpls_trace_impl.h"
18 #include <errno.h>
20 int debug = 0;
22 ldp_buf *ldp_buf_create(int size)
24 ldp_buf *b = (ldp_buf *) mpls_malloc(MTYPE_LDP_BUF, sizeof(ldp_buf));
25 char *c = NULL;
27 if (!b) {
28 return NULL;
30 memset(b, 0 , sizeof(ldp_buf));
31 c = (char*) mpls_malloc(MTYPE_LDP_BUF, size);
33 if (!c) {
34 mpls_free(MTYPE_LDP_BUF, b);
35 return NULL;
38 memset(c, 0, size);
40 b->buffer = c;
41 b->total = size;
42 b->size = 0;
43 b->current_size = 0;
44 b->current = b->buffer;
46 return b;
49 void ldp_buf_delete(ldp_buf * b)
51 MPLS_ASSERT(b);
52 if (b->buffer)
53 mpls_free(MTYPE_LDP_BUF, b->buffer);
54 mpls_free(MTYPE_LDP_BUF, b);
57 void ldp_buf_dump(mpls_instance_handle handle, ldp_buf * b, int size)
59 unsigned char *buf = b->current;
60 int i;
61 int j = 0;
63 for (i = 0; i < size; i++) {
64 LDP_TRACE_OUT(handle, "%02x ", buf[i]);
65 j++;
66 if (j == 16) {
67 LDP_TRACE_OUT(handle, "\n");
68 j = 0;
71 LDP_TRACE_OUT(handle, "\n");
74 int ldp_encode_one_mesg(ldp_global * g, uint32_t lsraddr, int label_space,
75 ldp_buf * b, ldp_mesg * msg)
77 ldp_trace_flags type = LDP_TRACE_FLAG_INIT;
79 unsigned char *hdrBuf = b->buffer;
80 unsigned char *bodyBuf = hdrBuf + MPLS_LDP_HDRSIZE;
82 int bodyBuf_size = b->total - MPLS_LDP_HDRSIZE;
83 int hdrBuf_size = MPLS_LDP_HDRSIZE;
85 int hdr_size;
86 int body_size;
88 switch (msg->u.generic.flags.flags.msgType) {
89 case MPLS_INIT_MSGTYPE:
90 body_size = Mpls_encodeLdpInitMsg(&msg->u.init, bodyBuf, bodyBuf_size);
91 break;
92 case MPLS_NOT_MSGTYPE:
93 body_size = Mpls_encodeLdpNotMsg(&msg->u.notif, bodyBuf, bodyBuf_size);
94 break;
95 case MPLS_KEEPAL_MSGTYPE:
96 body_size =
97 Mpls_encodeLdpKeepAliveMsg(&msg->u.keep, bodyBuf, bodyBuf_size);
98 break;
99 case MPLS_HELLO_MSGTYPE:
100 body_size = Mpls_encodeLdpHelloMsg(&msg->u.hello, bodyBuf, bodyBuf_size);
101 break;
102 case MPLS_LBLREQ_MSGTYPE:
103 body_size =
104 Mpls_encodeLdpLblReqMsg(&msg->u.request, bodyBuf, bodyBuf_size);
105 break;
106 case MPLS_LBLMAP_MSGTYPE:
107 body_size = Mpls_encodeLdpLblMapMsg(&msg->u.map, bodyBuf, bodyBuf_size);
108 break;
109 case MPLS_ADDR_MSGTYPE:
110 case MPLS_ADDRWITH_MSGTYPE:
111 body_size = Mpls_encodeLdpAdrMsg(&msg->u.addr, bodyBuf, bodyBuf_size);
112 break;
113 case MPLS_LBLWITH_MSGTYPE:
114 case MPLS_LBLREL_MSGTYPE:
115 body_size =
116 Mpls_encodeLdpLbl_W_R_Msg(&msg->u.release, bodyBuf, bodyBuf_size);
117 break;
118 case MPLS_LBLABORT_MSGTYPE:
119 body_size =
120 Mpls_encodeLdpLblAbortMsg(&msg->u.abort, bodyBuf, bodyBuf_size);
121 break;
122 default:
123 MPLS_ASSERT(0);
126 if (body_size < 0) {
127 return body_size;
130 msg->header.protocolVersion = 1;
131 msg->header.pduLength = body_size;
132 msg->header.pduLength = body_size + MPLS_LDPIDLEN;
133 msg->header.lsrAddress = lsraddr;
134 msg->header.labelSpace = label_space;
136 switch (msg->u.generic.flags.flags.msgType) {
137 case MPLS_INIT_MSGTYPE:
138 type = LDP_TRACE_FLAG_INIT;
139 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_INIT,
140 printHeader(g->user_data, &msg->header),
141 printInitMsg(g->user_data, &msg->u.init));
142 break;
143 case MPLS_NOT_MSGTYPE:
144 type = LDP_TRACE_FLAG_NOTIF;
145 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_NOTIF,
146 printHeader(g->user_data, &msg->header),
147 printNotMsg(g->user_data, &msg->u.notif));
148 break;
149 case MPLS_KEEPAL_MSGTYPE:
150 type = LDP_TRACE_FLAG_PERIODIC;
151 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_PERIODIC,
152 printHeader(g->user_data, &msg->header),
153 printKeepAliveMsg(g->user_data, &msg->u.keep));
154 break;
155 case MPLS_HELLO_MSGTYPE:
156 type = LDP_TRACE_FLAG_PERIODIC;
157 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_PERIODIC,
158 printHeader(g->user_data, &msg->header),
159 printHelloMsg(g->user_data, &msg->u.hello));
160 break;
161 case MPLS_LBLREQ_MSGTYPE:
162 type = LDP_TRACE_FLAG_LABEL;
163 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_LABEL,
164 printHeader(g->user_data, &msg->header),
165 printLlbReqMsg(g->user_data, &msg->u.request));
166 break;
167 case MPLS_LBLMAP_MSGTYPE:
168 type = LDP_TRACE_FLAG_LABEL;
169 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_LABEL,
170 printHeader(g->user_data, &msg->header),
171 printLlbMapMsg(g->user_data, &msg->u.map));
172 break;
173 case MPLS_ADDR_MSGTYPE:
174 case MPLS_ADDRWITH_MSGTYPE:
175 type = LDP_TRACE_FLAG_ADDRESS;
176 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_ADDRESS,
177 printHeader(g->user_data, &msg->header),
178 printAddressMsg(g->user_data, &msg->u.addr));
179 break;
180 case MPLS_LBLWITH_MSGTYPE:
181 case MPLS_LBLREL_MSGTYPE:
182 type = LDP_TRACE_FLAG_LABEL;
183 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_LABEL,
184 printHeader(g->user_data, &msg->header),
185 printLbl_W_R_Msg(g->user_data, &msg->u.release));
186 break;
187 case MPLS_LBLABORT_MSGTYPE:
188 type = LDP_TRACE_FLAG_LABEL;
189 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_LABEL,
190 printHeader(g->user_data, &msg->header),
191 printLlbAbortMsg(g->user_data, &msg->u.abort));
192 break;
195 if ((hdr_size =
196 Mpls_encodeLdpMsgHeader(&msg->header, hdrBuf, hdrBuf_size)) < 0) {
197 return hdr_size;
200 b->current_size = hdr_size + body_size;
201 b->current = b->buffer;
202 b->size = b->current_size;
204 LDP_DUMP_PKT(g->user_data, type, MPLS_TRACE_STATE_SEND,
205 ldp_buf_dump(g->user_data, b, b->size));
207 return b->size;
210 mpls_return_enum ldp_decode_header(ldp_global * g, ldp_buf * b, ldp_mesg * msg)
212 int encodedSize;
214 LDP_ENTER(g->user_data, "ldp_decode_header");
216 encodedSize =
217 Mpls_decodeLdpMsgHeader(&msg->header, b->current, b->current_size);
219 if (encodedSize < 0) {
220 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_PACKET,
221 "Failed while decoding HEADER:%d\n", encodedSize);
222 LDP_EXIT(g->user_data, "ldp_decode_header - failure");
223 return MPLS_FAILURE;
226 LDP_DUMP_PKT(g->user_data, LDP_TRACE_FLAG_PACKET, MPLS_TRACE_STATE_RECV,
227 ldp_buf_dump(g->user_data, b, encodedSize));
229 b->current_size -= encodedSize;
230 b->current += encodedSize;
232 LDP_EXIT(g->user_data, "ldp_decode_header");
233 return MPLS_SUCCESS;
236 int ldp_decode_one_mesg(ldp_global * g, ldp_buf * b, ldp_mesg * msg)
238 int max_mesg_size;
239 int encodedSize = 0;
240 u_short type = 0;
241 int mesgSize = 0;
243 MPLS_ASSERT(b);
245 LDP_ENTER(g->user_data, "ldp_decode_one_mesg");
247 if (msg->header.pduLength > (b->size - 4)) {
248 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
249 LDP_TRACE_FLAG_PACKET, "Buffer too small. Decoding failed\n");
250 LDP_EXIT(g->user_data, "ldp_decode_one_mesg - failure");
251 return MPLS_FAILURE;
254 max_mesg_size = b->current_size;
256 /* found the message type */
257 memcpy((u_char *) & type, b->current, 2);
258 type = ntohs(type) & 0x7fff; /* ignore the U bit for now */
260 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_PACKET,
261 "Found type %x\n", type);
263 switch (type) {
264 case MPLS_INIT_MSGTYPE:
266 MPLS_MSGPTR(Init) = &msg->u.init;
267 encodedSize = Mpls_decodeLdpInitMsg(MPLS_MSGPARAM(Init),
268 b->current, max_mesg_size);
269 LDP_DUMP_PKT(g->user_data, LDP_TRACE_FLAG_INIT, MPLS_TRACE_STATE_RECV,
270 ldp_buf_dump(g->user_data, b, encodedSize));
271 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
272 LDP_TRACE_FLAG_INIT, "decodedSize for Init msg = %d\n", encodedSize);
273 if (encodedSize < 0) {
274 goto ldp_decode_one_mesg;
276 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_INIT,
277 printHeader(g->user_data, &msg->header),
278 printInitMsg(g->user_data, MPLS_MSGPARAM(Init)));
279 b->current += encodedSize;
280 mesgSize += encodedSize;
281 break;
283 case MPLS_NOT_MSGTYPE:
285 MPLS_MSGPTR(Notif) = &msg->u.notif;
286 encodedSize = Mpls_decodeLdpNotMsg(MPLS_MSGPARAM(Notif),
287 b->current, max_mesg_size);
288 LDP_DUMP_PKT(g->user_data, LDP_TRACE_FLAG_NOTIF, MPLS_TRACE_STATE_RECV,
289 ldp_buf_dump(g->user_data, b,
290 (encodedSize < 0) ? max_mesg_size : encodedSize));
291 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_NOTIF,
292 "decodedSize for Notif msg = %d\n", encodedSize);
293 if (encodedSize < 0) {
294 goto ldp_decode_one_mesg;
296 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV,
297 LDP_TRACE_FLAG_NOTIF,
298 printHeader(g->user_data, &msg->header),
299 printNotMsg(g->user_data, MPLS_MSGPARAM(Notif)));
300 b->current += encodedSize;
301 mesgSize += encodedSize;
302 break;
304 case MPLS_KEEPAL_MSGTYPE:
306 MPLS_MSGPTR(KeepAl) = &msg->u.keep;
307 encodedSize = Mpls_decodeLdpKeepAliveMsg(MPLS_MSGPARAM(KeepAl),
308 b->current, max_mesg_size);
309 LDP_DUMP_PKT(g->user_data, LDP_TRACE_FLAG_PERIODIC,
310 MPLS_TRACE_STATE_RECV, ldp_buf_dump(g->user_data, b, encodedSize));
311 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
312 LDP_TRACE_FLAG_PERIODIC,
313 "decodedSize for KeepAlive msg = %d\n", encodedSize);
314 if (encodedSize < 0) {
315 goto ldp_decode_one_mesg;
317 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV,
318 LDP_TRACE_FLAG_PERIODIC,
319 printHeader(g->user_data, &msg->header),
320 printKeepAliveMsg(g->user_data, MPLS_MSGPARAM(KeepAl)));
321 b->current += encodedSize;
322 mesgSize += encodedSize;
323 break;
325 case MPLS_HELLO_MSGTYPE:
327 MPLS_MSGPTR(Hello) = &msg->u.hello;
328 encodedSize = Mpls_decodeLdpHelloMsg(MPLS_MSGPARAM(Hello),
329 b->current, max_mesg_size);
330 LDP_DUMP_PKT(g->user_data, LDP_TRACE_FLAG_PERIODIC,
331 MPLS_TRACE_STATE_RECV, ldp_buf_dump(g->user_data, b, encodedSize));
332 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
333 LDP_TRACE_FLAG_PERIODIC, "decodedSize for Hello msg = %d\n",
334 encodedSize);
335 if (encodedSize < 0) {
336 goto ldp_decode_one_mesg;
338 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV,
339 LDP_TRACE_FLAG_PERIODIC,
340 printHeader(g->user_data, &msg->header),
341 printHelloMsg(g->user_data, MPLS_MSGPARAM(Hello)));
342 b->current += encodedSize;
343 mesgSize += encodedSize;
344 break;
346 case MPLS_LBLREQ_MSGTYPE:
348 MPLS_MSGPTR(LblReq) = &msg->u.request;
349 encodedSize = Mpls_decodeLdpLblReqMsg(MPLS_MSGPARAM(LblReq),
350 b->current, max_mesg_size);
351 LDP_DUMP_PKT(g->user_data, LDP_TRACE_FLAG_LABEL, MPLS_TRACE_STATE_RECV,
352 ldp_buf_dump(g->user_data, b, encodedSize));
353 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
354 LDP_TRACE_FLAG_LABEL, "decodedSize for Req msg = %d\n", encodedSize);
355 if (encodedSize < 0) {
356 goto ldp_decode_one_mesg;
358 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV,
359 LDP_TRACE_FLAG_LABEL,
360 printHeader(g->user_data, &msg->header),
361 printLlbReqMsg(g->user_data, MPLS_MSGPARAM(LblReq)));
362 b->current += encodedSize;
363 mesgSize += encodedSize;
364 break;
366 case MPLS_LBLMAP_MSGTYPE:
368 MPLS_MSGPTR(LblMap) = &msg->u.map;
369 encodedSize = Mpls_decodeLdpLblMapMsg(MPLS_MSGPARAM(LblMap),
370 b->current, max_mesg_size);
371 LDP_DUMP_PKT(g->user_data, LDP_TRACE_FLAG_LABEL, MPLS_TRACE_STATE_RECV,
372 ldp_buf_dump(g->user_data, b, encodedSize));
373 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
374 LDP_TRACE_FLAG_LABEL, "decodedSize for Map msg = %d\n", encodedSize);
375 if (encodedSize < 0) {
376 goto ldp_decode_one_mesg;
378 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV,
379 LDP_TRACE_FLAG_LABEL,
380 printHeader(g->user_data, &msg->header),
381 printLlbMapMsg(g->user_data, MPLS_MSGPARAM(LblMap)));
382 b->current += encodedSize;
383 mesgSize += encodedSize;
384 break;
386 case MPLS_ADDR_MSGTYPE:
387 case MPLS_ADDRWITH_MSGTYPE:
389 MPLS_MSGPTR(Adr) = &msg->u.addr;
390 encodedSize = Mpls_decodeLdpAdrMsg(MPLS_MSGPARAM(Adr),
391 b->current, max_mesg_size);
392 LDP_DUMP_PKT(g->user_data, LDP_TRACE_FLAG_ADDRESS,
393 MPLS_TRACE_STATE_RECV, ldp_buf_dump(g->user_data, b, encodedSize));
394 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
395 LDP_TRACE_FLAG_ADDRESS, "decodedSize for Adr msg = %d\n",
396 encodedSize);
397 if (encodedSize < 0) {
398 goto ldp_decode_one_mesg;
400 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV,
401 LDP_TRACE_FLAG_ADDRESS,
402 printHeader(g->user_data, &msg->header),
403 printAddressMsg(g->user_data, MPLS_MSGPARAM(Adr)));
404 b->current += encodedSize;
405 mesgSize += encodedSize;
406 break;
408 case MPLS_LBLWITH_MSGTYPE:
409 case MPLS_LBLREL_MSGTYPE:
411 MPLS_MSGPTR(Lbl_W_R_) = &msg->u.release;
412 encodedSize = Mpls_decodeLdpLbl_W_R_Msg(MPLS_MSGPARAM(Lbl_W_R_),
413 b->current, max_mesg_size);
414 LDP_DUMP_PKT(g->user_data, LDP_TRACE_FLAG_LABEL, MPLS_TRACE_STATE_RECV,
415 ldp_buf_dump(g->user_data, b, encodedSize));
416 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
417 LDP_TRACE_FLAG_LABEL,
418 "decodedSize for Lbl Release/Mapping msg = %d\n", encodedSize);
419 if (encodedSize < 0) {
420 goto ldp_decode_one_mesg;
422 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV,
423 LDP_TRACE_FLAG_LABEL,
424 printHeader(g->user_data, &msg->header),
425 printLbl_W_R_Msg(g->user_data, MPLS_MSGPARAM(Lbl_W_R_)));
426 b->current += encodedSize;
427 mesgSize += encodedSize;
428 break;
430 case MPLS_LBLABORT_MSGTYPE:
432 MPLS_MSGPTR(LblAbort) = &msg->u.abort;
433 encodedSize = Mpls_decodeLdpLblAbortMsg(MPLS_MSGPARAM(LblAbort),
434 b->current, max_mesg_size);
435 LDP_DUMP_PKT(g->user_data, LDP_TRACE_FLAG_LABEL, MPLS_TRACE_STATE_RECV,
436 ldp_buf_dump(g->user_data, b, encodedSize));
437 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
438 LDP_TRACE_FLAG_LABEL, "decodedSize for Abort msg = %d\n",
439 encodedSize);
440 if (encodedSize < 0) {
441 goto ldp_decode_one_mesg;
443 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV,
444 LDP_TRACE_FLAG_LABEL,
445 printHeader(g->user_data, &msg->header),
446 printLlbAbortMsg(g->user_data, MPLS_MSGPARAM(LblAbort)));
447 b->current += encodedSize;
448 mesgSize += encodedSize;
449 break;
451 default:
453 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
454 LDP_TRACE_FLAG_PACKET, "Unknown message type = %x\n", type);
455 goto ldp_decode_one_mesg;
457 } /* switch */
459 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
460 LDP_TRACE_FLAG_PACKET, "Mesg size: %d (%d)\n", mesgSize, b->size);
462 b->current_size -= mesgSize;
464 LDP_EXIT(g->user_data, "ldp_decode_one_mesg");
465 return MPLS_SUCCESS;
467 ldp_decode_one_mesg:
469 LDP_EXIT(g->user_data, "ldp_decode_one_mesg - failure");
470 return MPLS_FAILURE;