Updated label mapping to better support the new fec -> nh relationship
[mpls-ldp-portable.git] / ldp / ldp_buf.c
blobe58fd900ff35b9f38429980420e1a013cd24a13f
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) + size);
26 if (!b) {
27 return NULL;
30 b->buffer = (uint8_t *) & b[1];
31 b->total = size;
32 b->size = 0;
33 b->current_size = 0;
34 b->current = b->buffer;
36 return b;
39 void ldp_buf_delete(ldp_buf * b)
41 MPLS_ASSERT(b);
42 mpls_free(b);
45 void ldp_buf_dump(mpls_instance_handle handle, ldp_buf * b, int size)
47 unsigned char *buf = b->current;
48 int i;
49 int j = 0;
51 for (i = 0; i < size; i++) {
52 LDP_TRACE_OUT(handle, "%02x ", buf[i]);
53 j++;
54 if (j == 16) {
55 LDP_TRACE_OUT(handle, "\n");
56 j = 0;
59 LDP_TRACE_OUT(handle, "\n");
62 int ldp_encode_one_mesg(ldp_global * g, uint32_t lsraddr, int label_space,
63 ldp_buf * b, ldp_mesg * msg)
65 ldp_trace_flags type = LDP_TRACE_FLAG_INIT;
67 unsigned char *hdrBuf = b->buffer;
68 unsigned char *bodyBuf = hdrBuf + MPLS_LDP_HDRSIZE;
70 int bodyBuf_size = b->total - MPLS_LDP_HDRSIZE;
71 int hdrBuf_size = MPLS_LDP_HDRSIZE;
73 int hdr_size;
74 int body_size;
76 switch (msg->u.generic.flags.flags.msgType) {
77 case MPLS_INIT_MSGTYPE:
78 body_size = Mpls_encodeLdpInitMsg(&msg->u.init, bodyBuf, bodyBuf_size);
79 break;
80 case MPLS_NOT_MSGTYPE:
81 body_size = Mpls_encodeLdpNotMsg(&msg->u.notif, bodyBuf, bodyBuf_size);
82 break;
83 case MPLS_KEEPAL_MSGTYPE:
84 body_size =
85 Mpls_encodeLdpKeepAliveMsg(&msg->u.keep, bodyBuf, bodyBuf_size);
86 break;
87 case MPLS_HELLO_MSGTYPE:
88 body_size = Mpls_encodeLdpHelloMsg(&msg->u.hello, bodyBuf, bodyBuf_size);
89 break;
90 case MPLS_LBLREQ_MSGTYPE:
91 body_size =
92 Mpls_encodeLdpLblReqMsg(&msg->u.request, bodyBuf, bodyBuf_size);
93 break;
94 case MPLS_LBLMAP_MSGTYPE:
95 body_size = Mpls_encodeLdpLblMapMsg(&msg->u.map, bodyBuf, bodyBuf_size);
96 break;
97 case MPLS_ADDR_MSGTYPE:
98 case MPLS_ADDRWITH_MSGTYPE:
99 body_size = Mpls_encodeLdpAdrMsg(&msg->u.addr, bodyBuf, bodyBuf_size);
100 break;
101 case MPLS_LBLWITH_MSGTYPE:
102 case MPLS_LBLREL_MSGTYPE:
103 body_size =
104 Mpls_encodeLdpLbl_W_R_Msg(&msg->u.release, bodyBuf, bodyBuf_size);
105 break;
106 case MPLS_LBLABORT_MSGTYPE:
107 body_size =
108 Mpls_encodeLdpLblAbortMsg(&msg->u.abort, bodyBuf, bodyBuf_size);
109 break;
110 default:
111 MPLS_ASSERT(0);
114 if (body_size < 0) {
115 return body_size;
118 msg->header.protocolVersion = 1;
119 msg->header.pduLength = body_size;
120 msg->header.pduLength = body_size + MPLS_LDPIDLEN;
121 msg->header.lsrAddress = lsraddr;
122 msg->header.labelSpace = label_space;
124 switch (msg->u.generic.flags.flags.msgType) {
125 case MPLS_INIT_MSGTYPE:
126 type = LDP_TRACE_FLAG_INIT;
127 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_INIT,
128 printHeader(g->user_data, &msg->header),
129 printInitMsg(g->user_data, &msg->u.init));
130 break;
131 case MPLS_NOT_MSGTYPE:
132 type = LDP_TRACE_FLAG_NOTIF;
133 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_NOTIF,
134 printHeader(g->user_data, &msg->header),
135 printNotMsg(g->user_data, &msg->u.notif));
136 break;
137 case MPLS_KEEPAL_MSGTYPE:
138 type = LDP_TRACE_FLAG_PERIODIC;
139 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_PERIODIC,
140 printHeader(g->user_data, &msg->header),
141 printKeepAliveMsg(g->user_data, &msg->u.keep));
142 break;
143 case MPLS_HELLO_MSGTYPE:
144 type = LDP_TRACE_FLAG_PERIODIC;
145 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_PERIODIC,
146 printHeader(g->user_data, &msg->header),
147 printHelloMsg(g->user_data, &msg->u.hello));
148 break;
149 case MPLS_LBLREQ_MSGTYPE:
150 type = LDP_TRACE_FLAG_LABEL;
151 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_LABEL,
152 printHeader(g->user_data, &msg->header),
153 printLlbReqMsg(g->user_data, &msg->u.request));
154 break;
155 case MPLS_LBLMAP_MSGTYPE:
156 type = LDP_TRACE_FLAG_LABEL;
157 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_LABEL,
158 printHeader(g->user_data, &msg->header),
159 printLlbMapMsg(g->user_data, &msg->u.map));
160 break;
161 case MPLS_ADDR_MSGTYPE:
162 case MPLS_ADDRWITH_MSGTYPE:
163 type = LDP_TRACE_FLAG_ADDRESS;
164 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_ADDRESS,
165 printHeader(g->user_data, &msg->header),
166 printAddressMsg(g->user_data, &msg->u.addr));
167 break;
168 case MPLS_LBLWITH_MSGTYPE:
169 case MPLS_LBLREL_MSGTYPE:
170 type = LDP_TRACE_FLAG_LABEL;
171 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_LABEL,
172 printHeader(g->user_data, &msg->header),
173 printLbl_W_R_Msg(g->user_data, &msg->u.release));
174 break;
175 case MPLS_LBLABORT_MSGTYPE:
176 type = LDP_TRACE_FLAG_LABEL;
177 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_LABEL,
178 printHeader(g->user_data, &msg->header),
179 printLlbAbortMsg(g->user_data, &msg->u.abort));
180 break;
183 if ((hdr_size =
184 Mpls_encodeLdpMsgHeader(&msg->header, hdrBuf, hdrBuf_size)) < 0) {
185 return hdr_size;
188 b->current_size = hdr_size + body_size;
189 b->current = b->buffer;
190 b->size = b->current_size;
192 LDP_DUMP_PKT(g->user_data, type, MPLS_TRACE_STATE_SEND,
193 ldp_buf_dump(g->user_data, b, b->size));
195 return b->size;
198 mpls_return_enum ldp_decode_header(ldp_global * g, ldp_buf * b, ldp_mesg * msg)
200 int encodedSize;
202 LDP_ENTER(g->user_data, "ldp_decode_header");
204 encodedSize =
205 Mpls_decodeLdpMsgHeader(&msg->header, b->current, b->current_size);
207 if (encodedSize < 0) {
208 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_PACKET,
209 "Failed while decoding HEADER:%d\n", encodedSize);
210 LDP_EXIT(g->user_data, "ldp_decode_header - failure");
211 return MPLS_FAILURE;
214 LDP_DUMP_PKT(g->user_data, LDP_TRACE_FLAG_PACKET, MPLS_TRACE_STATE_RECV,
215 ldp_buf_dump(g->user_data, b, encodedSize));
217 b->current_size -= encodedSize;
218 b->current += encodedSize;
220 LDP_EXIT(g->user_data, "ldp_decode_header");
221 return MPLS_SUCCESS;
224 int ldp_decode_one_mesg(ldp_global * g, ldp_buf * b, ldp_mesg * msg)
226 int max_mesg_size;
227 int encodedSize = 0;
228 u_short type = 0;
229 int mesgSize = 0;
231 MPLS_ASSERT(b);
233 LDP_ENTER(g->user_data, "ldp_decode_one_mesg");
235 if (msg->header.pduLength > (b->size - 4)) {
236 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
237 LDP_TRACE_FLAG_PACKET, "Buffer too small. Decoding failed\n");
238 LDP_EXIT(g->user_data, "ldp_decode_one_mesg - failure");
239 return MPLS_FAILURE;
242 max_mesg_size = b->current_size;
244 /* found the message type */
245 memcpy((u_char *) & type, b->current, 2);
246 type = ntohs(type) & 0x7fff; /* ignore the U bit for now */
248 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_PACKET,
249 "Found type %x\n", type);
251 switch (type) {
252 case MPLS_INIT_MSGTYPE:
254 MPLS_MSGPTR(Init) = &msg->u.init;
255 encodedSize = Mpls_decodeLdpInitMsg(MPLS_MSGPARAM(Init),
256 b->current, max_mesg_size);
257 LDP_DUMP_PKT(g->user_data, LDP_TRACE_FLAG_INIT, MPLS_TRACE_STATE_RECV,
258 ldp_buf_dump(g->user_data, b, encodedSize));
259 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
260 LDP_TRACE_FLAG_INIT, "decodedSize for Init msg = %d\n", encodedSize);
261 if (encodedSize < 0) {
262 goto ldp_decode_one_mesg;
264 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_INIT,
265 printHeader(g->user_data, &msg->header),
266 printInitMsg(g->user_data, MPLS_MSGPARAM(Init)));
267 b->current += encodedSize;
268 mesgSize += encodedSize;
269 break;
271 case MPLS_NOT_MSGTYPE:
273 MPLS_MSGPTR(Notif) = &msg->u.notif;
274 encodedSize = Mpls_decodeLdpNotMsg(MPLS_MSGPARAM(Notif),
275 b->current, max_mesg_size);
276 LDP_DUMP_PKT(g->user_data, LDP_TRACE_FLAG_NOTIF, MPLS_TRACE_STATE_RECV,
277 ldp_buf_dump(g->user_data, b,
278 (encodedSize < 0) ? max_mesg_size : encodedSize));
279 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV, LDP_TRACE_FLAG_NOTIF,
280 "decodedSize for Notif msg = %d\n", encodedSize);
281 if (encodedSize < 0) {
282 goto ldp_decode_one_mesg;
284 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV,
285 LDP_TRACE_FLAG_NOTIF,
286 printHeader(g->user_data, &msg->header),
287 printNotMsg(g->user_data, MPLS_MSGPARAM(Notif)));
288 b->current += encodedSize;
289 mesgSize += encodedSize;
290 break;
292 case MPLS_KEEPAL_MSGTYPE:
294 MPLS_MSGPTR(KeepAl) = &msg->u.keep;
295 encodedSize = Mpls_decodeLdpKeepAliveMsg(MPLS_MSGPARAM(KeepAl),
296 b->current, max_mesg_size);
297 LDP_DUMP_PKT(g->user_data, LDP_TRACE_FLAG_PERIODIC,
298 MPLS_TRACE_STATE_RECV, ldp_buf_dump(g->user_data, b, encodedSize));
299 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
300 LDP_TRACE_FLAG_PERIODIC,
301 "decodedSize for KeepAlive msg = %d\n", encodedSize);
302 if (encodedSize < 0) {
303 goto ldp_decode_one_mesg;
305 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV,
306 LDP_TRACE_FLAG_PERIODIC,
307 printHeader(g->user_data, &msg->header),
308 printKeepAliveMsg(g->user_data, MPLS_MSGPARAM(KeepAl)));
309 b->current += encodedSize;
310 mesgSize += encodedSize;
311 break;
313 case MPLS_HELLO_MSGTYPE:
315 MPLS_MSGPTR(Hello) = &msg->u.hello;
316 encodedSize = Mpls_decodeLdpHelloMsg(MPLS_MSGPARAM(Hello),
317 b->current, max_mesg_size);
318 LDP_DUMP_PKT(g->user_data, LDP_TRACE_FLAG_PERIODIC,
319 MPLS_TRACE_STATE_RECV, ldp_buf_dump(g->user_data, b, encodedSize));
320 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
321 LDP_TRACE_FLAG_PERIODIC, "decodedSize for Hello msg = %d\n",
322 encodedSize);
323 if (encodedSize < 0) {
324 goto ldp_decode_one_mesg;
326 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV,
327 LDP_TRACE_FLAG_PERIODIC,
328 printHeader(g->user_data, &msg->header),
329 printHelloMsg(g->user_data, MPLS_MSGPARAM(Hello)));
330 b->current += encodedSize;
331 mesgSize += encodedSize;
332 break;
334 case MPLS_LBLREQ_MSGTYPE:
336 MPLS_MSGPTR(LblReq) = &msg->u.request;
337 encodedSize = Mpls_decodeLdpLblReqMsg(MPLS_MSGPARAM(LblReq),
338 b->current, max_mesg_size);
339 LDP_DUMP_PKT(g->user_data, LDP_TRACE_FLAG_LABEL, MPLS_TRACE_STATE_RECV,
340 ldp_buf_dump(g->user_data, b, encodedSize));
341 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
342 LDP_TRACE_FLAG_LABEL, "decodedSize for Req msg = %d\n", encodedSize);
343 if (encodedSize < 0) {
344 goto ldp_decode_one_mesg;
346 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV,
347 LDP_TRACE_FLAG_LABEL,
348 printHeader(g->user_data, &msg->header),
349 printLlbReqMsg(g->user_data, MPLS_MSGPARAM(LblReq)));
350 b->current += encodedSize;
351 mesgSize += encodedSize;
352 break;
354 case MPLS_LBLMAP_MSGTYPE:
356 MPLS_MSGPTR(LblMap) = &msg->u.map;
357 encodedSize = Mpls_decodeLdpLblMapMsg(MPLS_MSGPARAM(LblMap),
358 b->current, max_mesg_size);
359 LDP_DUMP_PKT(g->user_data, LDP_TRACE_FLAG_LABEL, MPLS_TRACE_STATE_RECV,
360 ldp_buf_dump(g->user_data, b, encodedSize));
361 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
362 LDP_TRACE_FLAG_LABEL, "decodedSize for Map msg = %d\n", encodedSize);
363 if (encodedSize < 0) {
364 goto ldp_decode_one_mesg;
366 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV,
367 LDP_TRACE_FLAG_LABEL,
368 printHeader(g->user_data, &msg->header),
369 printLlbMapMsg(g->user_data, MPLS_MSGPARAM(LblMap)));
370 b->current += encodedSize;
371 mesgSize += encodedSize;
372 break;
374 case MPLS_ADDR_MSGTYPE:
375 case MPLS_ADDRWITH_MSGTYPE:
377 MPLS_MSGPTR(Adr) = &msg->u.addr;
378 encodedSize = Mpls_decodeLdpAdrMsg(MPLS_MSGPARAM(Adr),
379 b->current, max_mesg_size);
380 LDP_DUMP_PKT(g->user_data, LDP_TRACE_FLAG_ADDRESS,
381 MPLS_TRACE_STATE_RECV, ldp_buf_dump(g->user_data, b, encodedSize));
382 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
383 LDP_TRACE_FLAG_ADDRESS, "decodedSize for Adr msg = %d\n",
384 encodedSize);
385 if (encodedSize < 0) {
386 goto ldp_decode_one_mesg;
388 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV,
389 LDP_TRACE_FLAG_ADDRESS,
390 printHeader(g->user_data, &msg->header),
391 printAddressMsg(g->user_data, MPLS_MSGPARAM(Adr)));
392 b->current += encodedSize;
393 mesgSize += encodedSize;
394 break;
396 case MPLS_LBLWITH_MSGTYPE:
397 case MPLS_LBLREL_MSGTYPE:
399 MPLS_MSGPTR(Lbl_W_R_) = &msg->u.release;
400 encodedSize = Mpls_decodeLdpLbl_W_R_Msg(MPLS_MSGPARAM(Lbl_W_R_),
401 b->current, max_mesg_size);
402 LDP_DUMP_PKT(g->user_data, LDP_TRACE_FLAG_LABEL, MPLS_TRACE_STATE_RECV,
403 ldp_buf_dump(g->user_data, b, encodedSize));
404 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
405 LDP_TRACE_FLAG_LABEL,
406 "decodedSize for Lbl Release/Mapping msg = %d\n", encodedSize);
407 if (encodedSize < 0) {
408 goto ldp_decode_one_mesg;
410 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV,
411 LDP_TRACE_FLAG_LABEL,
412 printHeader(g->user_data, &msg->header),
413 printLbl_W_R_Msg(g->user_data, MPLS_MSGPARAM(Lbl_W_R_)));
414 b->current += encodedSize;
415 mesgSize += encodedSize;
416 break;
418 case MPLS_LBLABORT_MSGTYPE:
420 MPLS_MSGPTR(LblAbort) = &msg->u.abort;
421 encodedSize = Mpls_decodeLdpLblAbortMsg(MPLS_MSGPARAM(LblAbort),
422 b->current, max_mesg_size);
423 LDP_DUMP_PKT(g->user_data, LDP_TRACE_FLAG_LABEL, MPLS_TRACE_STATE_RECV,
424 ldp_buf_dump(g->user_data, b, encodedSize));
425 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
426 LDP_TRACE_FLAG_LABEL, "decodedSize for Abort msg = %d\n",
427 encodedSize);
428 if (encodedSize < 0) {
429 goto ldp_decode_one_mesg;
431 LDP_TRACE_PKT(g->user_data, MPLS_TRACE_STATE_RECV,
432 LDP_TRACE_FLAG_LABEL,
433 printHeader(g->user_data, &msg->header),
434 printLlbAbortMsg(g->user_data, MPLS_MSGPARAM(LblAbort)));
435 b->current += encodedSize;
436 mesgSize += encodedSize;
437 break;
439 default:
441 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
442 LDP_TRACE_FLAG_PACKET, "Unknown message type = %x\n", type);
443 goto ldp_decode_one_mesg;
445 } /* switch */
447 LDP_TRACE_LOG(g->user_data, MPLS_TRACE_STATE_RECV,
448 LDP_TRACE_FLAG_PACKET, "Mesg size: %d (%d)\n", mesgSize, b->size);
450 b->current_size -= mesgSize;
452 LDP_EXIT(g->user_data, "ldp_decode_one_mesg");
453 return MPLS_SUCCESS;
455 ldp_decode_one_mesg:
457 LDP_EXIT(g->user_data, "ldp_decode_one_mesg - failure");
458 return MPLS_FAILURE;