Print standard delete message
[mpls-ldp-portable.git] / ldp / ldp_buf.c
blobe73c103d536c5625e988457774ee874aa8dad1a6
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(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(size);
33 if (!c) {
34 mpls_free(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 mpls_free(b);
55 void ldp_buf_dump(mpls_instance_handle handle, ldp_buf * b, int size)
57 unsigned char *buf = b->current;
58 int i;
59 int j = 0;
61 for (i = 0; i < size; i++) {
62 LDP_TRACE_OUT(handle, "%02x ", buf[i]);
63 j++;
64 if (j == 16) {
65 LDP_TRACE_OUT(handle, "\n");
66 j = 0;
69 LDP_TRACE_OUT(handle, "\n");
72 int ldp_encode_one_mesg(ldp_global * g, uint32_t lsraddr, int label_space,
73 ldp_buf * b, ldp_mesg * msg)
75 ldp_trace_flags type = LDP_TRACE_FLAG_INIT;
77 unsigned char *hdrBuf = b->buffer;
78 unsigned char *bodyBuf = hdrBuf + MPLS_LDP_HDRSIZE;
80 int bodyBuf_size = b->total - MPLS_LDP_HDRSIZE;
81 int hdrBuf_size = MPLS_LDP_HDRSIZE;
83 int hdr_size;
84 int body_size;
86 switch (msg->u.generic.flags.flags.msgType) {
87 case MPLS_INIT_MSGTYPE:
88 body_size = Mpls_encodeLdpInitMsg(&msg->u.init, bodyBuf, bodyBuf_size);
89 break;
90 case MPLS_NOT_MSGTYPE:
91 body_size = Mpls_encodeLdpNotMsg(&msg->u.notif, bodyBuf, bodyBuf_size);
92 break;
93 case MPLS_KEEPAL_MSGTYPE:
94 body_size =
95 Mpls_encodeLdpKeepAliveMsg(&msg->u.keep, bodyBuf, bodyBuf_size);
96 break;
97 case MPLS_HELLO_MSGTYPE:
98 body_size = Mpls_encodeLdpHelloMsg(&msg->u.hello, bodyBuf, bodyBuf_size);
99 break;
100 case MPLS_LBLREQ_MSGTYPE:
101 body_size =
102 Mpls_encodeLdpLblReqMsg(&msg->u.request, bodyBuf, bodyBuf_size);
103 break;
104 case MPLS_LBLMAP_MSGTYPE:
105 body_size = Mpls_encodeLdpLblMapMsg(&msg->u.map, bodyBuf, bodyBuf_size);
106 break;
107 case MPLS_ADDR_MSGTYPE:
108 case MPLS_ADDRWITH_MSGTYPE:
109 body_size = Mpls_encodeLdpAdrMsg(&msg->u.addr, bodyBuf, bodyBuf_size);
110 break;
111 case MPLS_LBLWITH_MSGTYPE:
112 case MPLS_LBLREL_MSGTYPE:
113 body_size =
114 Mpls_encodeLdpLbl_W_R_Msg(&msg->u.release, bodyBuf, bodyBuf_size);
115 break;
116 case MPLS_LBLABORT_MSGTYPE:
117 body_size =
118 Mpls_encodeLdpLblAbortMsg(&msg->u.abort, bodyBuf, bodyBuf_size);
119 break;
120 default:
121 MPLS_ASSERT(0);
124 if (body_size < 0) {
125 return body_size;
128 msg->header.protocolVersion = 1;
129 msg->header.pduLength = body_size;
130 msg->header.pduLength = body_size + MPLS_LDPIDLEN;
131 msg->header.lsrAddress = lsraddr;
132 msg->header.labelSpace = label_space;
134 switch (msg->u.generic.flags.flags.msgType) {
135 case MPLS_INIT_MSGTYPE:
136 type = LDP_TRACE_FLAG_INIT;
137 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_INIT,
138 printHeader(g->user_data, &msg->header),
139 printInitMsg(g->user_data, &msg->u.init));
140 break;
141 case MPLS_NOT_MSGTYPE:
142 type = LDP_TRACE_FLAG_NOTIF;
143 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_NOTIF,
144 printHeader(g->user_data, &msg->header),
145 printNotMsg(g->user_data, &msg->u.notif));
146 break;
147 case MPLS_KEEPAL_MSGTYPE:
148 type = LDP_TRACE_FLAG_PERIODIC;
149 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_PERIODIC,
150 printHeader(g->user_data, &msg->header),
151 printKeepAliveMsg(g->user_data, &msg->u.keep));
152 break;
153 case MPLS_HELLO_MSGTYPE:
154 type = LDP_TRACE_FLAG_PERIODIC;
155 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_PERIODIC,
156 printHeader(g->user_data, &msg->header),
157 printHelloMsg(g->user_data, &msg->u.hello));
158 break;
159 case MPLS_LBLREQ_MSGTYPE:
160 type = LDP_TRACE_FLAG_LABEL;
161 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_LABEL,
162 printHeader(g->user_data, &msg->header),
163 printLlbReqMsg(g->user_data, &msg->u.request));
164 break;
165 case MPLS_LBLMAP_MSGTYPE:
166 type = LDP_TRACE_FLAG_LABEL;
167 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_LABEL,
168 printHeader(g->user_data, &msg->header),
169 printLlbMapMsg(g->user_data, &msg->u.map));
170 break;
171 case MPLS_ADDR_MSGTYPE:
172 case MPLS_ADDRWITH_MSGTYPE:
173 type = LDP_TRACE_FLAG_ADDRESS;
174 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_ADDRESS,
175 printHeader(g->user_data, &msg->header),
176 printAddressMsg(g->user_data, &msg->u.addr));
177 break;
178 case MPLS_LBLWITH_MSGTYPE:
179 case MPLS_LBLREL_MSGTYPE:
180 type = LDP_TRACE_FLAG_LABEL;
181 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_LABEL,
182 printHeader(g->user_data, &msg->header),
183 printLbl_W_R_Msg(g->user_data, &msg->u.release));
184 break;
185 case MPLS_LBLABORT_MSGTYPE:
186 type = LDP_TRACE_FLAG_LABEL;
187 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_LABEL,
188 printHeader(g->user_data, &msg->header),
189 printLlbAbortMsg(g->user_data, &msg->u.abort));
190 break;
193 if ((hdr_size =
194 Mpls_encodeLdpMsgHeader(&msg->header, hdrBuf, hdrBuf_size)) < 0) {
195 return hdr_size;
198 b->current_size = hdr_size + body_size;
199 b->current = b->buffer;
200 b->size = b->current_size;
202 LDP_DUMP_PKT(g->user_data, type, MPLS_TRACE_STATE_SEND,
203 ldp_buf_dump(g->user_data, b, b->size));
205 return b->size;
208 mpls_return_enum ldp_decode_header(ldp_global * g, ldp_buf * b, ldp_mesg * msg)
210 int encodedSize;
212 LDP_ENTER(g->user_data, "ldp_decode_header");
214 encodedSize =
215 Mpls_decodeLdpMsgHeader(&msg->header, b->current, b->current_size);
217 if (encodedSize < 0) {
218 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_PACKET,
219 "Failed while decoding HEADER:%d\n", encodedSize);
220 LDP_EXIT(g->user_data, "ldp_decode_header - failure");
221 return MPLS_FAILURE;
224 LDP_DUMP_PKT(g->user_data, LDP_TRACE_FLAG_PACKET, MPLS_TRACE_STATE_RECV,
225 ldp_buf_dump(g->user_data, b, encodedSize));
227 b->current_size -= encodedSize;
228 b->current += encodedSize;
230 LDP_EXIT(g->user_data, "ldp_decode_header");
231 return MPLS_SUCCESS;
234 int ldp_decode_one_mesg(ldp_global * g, ldp_buf * b, ldp_mesg * msg)
236 int max_mesg_size;
237 int encodedSize = 0;
238 u_short type = 0;
239 int mesgSize = 0;
241 MPLS_ASSERT(b);
243 LDP_ENTER(g->user_data, "ldp_decode_one_mesg");
245 if (msg->header.pduLength > (b->size - 4)) {
246 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
247 LDP_TRACE_FLAG_PACKET, "Buffer too small. Decoding failed\n");
248 LDP_EXIT(g->user_data, "ldp_decode_one_mesg - failure");
249 return MPLS_FAILURE;
252 max_mesg_size = b->current_size;
254 /* found the message type */
255 memcpy((u_char *) & type, b->current, 2);
256 type = ntohs(type) & 0x7fff; /* ignore the U bit for now */
258 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_PACKET,
259 "Found type %x\n", type);
261 switch (type) {
262 case MPLS_INIT_MSGTYPE:
264 MPLS_MSGPTR(Init) = &msg->u.init;
265 encodedSize = Mpls_decodeLdpInitMsg(MPLS_MSGPARAM(Init),
266 b->current, max_mesg_size);
267 LDP_DUMP_PKT(g->user_data, LDP_TRACE_FLAG_INIT, MPLS_TRACE_STATE_RECV,
268 ldp_buf_dump(g->user_data, b, encodedSize));
269 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
270 LDP_TRACE_FLAG_INIT, "decodedSize for Init msg = %d\n", encodedSize);
271 if (encodedSize < 0) {
272 goto ldp_decode_one_mesg;
274 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_INIT,
275 printHeader(g->user_data, &msg->header),
276 printInitMsg(g->user_data, MPLS_MSGPARAM(Init)));
277 b->current += encodedSize;
278 mesgSize += encodedSize;
279 break;
281 case MPLS_NOT_MSGTYPE:
283 MPLS_MSGPTR(Notif) = &msg->u.notif;
284 encodedSize = Mpls_decodeLdpNotMsg(MPLS_MSGPARAM(Notif),
285 b->current, max_mesg_size);
286 LDP_DUMP_PKT(g->user_data, LDP_TRACE_FLAG_NOTIF, MPLS_TRACE_STATE_RECV,
287 ldp_buf_dump(g->user_data, b,
288 (encodedSize < 0) ? max_mesg_size : encodedSize));
289 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_NOTIF,
290 "decodedSize for Notif msg = %d\n", encodedSize);
291 if (encodedSize < 0) {
292 goto ldp_decode_one_mesg;
294 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV,
295 LDP_TRACE_FLAG_NOTIF,
296 printHeader(g->user_data, &msg->header),
297 printNotMsg(g->user_data, MPLS_MSGPARAM(Notif)));
298 b->current += encodedSize;
299 mesgSize += encodedSize;
300 break;
302 case MPLS_KEEPAL_MSGTYPE:
304 MPLS_MSGPTR(KeepAl) = &msg->u.keep;
305 encodedSize = Mpls_decodeLdpKeepAliveMsg(MPLS_MSGPARAM(KeepAl),
306 b->current, max_mesg_size);
307 LDP_DUMP_PKT(g->user_data, LDP_TRACE_FLAG_PERIODIC,
308 MPLS_TRACE_STATE_RECV, ldp_buf_dump(g->user_data, b, encodedSize));
309 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
310 LDP_TRACE_FLAG_PERIODIC,
311 "decodedSize for KeepAlive msg = %d\n", encodedSize);
312 if (encodedSize < 0) {
313 goto ldp_decode_one_mesg;
315 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV,
316 LDP_TRACE_FLAG_PERIODIC,
317 printHeader(g->user_data, &msg->header),
318 printKeepAliveMsg(g->user_data, MPLS_MSGPARAM(KeepAl)));
319 b->current += encodedSize;
320 mesgSize += encodedSize;
321 break;
323 case MPLS_HELLO_MSGTYPE:
325 MPLS_MSGPTR(Hello) = &msg->u.hello;
326 encodedSize = Mpls_decodeLdpHelloMsg(MPLS_MSGPARAM(Hello),
327 b->current, max_mesg_size);
328 LDP_DUMP_PKT(g->user_data, LDP_TRACE_FLAG_PERIODIC,
329 MPLS_TRACE_STATE_RECV, ldp_buf_dump(g->user_data, b, encodedSize));
330 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
331 LDP_TRACE_FLAG_PERIODIC, "decodedSize for Hello msg = %d\n",
332 encodedSize);
333 if (encodedSize < 0) {
334 goto ldp_decode_one_mesg;
336 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV,
337 LDP_TRACE_FLAG_PERIODIC,
338 printHeader(g->user_data, &msg->header),
339 printHelloMsg(g->user_data, MPLS_MSGPARAM(Hello)));
340 b->current += encodedSize;
341 mesgSize += encodedSize;
342 break;
344 case MPLS_LBLREQ_MSGTYPE:
346 MPLS_MSGPTR(LblReq) = &msg->u.request;
347 encodedSize = Mpls_decodeLdpLblReqMsg(MPLS_MSGPARAM(LblReq),
348 b->current, max_mesg_size);
349 LDP_DUMP_PKT(g->user_data, LDP_TRACE_FLAG_LABEL, MPLS_TRACE_STATE_RECV,
350 ldp_buf_dump(g->user_data, b, encodedSize));
351 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
352 LDP_TRACE_FLAG_LABEL, "decodedSize for Req msg = %d\n", encodedSize);
353 if (encodedSize < 0) {
354 goto ldp_decode_one_mesg;
356 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV,
357 LDP_TRACE_FLAG_LABEL,
358 printHeader(g->user_data, &msg->header),
359 printLlbReqMsg(g->user_data, MPLS_MSGPARAM(LblReq)));
360 b->current += encodedSize;
361 mesgSize += encodedSize;
362 break;
364 case MPLS_LBLMAP_MSGTYPE:
366 MPLS_MSGPTR(LblMap) = &msg->u.map;
367 encodedSize = Mpls_decodeLdpLblMapMsg(MPLS_MSGPARAM(LblMap),
368 b->current, max_mesg_size);
369 LDP_DUMP_PKT(g->user_data, LDP_TRACE_FLAG_LABEL, MPLS_TRACE_STATE_RECV,
370 ldp_buf_dump(g->user_data, b, encodedSize));
371 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
372 LDP_TRACE_FLAG_LABEL, "decodedSize for Map msg = %d\n", encodedSize);
373 if (encodedSize < 0) {
374 goto ldp_decode_one_mesg;
376 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV,
377 LDP_TRACE_FLAG_LABEL,
378 printHeader(g->user_data, &msg->header),
379 printLlbMapMsg(g->user_data, MPLS_MSGPARAM(LblMap)));
380 b->current += encodedSize;
381 mesgSize += encodedSize;
382 break;
384 case MPLS_ADDR_MSGTYPE:
385 case MPLS_ADDRWITH_MSGTYPE:
387 MPLS_MSGPTR(Adr) = &msg->u.addr;
388 encodedSize = Mpls_decodeLdpAdrMsg(MPLS_MSGPARAM(Adr),
389 b->current, max_mesg_size);
390 LDP_DUMP_PKT(g->user_data, LDP_TRACE_FLAG_ADDRESS,
391 MPLS_TRACE_STATE_RECV, ldp_buf_dump(g->user_data, b, encodedSize));
392 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
393 LDP_TRACE_FLAG_ADDRESS, "decodedSize for Adr msg = %d\n",
394 encodedSize);
395 if (encodedSize < 0) {
396 goto ldp_decode_one_mesg;
398 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV,
399 LDP_TRACE_FLAG_ADDRESS,
400 printHeader(g->user_data, &msg->header),
401 printAddressMsg(g->user_data, MPLS_MSGPARAM(Adr)));
402 b->current += encodedSize;
403 mesgSize += encodedSize;
404 break;
406 case MPLS_LBLWITH_MSGTYPE:
407 case MPLS_LBLREL_MSGTYPE:
409 MPLS_MSGPTR(Lbl_W_R_) = &msg->u.release;
410 encodedSize = Mpls_decodeLdpLbl_W_R_Msg(MPLS_MSGPARAM(Lbl_W_R_),
411 b->current, max_mesg_size);
412 LDP_DUMP_PKT(g->user_data, LDP_TRACE_FLAG_LABEL, MPLS_TRACE_STATE_RECV,
413 ldp_buf_dump(g->user_data, b, encodedSize));
414 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
415 LDP_TRACE_FLAG_LABEL,
416 "decodedSize for Lbl Release/Mapping msg = %d\n", encodedSize);
417 if (encodedSize < 0) {
418 goto ldp_decode_one_mesg;
420 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV,
421 LDP_TRACE_FLAG_LABEL,
422 printHeader(g->user_data, &msg->header),
423 printLbl_W_R_Msg(g->user_data, MPLS_MSGPARAM(Lbl_W_R_)));
424 b->current += encodedSize;
425 mesgSize += encodedSize;
426 break;
428 case MPLS_LBLABORT_MSGTYPE:
430 MPLS_MSGPTR(LblAbort) = &msg->u.abort;
431 encodedSize = Mpls_decodeLdpLblAbortMsg(MPLS_MSGPARAM(LblAbort),
432 b->current, max_mesg_size);
433 LDP_DUMP_PKT(g->user_data, LDP_TRACE_FLAG_LABEL, MPLS_TRACE_STATE_RECV,
434 ldp_buf_dump(g->user_data, b, encodedSize));
435 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
436 LDP_TRACE_FLAG_LABEL, "decodedSize for Abort msg = %d\n",
437 encodedSize);
438 if (encodedSize < 0) {
439 goto ldp_decode_one_mesg;
441 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV,
442 LDP_TRACE_FLAG_LABEL,
443 printHeader(g->user_data, &msg->header),
444 printLlbAbortMsg(g->user_data, MPLS_MSGPARAM(LblAbort)));
445 b->current += encodedSize;
446 mesgSize += encodedSize;
447 break;
449 default:
451 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
452 LDP_TRACE_FLAG_PACKET, "Unknown message type = %x\n", type);
453 goto ldp_decode_one_mesg;
455 } /* switch */
457 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
458 LDP_TRACE_FLAG_PACKET, "Mesg size: %d (%d)\n", mesgSize, b->size);
460 b->current_size -= mesgSize;
462 LDP_EXIT(g->user_data, "ldp_decode_one_mesg");
463 return MPLS_SUCCESS;
465 ldp_decode_one_mesg:
467 LDP_EXIT(g->user_data, "ldp_decode_one_mesg - failure");
468 return MPLS_FAILURE;