3 * Copyright (C) James R. Leu 2000
6 * This software is covered under the LGPL, for more
7 * info check out http://www.gnu.org/copyleft/lgpl.html
11 #include <netinet/in.h>
12 #include "ldp_struct.h"
13 #include "ldp_nortel.h"
16 #include "mpls_mm_impl.h"
17 #include "mpls_trace_impl.h"
22 ldp_buf
*ldp_buf_create(int size
)
24 ldp_buf
*b
= (ldp_buf
*) mpls_malloc(MTYPE_LDP_BUF
, sizeof(ldp_buf
));
30 memset(b
, 0 , sizeof(ldp_buf
));
31 c
= (char*) mpls_malloc(MTYPE_LDP_BUF
, size
);
34 mpls_free(MTYPE_LDP_BUF
, b
);
44 b
->current
= b
->buffer
;
49 void ldp_buf_delete(ldp_buf
* b
)
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
;
63 for (i
= 0; i
< size
; i
++) {
64 LDP_TRACE_OUT(handle
, "%02x ", buf
[i
]);
67 LDP_TRACE_OUT(handle
, "\n");
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
;
88 switch (msg
->u
.generic
.flags
.flags
.msgType
) {
89 case MPLS_INIT_MSGTYPE
:
90 body_size
= Mpls_encodeLdpInitMsg(&msg
->u
.init
, bodyBuf
, bodyBuf_size
);
92 case MPLS_NOT_MSGTYPE
:
93 body_size
= Mpls_encodeLdpNotMsg(&msg
->u
.notif
, bodyBuf
, bodyBuf_size
);
95 case MPLS_KEEPAL_MSGTYPE
:
97 Mpls_encodeLdpKeepAliveMsg(&msg
->u
.keep
, bodyBuf
, bodyBuf_size
);
99 case MPLS_HELLO_MSGTYPE
:
100 body_size
= Mpls_encodeLdpHelloMsg(&msg
->u
.hello
, bodyBuf
, bodyBuf_size
);
102 case MPLS_LBLREQ_MSGTYPE
:
104 Mpls_encodeLdpLblReqMsg(&msg
->u
.request
, bodyBuf
, bodyBuf_size
);
106 case MPLS_LBLMAP_MSGTYPE
:
107 body_size
= Mpls_encodeLdpLblMapMsg(&msg
->u
.map
, bodyBuf
, bodyBuf_size
);
109 case MPLS_ADDR_MSGTYPE
:
110 case MPLS_ADDRWITH_MSGTYPE
:
111 body_size
= Mpls_encodeLdpAdrMsg(&msg
->u
.addr
, bodyBuf
, bodyBuf_size
);
113 case MPLS_LBLWITH_MSGTYPE
:
114 case MPLS_LBLREL_MSGTYPE
:
116 Mpls_encodeLdpLbl_W_R_Msg(&msg
->u
.release
, bodyBuf
, bodyBuf_size
);
118 case MPLS_LBLABORT_MSGTYPE
:
120 Mpls_encodeLdpLblAbortMsg(&msg
->u
.abort
, bodyBuf
, bodyBuf_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
));
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
));
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
));
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
));
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
));
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
));
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
));
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
));
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
));
196 Mpls_encodeLdpMsgHeader(&msg
->header
, hdrBuf
, hdrBuf_size
)) < 0) {
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
));
210 mpls_return_enum
ldp_decode_header(ldp_global
* g
, ldp_buf
* b
, ldp_mesg
* msg
)
214 LDP_ENTER(g
->user_data
, "ldp_decode_header");
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");
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");
236 int ldp_decode_one_mesg(ldp_global
* g
, ldp_buf
* b
, ldp_mesg
* msg
)
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");
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
);
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
;
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
;
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
;
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",
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
;
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
;
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
;
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",
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
;
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
;
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",
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
;
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
;
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");
469 LDP_EXIT(g
->user_data
, "ldp_decode_one_mesg - failure");