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(sizeof(ldp_buf
) + size
);
30 b
->buffer
= (uint8_t *) & b
[1];
34 b
->current
= b
->buffer
;
39 void ldp_buf_delete(ldp_buf
* b
)
45 void ldp_buf_dump(mpls_instance_handle handle
, ldp_buf
* b
, int size
)
47 unsigned char *buf
= b
->current
;
51 for (i
= 0; i
< size
; i
++) {
52 LDP_TRACE_OUT(handle
, "%02x ", buf
[i
]);
55 LDP_TRACE_OUT(handle
, "\n");
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
;
76 switch (msg
->u
.generic
.flags
.flags
.msgType
) {
77 case MPLS_INIT_MSGTYPE
:
78 body_size
= Mpls_encodeLdpInitMsg(&msg
->u
.init
, bodyBuf
, bodyBuf_size
);
80 case MPLS_NOT_MSGTYPE
:
81 body_size
= Mpls_encodeLdpNotMsg(&msg
->u
.notif
, bodyBuf
, bodyBuf_size
);
83 case MPLS_KEEPAL_MSGTYPE
:
85 Mpls_encodeLdpKeepAliveMsg(&msg
->u
.keep
, bodyBuf
, bodyBuf_size
);
87 case MPLS_HELLO_MSGTYPE
:
88 body_size
= Mpls_encodeLdpHelloMsg(&msg
->u
.hello
, bodyBuf
, bodyBuf_size
);
90 case MPLS_LBLREQ_MSGTYPE
:
92 Mpls_encodeLdpLblReqMsg(&msg
->u
.request
, bodyBuf
, bodyBuf_size
);
94 case MPLS_LBLMAP_MSGTYPE
:
95 body_size
= Mpls_encodeLdpLblMapMsg(&msg
->u
.map
, bodyBuf
, bodyBuf_size
);
97 case MPLS_ADDR_MSGTYPE
:
98 case MPLS_ADDRWITH_MSGTYPE
:
99 body_size
= Mpls_encodeLdpAdrMsg(&msg
->u
.addr
, bodyBuf
, bodyBuf_size
);
101 case MPLS_LBLWITH_MSGTYPE
:
102 case MPLS_LBLREL_MSGTYPE
:
104 Mpls_encodeLdpLbl_W_R_Msg(&msg
->u
.release
, bodyBuf
, bodyBuf_size
);
106 case MPLS_LBLABORT_MSGTYPE
:
108 Mpls_encodeLdpLblAbortMsg(&msg
->u
.abort
, bodyBuf
, bodyBuf_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
));
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
));
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
));
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
));
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
));
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
));
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
));
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
));
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
));
184 Mpls_encodeLdpMsgHeader(&msg
->header
, hdrBuf
, hdrBuf_size
)) < 0) {
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
));
198 mpls_return_enum
ldp_decode_header(ldp_global
* g
, ldp_buf
* b
, ldp_mesg
* msg
)
202 LDP_ENTER(g
->user_data
, "ldp_decode_header");
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");
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");
224 int ldp_decode_one_mesg(ldp_global
* g
, ldp_buf
* b
, ldp_mesg
* msg
)
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");
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
);
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
;
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
;
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
;
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",
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
;
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
;
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
;
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",
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
;
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
;
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",
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
;
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
;
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");
457 LDP_EXIT(g
->user_data
, "ldp_decode_one_mesg - failure");