/* * Copyright (C) James R. Leu 2000 * jleu@mindspring.com * * This software is covered under the LGPL, for more * info check out http://www.gnu.org/copyleft/lgpl.html */ #include #include #include "ldp_struct.h" #include "ldp_assert.h" #include "ldp_msg.h" #include "ldp_pdu.h" #include "ldp_mm_impl.h" #include "ldp_socket_impl.h" #include "ldp_msg_alloc.h" #include "ldp_trace_impl.h" ldp_return_enum ldp_msg_send_tcp(ldp_global* g,ldp_session* s,ldp_msg* msg) { uint32_t buffer_size = 0; uint8_t *buffer = NULL; int32_t pdu_size = 0; uint16_t label_space = 0; ldp_entity* e = NULL; int32_t result = 0; LDP_ASSERT(s != NULL); e = s->entity; LDP_ASSERT(e != NULL); switch(e->entity_type) { case LDP_DIRECT: LDP_ASSERT(e->p.iff != NULL); buffer_size = e->p.iff->buffer_size; buffer = e->p.iff->buffer; label_space = e->p.iff->label_space; break; case LDP_INDIRECT: LDP_ASSERT(e->p.peer != NULL); buffer_size = e->p.peer->buffer_size; buffer = e->p.peer->buffer; label_space = e->p.peer->label_space; break; default: LDP_ASSERT(0); } pdu_size = Mpls_encodeLdpPDU(g,g->lsr_identifier.u.ipv4,label_space,msg, buffer,buffer_size); if(pdu_size <= 0) return LDP_FAILURE; result = ldp_socket_tcp_write(g->socket_handle,s->socket,buffer,pdu_size); if(result <= 0) { LDP_PRINT(g->user_data,"send failed(%d)\n",result); perror("send"); return LDP_FAILURE; } return LDP_SUCCESS; } ldp_return_enum ldp_msg_send_udp(ldp_global* g,ldp_entity* e,ldp_msg* msg) { uint8_t *buffer = NULL; uint32_t buffer_size = 0; ldp_dest *dest = NULL; int32_t pdu_size = 0; int32_t result = 0; uint16_t label_space = 0; LDP_ASSERT(e != NULL); switch(e->entity_type) { case LDP_DIRECT: LDP_ASSERT(e->p.iff != NULL); if(ldp_socket_multicast_if_tx(g->socket_handle,g->hello_socket, e->p.iff) == LDP_FAILURE) { LDP_PRINT(g->user_data,"ldp_msg_send_udp: muticast tx error(%d)\n", ldp_socket_get_errno(g->socket_handle,g->hello_socket)); return LDP_FAILURE; } dest = &e->p.iff->dest; buffer_size = e->p.iff->buffer_size; buffer = e->p.iff->buffer; label_space = e->p.iff->label_space; break; case LDP_INDIRECT: LDP_ASSERT(e->p.peer != NULL); dest = &e->p.peer->dest; buffer_size = e->p.peer->buffer_size; buffer = e->p.peer->buffer; label_space = e->p.peer->label_space; break; default: LDP_ASSERT(0); } pdu_size = Mpls_encodeLdpPDU(g,g->lsr_identifier.u.ipv4,label_space,msg, buffer,buffer_size); if(pdu_size <= 0) return LDP_FAILURE; result = ldp_socket_udp_sendto(g->socket_handle,g->hello_socket,buffer, pdu_size,dest); switch(e->entity_type) { case LDP_DIRECT: ldp_socket_multicast_if_tx(g->socket_handle,g->hello_socket,NULL); break; case LDP_INDIRECT: break; default: LDP_ASSERT(0); } if(result < 0) { LDP_PRINT(g->user_data,"sendto failed(%d)\n",result); perror("sendto"); return LDP_FAILURE; } return LDP_SUCCESS; } ldp_msg *ldp_msg_create(uint16_t type,uint32_t id) { ldp_msg *msg = (ldp_msg*)ldp_malloc(sizeof(ldp_msg)); if(msg == NULL) { return NULL; } msg->hdr = NULL; msg->type = type; switch(type) { case MPLS_INIT_MSGTYPE: msg->body = (mplsLdpMsg_t*)allocLdpInit(id); break; case MPLS_NOT_MSGTYPE: msg->body = (mplsLdpMsg_t*)allocLdpNotify(id); break; case MPLS_KEEPAL_MSGTYPE: msg->body = (mplsLdpMsg_t*)allocLdpKeepalive(id); break; case MPLS_HELLO_MSGTYPE: msg->body = (mplsLdpMsg_t*)allocLdpHello(id); break; case MPLS_LBLREQ_MSGTYPE: msg->body = (mplsLdpMsg_t*)allocLdpLabelRequest(id); break; case MPLS_LBLMAP_MSGTYPE: msg->body = (mplsLdpMsg_t*)allocLdpLabelMapping(id); break; case MPLS_ADDR_MSGTYPE: msg->body = (mplsLdpMsg_t*)allocLdpAddr(id); break; case MPLS_ADDRWITH_MSGTYPE: msg->body = (mplsLdpMsg_t*)allocLdpAddrWith(id); break; case MPLS_LBLWITH_MSGTYPE: msg->body = (mplsLdpMsg_t*)allocLdpLabelWithdraw(id); break; case MPLS_LBLREL_MSGTYPE: msg->body = (mplsLdpMsg_t*)allocLdpLabelRelease(id); break; case MPLS_LBLABORT_MSGTYPE: msg->body = (mplsLdpMsg_t*)allocLdpLabelAbort(id); break; default: msg->body = NULL; return msg; } if(msg->body == NULL) { ldp_free(msg); return NULL; } return msg; } void ldp_msg_delete(ldp_msg *msg) { if(msg != NULL) { if(msg->body != NULL) { ldp_free(msg->body); msg->body = NULL; } if(msg->hdr != NULL) { ldp_free(msg->hdr); msg->hdr = NULL; } ldp_free(msg); } } ldp_return_enum ldp_msg_hdr_get_lsraddr(ldp_msg *msg,ldp_inet_addr *lsraddr) { if(msg == NULL || msg->hdr == NULL || lsraddr == NULL) return LDP_FAILURE; lsraddr->protocol = AF_INET; lsraddr->u.ipv4 = msg->hdr->lsrAddress; return LDP_SUCCESS; } ldp_return_enum ldp_msg_hdr_get_labelspace(ldp_msg *msg,int *labelspace) { if(msg == NULL || msg->hdr == NULL || labelspace == NULL) return LDP_FAILURE; *labelspace = msg->hdr->labelSpace; return LDP_SUCCESS; } uint16_t ldp_msg_get_type(ldp_msg *msg) { if(msg == NULL || msg->body == NULL) return 0; return msg->body->flags.flags.msgType; } ldp_return_enum ldp_msg_hello_get_traddr(ldp_msg *msg,ldp_inet_addr *traddr) { MPLS_MSGPTR(Hello); if(msg == NULL || msg->body == NULL || traddr == NULL) return LDP_FAILURE; MPLS_MSGCAST(Hello,msg->body); if(!MPLS_MSGPARAM(Hello)->trAdrTlvExists) return LDP_FAILURE; traddr->protocol = AF_INET; traddr->u.ipv4 = MPLS_MSGPARAM(Hello)->trAdr.address; return LDP_SUCCESS; } ldp_return_enum ldp_msg_hello_get_hellotime(ldp_msg *msg,int *hellotime) { MPLS_MSGPTR(Hello); if(msg == NULL || msg->body == NULL || hellotime == NULL) return LDP_FAILURE; MPLS_MSGCAST(Hello,msg->body); if(!MPLS_MSGPARAM(Hello)->chpTlvExists) return LDP_FAILURE; *hellotime = MPLS_MSGPARAM(Hello)->chp.holdTime; return LDP_SUCCESS; } ldp_return_enum ldp_msg_hello_get_csn(ldp_msg *msg,uint32_t *csn) { MPLS_MSGPTR(Hello); if(msg == NULL || msg->body == NULL || csn == NULL) return LDP_FAILURE; MPLS_MSGCAST(Hello,msg->body); if(!MPLS_MSGPARAM(Hello)->csnTlvExists) return LDP_FAILURE; *csn = MPLS_MSGPARAM(Hello)->csn.seqNumber; return LDP_SUCCESS; } ldp_return_enum ldp_msg_hello_get_request(ldp_msg *msg,int *req) { MPLS_MSGPTR(Hello); if(msg == NULL || msg->body == NULL || req == NULL) return LDP_FAILURE; MPLS_MSGCAST(Hello,msg->body); *req = MPLS_MSGPARAM(Hello)->chp.flags.flags.request; return LDP_SUCCESS; } ldp_return_enum ldp_msg_hello_get_targeted(ldp_msg *msg,int *tar) { MPLS_MSGPTR(Hello); if(msg == NULL || msg->body == NULL || tar == NULL) return LDP_FAILURE; MPLS_MSGCAST(Hello,msg->body); *tar = MPLS_MSGPARAM(Hello)->chp.flags.flags.target; return LDP_SUCCESS; }