init.c revision 1.3
1/* $OpenBSD: init.c,v 1.3 2010/02/20 21:28:39 michele Exp $ */ 2 3/* 4 * Copyright (c) 2009 Michele Marchetto <michele@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19#include <sys/types.h> 20#include <sys/socket.h> 21#include <sys/uio.h> 22 23#include <netinet/in.h> 24#include <netinet/in_systm.h> 25#include <netinet/ip.h> 26#include <arpa/inet.h> 27#include <net/if_dl.h> 28#include <unistd.h> 29 30#include <errno.h> 31#include <event.h> 32#include <stdlib.h> 33#include <string.h> 34 35#include "ldpd.h" 36#include "ldp.h" 37#include "log.h" 38#include "ldpe.h" 39 40int gen_init_prms_tlv(struct buf *, struct nbr *, u_int16_t); 41 42void 43send_init(struct nbr *nbr) 44{ 45 struct buf *buf; 46 u_int16_t size; 47 48 if (nbr->iface->passive) 49 return; 50 51 log_debug("send_init: neighbor ID %s", inet_ntoa(nbr->id)); 52 53 if ((buf = buf_open(LDP_MAX_LEN)) == NULL) 54 fatal("send_init"); 55 56 size = LDP_HDR_SIZE + sizeof(struct ldp_msg) + SESS_PRMS_SIZE; 57 58 gen_ldp_hdr(buf, nbr->iface, size); 59 60 size -= LDP_HDR_SIZE; 61 62 gen_msg_tlv(buf, MSG_TYPE_INIT, size); 63 64 size -= sizeof(struct ldp_msg); 65 66 gen_init_prms_tlv(buf, nbr, size); 67 68 bufferevent_write(nbr->bev, buf->buf, buf->wpos); 69 buf_free(buf); 70} 71 72int 73recv_init(struct nbr *nbr, char *buf, u_int16_t len) 74{ 75 struct ldp_msg *init; 76 struct sess_prms_tlv *sess_tlv; 77 78 log_debug("recv_init: neighbor ID %s", inet_ntoa(nbr->id)); 79 80 init = (struct ldp_msg *)buf; 81 82 if ((len - TLV_HDR_LEN) < ntohs(init->length)) { 83 session_shutdown(nbr, S_BAD_MSG_LEN, init->msgid, init->type); 84 return (-1); 85 } 86 87 buf += sizeof(struct ldp_msg); 88 len -= sizeof(struct ldp_msg); 89 90 sess_tlv = (struct sess_prms_tlv *)buf; 91 92 if (len < SESS_PRMS_SIZE || 93 ntohs(sess_tlv->length) != (SESS_PRMS_SIZE - TLV_HDR_LEN)) { 94 session_shutdown(nbr, S_BAD_TLV_LEN, init->msgid, init->type); 95 return (-1); 96 } 97 98 if (nbr->iface->keepalive < ntohs(sess_tlv->keepalive_time)) 99 nbr->keepalive = nbr->iface->keepalive; 100 else 101 nbr->keepalive = ntohs(sess_tlv->keepalive_time); 102 103 nbr_fsm(nbr, NBR_EVT_INIT_RCVD); 104 105 return (ntohs(init->length)); 106} 107 108int 109gen_init_prms_tlv(struct buf *buf, struct nbr *nbr, u_int16_t size) 110{ 111 struct sess_prms_tlv parms; 112 113 /* We want just the size of the value */ 114 size -= TLV_HDR_LEN; 115 116 bzero(&parms, sizeof(parms)); 117 parms.type = htons(TLV_TYPE_COMMONSESSION); 118 parms.length = htons(size); 119 parms.proto_version = htons(LDP_VERSION); 120 parms.keepalive_time = htons(nbr->iface->keepalive); 121 parms.reserved = 0; 122 parms.pvlim = 0; 123 parms.max_pdu_len = 0; 124 parms.lsr_id = nbr->id.s_addr; 125 /* XXX: nbr lspace */ 126 parms.lspace_id = 0; 127 128 return (buf_add(buf, &parms, SESS_PRMS_SIZE)); 129} 130