📄 ldp_nortel.c
字号:
/******************************************************************************* Nortel Networks Software License ** ** READ THE TERMS OF THIS LICENSE CAREFULLY. BY USING, MODIFYING, OR ** DISTRIBUTING THIS SOFTWARE AND ANY ACCOMPANYING DOCUMENTATION (COLLECTIVELY,** "SOFTWARE") YOU ARE AGREEING TO ALL OF THE TERMS OF THIS LICENSE. ** ** 1. Nortel Telecom Limited, on behalf of itself and its subsidiaries ** (collectively "Nortel Networks") grants to you a non-exclusive, perpetual, ** world-wide right to use, copy, modify, and distribute the Software at no ** charge. ** ** 2. You may sublicense recipients of redistributed Software to use, ** copy, modify, and distribute the Software on substantially the same terms as** this License. You may not impose any further restrictions on the ** recipient's exercise of the rights in the Software granted under this ** License. Software distributed to other parties must be accompanied by a ** License containing a grant, disclaimer and limitation of liability ** substantially in the form of 3, 4, and 5 below provided that references to ** "Nortel Networks" may be changed to "Supplier". ** ** 3. Nortel Networks reserves the right to modify and release new ** versions of the Software from time to time which may include modifications ** made by third parties like you. Accordingly, you agree that you shall ** automatically grant a license to Nortel Networks to include, at its option, ** in any new version of the Software any modifications to the Software made by** you and made available directly or indirectly to Nortel Networks. Nortel ** Networks shall have the right to use, copy, modify, and distribute any such ** modified Software on substantially the same terms as this License. ** ** 4. THE SOFTWARE IS PROVIDED ON AN "AS IS" BASIS. NORTEL NETWORKS AND ** ITS AGENTS AND SUPPLIERS DISCLAIM ALL REPRESENTATIONS, WARRANTIES AND ** CONDITIONS RELATING TO THE SOFTWARE, INCLUDING, BUT NOT LIMITED TO, IMPLIED ** WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ** NON-INFRINGEMENT OF THIRD-PARTY INTELLECTUAL PROPERTY RIGHTS. NORTEL ** NETWORKS AND ITS AGENTS AND SUPPLIERS DO NOT WARRANT, GUARANTEE, OR MAKE ANY** REPRESENTATIONS REGARDING THE USE, OR THE RESULTS OF THE USE, OF THE ** SOFTWARE IN TERMS OR CORRECTNESS, ACCURACY, RELIABILITY, CURRENTNESS, OR ** OTHERWISE. ** ** 5. NEITHER NORTEL NETWORKS NOR ANY OF ITS AGENTS OR SUPPLIERS SHALL BE ** LIABLE FOR ANY DIRECT, INDIRECT, CONSEQUENTIAL, INCIDENTAL OR EXEMPLARY ** DAMAGES, OR ECONOMIC LOSSES (INCLUDING DAMAGES FOR LOSS OF BUSINESS PROFITS,** BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION AND THE LIKE), ARISING ** FROM THE SOFTWARE OR THIS LICENSE AGREEMENT, EVEN IF NORTEL NETWORKS OR SUCH** AGENT OR SUPPLIER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES OR ** LOSSES, AND WHETHER ANY SUCH DAMAGE OR LOSS ARISES OUT OF CONTRACT, TORT, OR** OTHERWISE. ** ** 6. This License shall be governed by the laws of the Province of ** Ontario, Canada. ********************************************************************************//****************************************************************************** * This file contains the C implementation for encode/decode functions * * for the following types of messages: notification, hello, initialization, * * keepAlive, address, address Withdraw, label Mapping, label Request, label * * Withdraw and label Release. There are also encode/decode methods for all * * tlv types required by the previously enumerated messages. * * Please remember that the pdu will always contain the header followed by 1 * * or more LDP messages. The file contains functions to encode/decode the LDP * * header as well. * * All the messages, header message and the tlvs are in conformity with the * * draft-ietf-mpls-ldp-04 (May 1999) and with draft-ietf-mpls-cr-ldp-01 * * (Jan 1999). * * * * Please note that the U bit in the message and the F bit in the tlv are * * ignored in this version of the code. * * * * Please note that the traffic parameters for traffic TLV have to be IEEE * * single precision floating point numbers. * * * * Please note that there might be a small chance for bit field manipulation * * portability inconsistency. If such problems occure, the code requires * * changes for a suitable bit-field manipulation. The code for encoding and * * decoding makes the assumption that the compiler packs the bit fields in a * * structure into adjacent bits of the same unit. * * * * The usage of the encode/decode functions is described below. * * * * The encode functions take as arguments: a pointer to the structure which * * implements msg/tlv, a buffer (where the encoding is done) and the buffer * * length. * * If the encode is successfull, the function returns the total encoded * * length. * * If the encode fails, the function returns an error code. * * The encode functions for messages and message headers do not modify the * * content of the struct which is to be encoded. All the other encode * * functions will change the content of the structure. The pointer which * * points to the beginning of the buffer is not changed. * * * * The decode functions take as arguments: a pointer to the structure which * * is going to be populated after decoding, a pointer to a buffer and the * * buffer length. * * If the decode is successful, the function returns the total decoded length * * If the decode fails, the function returns an error code. The decode * * functions do not modify the pointer to the buffer which contains the data * * to be decoded. * * * * Example on how to use the encode/decode functions for a keepAlive message: * * * * Encode the keep alive message: * * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ * * u_char buffer[500]; * * int returnCode; * * struct mplsLdpKeepAlMsg_s keepAliveMsg; * * keepAliveMsg.baseMsg.msgType = MPLS_KEEPAL_MSGTYPE; * * keepAliveMsg.baseMsg.msgLength = MPLS_MSGIDFIXLEN; * * keepAliveMsg.baseMsg.msgId = 123; * * memset(buffer, 0, 500); * * returnCode = Mpls_encodeLdpKeepAliveMsg(&keepAliveMsg, * * buffer, * * 500); * * if (returnCode < 0) * * check the error code * * else * * write(fd, buffer, returnCode); * * * * * * Decode the keep alive meesage: * * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ * * u_char buffer[500]; * * int returnCode; * * struct mplsLdpKeepAlMsg_s keepAliveMsg; * * read(fd, buffer, length); * * returnCode = Mpls_decodeLdpKeepAliveMsg(&keepAliveMsg, * * buffer, * * 500); * * if (returnCode < 0) * * check the error code * * else * * { * * printKeepAliveMsg(&keepAliveMsg); * * } * * * * An example on how to use the decode functions for the header and the * * messages can be found in the main function. * * * * The code was tested for big endian and little endian for sparc5, linux * * and i960. * * * * In order to compile for little endian, the LITTLE_ENDIAN_BYTE_ORDER should * * be defined. * * * * At the end of this file there is an examples of a hex buffers and its * * corresponding values. * * * * * * Version History * * Version Date Authors Description * * =========== ======== ========= ====================== * * mpls_encdec_01.c 99/03/15 Antonela Paraschiv draft-ietf-mpls-ldp-03 and * * draft-ietf-mpls-cr-ldp-01 * * * * mpls_encdec_02.c 99/05/19 Antonela Paraschiv draft-ietf-mpls-ldp-04 and * * draft-ietf-mpls-cr-ldp-01 * * * ******************************************************************************/#ifdef VXWORKS#include <in.h> /* htons, htonl, ntohs, ntohl */#include <types.h> /* u_int, u_char, u_short, float etc. */#else#include <netinet/in.h> /* htons, htonl, ntohs, ntohl */#include <sys/types.h> /* u_int, u_char, u_short, float etc. */#endif /* VXWORKS */#include "ldp_struct.h"#include "mpls_trace_impl.h"#include "ldp_nortel.h"int global_ldp_pdu_debug = 0;/* * Encode-decode for Ldp Msg Header *//* * Encode: */int Mpls_encodeLdpMsgHeader (mplsLdpHeader_t * header, u_char * buff, int bufSize) { mplsLdpHeader_t headerCopy; if (MPLS_LDP_HDRSIZE > bufSize) { /* not enough room for header */ return MPLS_ENC_BUFFTOOSMALL; } headerCopy = *header; headerCopy.protocolVersion = htons(headerCopy.protocolVersion); headerCopy.pduLength = htons(headerCopy.pduLength); headerCopy.lsrAddress = htonl(headerCopy.lsrAddress); headerCopy.labelSpace = htons(headerCopy.labelSpace); MEM_COPY(buff, (u_char *) & headerCopy, MPLS_LDP_HDRSIZE); return MPLS_LDP_HDRSIZE;} /* End : Mpls_encodeLdpMsgHeader *//* * Decode: */int Mpls_decodeLdpMsgHeader (mplsLdpHeader_t * header, u_char * buff, int bufSize) { if (MPLS_LDP_HDRSIZE > bufSize) { return MPLS_DEC_BUFFTOOSMALL; } MEM_COPY((u_char *) header, buff, MPLS_LDP_HDRSIZE); header->protocolVersion = ntohs(header->protocolVersion); header->pduLength = ntohs(header->pduLength); header->lsrAddress = ntohl(header->lsrAddress); header->labelSpace = ntohs(header->labelSpace); /* check if the length is over the max length */ if (header->pduLength > MPLS_PDUMAXLEN) { return MPLS_PDU_LENGTH_ERROR; } return MPLS_LDP_HDRSIZE;} /* End: Mpls_decodeLdpMsgHeader *//* * Encode-decode for Ldp Base Message *//* * Encode: */int Mpls_encodeLdpBaseMsg(mplsLdpMsg_t * ldpMsg, u_char * buff, int bufSize){ if (MPLS_MSGIDFIXLEN + MPLS_TLVFIXLEN > bufSize) { /* not enough room for header */ return MPLS_ENC_BUFFTOOSMALL; } ldpMsg->flags.mark = htons(ldpMsg->flags.mark); ldpMsg->msgLength = htons(ldpMsg->msgLength); ldpMsg->msgId = htonl(ldpMsg->msgId); MEM_COPY(buff, (u_char *) ldpMsg, MPLS_MSGIDFIXLEN + MPLS_TLVFIXLEN); return (MPLS_MSGIDFIXLEN + MPLS_TLVFIXLEN);} /* End : Mpls_encodeLdpBaseMsg *//* * Decode: */int Mpls_decodeLdpBaseMsg(mplsLdpMsg_t * ldpMsg, u_char * buff, int bufSize){ if (MPLS_MSGIDFIXLEN + MPLS_TLVFIXLEN > bufSize) { return MPLS_DEC_BUFFTOOSMALL; } MEM_COPY((u_char *) ldpMsg, buff, MPLS_MSGIDFIXLEN + MPLS_TLVFIXLEN); ldpMsg->flags.mark = ntohs(ldpMsg->flags.mark); ldpMsg->msgLength = ntohs(ldpMsg->msgLength); ldpMsg->msgId = ntohl(ldpMsg->msgId); return MPLS_MSGIDFIXLEN + MPLS_TLVFIXLEN;} /* End: Mpls_decodeLdpBaseMsg *//* * Encode-decode for ATM Label Range Component *//* * encode: */int Mpls_encodeLdpAtmLblRng (mplsLdpAtmLblRng_t * atmLbl, u_char * buff, int bufSize) { if (MPLS_ATMLRGFIXLEN > bufSize) { /* not enough room for label */ return MPLS_ENC_BUFFTOOSMALL; } atmLbl->flags.flags.res1 = 0; atmLbl->flags.flags.res2 = 0; atmLbl->flags.mark[0] = htonl(atmLbl->flags.mark[0]); atmLbl->flags.mark[1] = htonl(atmLbl->flags.mark[1]); MEM_COPY(buff, (u_char *) atmLbl, MPLS_ATMLRGFIXLEN); return MPLS_ATMLRGFIXLEN;} /* End Mpls_encodeLdpAtmLblRng *//* * decode: */int Mpls_decodeLdpAtmLblRng (mplsLdpAtmLblRng_t * atmLbl, u_char * buff, int bufSize) { if (MPLS_ATMLRGFIXLEN > bufSize) { PRINT_ERR("failed decoding the Atm Lbl Rng\n"); return MPLS_DEC_BUFFTOOSMALL; } MEM_COPY((u_char *) atmLbl, buff, MPLS_ATMLRGFIXLEN); atmLbl->flags.mark[0] = ntohl(atmLbl->flags.mark[0]); atmLbl->flags.mark[1] = ntohl(atmLbl->flags.mark[1]); return MPLS_ATMLRGFIXLEN;} /* End Mpls_decodeLdpAtmLblRng *//* * Encode-decode for ATM Session Parameters *//* * encode: */int Mpls_encodeLdpAsp(mplsLdpAspTlv_t * atmAsp, u_char * buff, int bufSize){ int encodedSize = 0; u_short totalSize = 0; u_char *tempBuf = buff; /* no change for the buff ptr */ u_int i, numLblRng; /* get the size of the atmAsp to be encoded and check it against the buffer size */ if (MPLS_TLVFIXLEN + (int)(atmAsp->baseTlv.length) > bufSize) { /* not enough room */ return MPLS_ENC_BUFFTOOSMALL; } /* * encode for tlv */ encodedSize = Mpls_encodeLdpTlv(&(atmAsp->baseTlv), tempBuf, bufSize); if (encodedSize < 0) { return MPLS_ENC_TLVERROR; } tempBuf += encodedSize; totalSize += encodedSize; /* * encode for M + N + D + res */ numLblRng = atmAsp->flags.flags.numLblRng; atmAsp->flags.flags.res = 0; atmAsp->flags.mark = htonl(atmAsp->flags.mark); MEM_COPY(tempBuf, (u_char *) & (atmAsp->flags.mark), MPLS_ASPFIXLEN); tempBuf += MPLS_ASPFIXLEN; totalSize += MPLS_ASPFIXLEN; /* * encode for ATM labels */ for (i = 0; i < numLblRng; i++) { encodedSize = Mpls_encodeLdpAtmLblRng(&(atmAsp->lblRngList[i]), tempBuf, bufSize - totalSize); if (encodedSize < 0) { return MPLS_ENC_ATMLBLERROR; } tempBuf += encodedSize; totalSize += encodedSize; } return totalSize;} /* End Mpls_encodeLdpAsp *//* * decode: */int Mpls_decodeLdpAsp(mplsLdpAspTlv_t * atmAsp, u_char * buff, int bufSize){ int decodedSize = 0; u_short totalSize = 0; u_char *tempBuf = buff; /* no change for the buff ptr */ u_int i; if (MPLS_ASPFIXLEN > bufSize) { /* the buffer does not contain even the required field */ PRINT_ERR("failed in decoding LdpAsp\n"); return MPLS_DEC_BUFFTOOSMALL; } /* * decode for M + N + D + res */ MEM_COPY((u_char *) & (atmAsp->flags.mark), tempBuf, MPLS_ASPFIXLEN); tempBuf += MPLS_ASPFIXLEN; totalSize += MPLS_ASPFIXLEN; atmAsp->flags.mark = ntohl(atmAsp->flags.mark); /* * decode for ATM labels */ for (i = 0; i < atmAsp->flags.flags.numLblRng; i++) { decodedSize = Mpls_decodeLdpAtmLblRng(&(atmAsp->lblRngList[i]), tempBuf, bufSize - totalSize); if (decodedSize < 0) { PRINT_ERR("failed in decoding LdpAtmLabel[%d] for LdpAsp\n", i); return MPLS_DEC_ATMLBLERROR; } tempBuf += decodedSize; totalSize += decodedSize; } return totalSize;} /* End Mpls_decodeLdpAsp *//* * Encode-decode for TLV *//* * encode: */int Mpls_encodeLdpTlv(mplsLdpTlv_t * tlv, u_char * buff, int bufSize){ if (MPLS_TLVFIXLEN > bufSize) { /* not enough room for label */ return MPLS_ENC_BUFFTOOSMALL; } tlv->flags.mark = htons(tlv->flags.mark);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -