summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2010-11-04 09:52:17 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2010-11-04 09:52:17 +0000
commitf43f9ad39dccdded320e0038181cb93f2586f9dd (patch)
tree1cd9a589d4c5ec3b1d050e521bcd77d03850c8c6
parent399e2bd2fdd1d1bfede26dda086423c31e1000bc (diff)
Rewrite all packet parsers to be more careful about alignment. Until
now ldpd had no chance to run on a strict alignment architecture but this makes ldpd happy on sparc64. Be careful to do all needed overflow checks and try to make all parsing functions look similar. OK michele@
-rw-r--r--usr.sbin/ldpd/address.c127
-rw-r--r--usr.sbin/ldpd/hello.c120
-rw-r--r--usr.sbin/ldpd/init.c33
-rw-r--r--usr.sbin/ldpd/keepalive.c15
-rw-r--r--usr.sbin/ldpd/labelmapping.c393
-rw-r--r--usr.sbin/ldpd/ldp.h14
-rw-r--r--usr.sbin/ldpd/ldpe.h3
-rw-r--r--usr.sbin/ldpd/notification.c38
-rw-r--r--usr.sbin/ldpd/packet.c33
9 files changed, 404 insertions, 372 deletions
diff --git a/usr.sbin/ldpd/address.c b/usr.sbin/ldpd/address.c
index e0bf23d0e11..0c456e91827 100644
--- a/usr.sbin/ldpd/address.c
+++ b/usr.sbin/ldpd/address.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: address.c,v 1.5 2010/05/26 13:56:07 nicm Exp $ */
+/* $OpenBSD: address.c,v 1.6 2010/11/04 09:52:16 claudio Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
@@ -83,61 +83,67 @@ send_address(struct nbr *nbr, struct iface *iface)
int
recv_address(struct nbr *nbr, char *buf, u_int16_t len)
{
- struct ldp_msg *addr;
- struct address_list_tlv *alt;
- struct in_addr *address;
- u_int32_t addrs_len;
+ struct ldp_msg addr;
+ struct address_list_tlv alt;
+ enum imsg_type type;
- log_debug("recv_address: neighbor ID %s", inet_ntoa(nbr->id));
-
- if (nbr->state != NBR_STA_OPER)
- return (-1);
-
- addr = (struct ldp_msg *)buf;
-
- if ((len - TLV_HDR_LEN) < ntohs(addr->length)) {
- session_shutdown(nbr, S_BAD_MSG_LEN, addr->msgid, addr->type);
+ if (nbr->state != NBR_STA_OPER) {
+ log_debug("recv_address: neighbor ID %s not operational",
+ inet_ntoa(nbr->id));
return (-1);
}
+ bcopy(buf, &addr, sizeof(addr));
+ log_debug("recv_address: neighbor ID %s%s", inet_ntoa(nbr->id),
+ ntohs(addr.type) == MSG_TYPE_ADDR ? "" : " address withdraw");
+ if (ntohs(addr.type) == MSG_TYPE_ADDR)
+ type = IMSG_ADDRESS_ADD;
+ else
+ type = IMSG_ADDRESS_DEL;
+
buf += sizeof(struct ldp_msg);
len -= sizeof(struct ldp_msg);
- alt = (struct address_list_tlv *)buf;
-
- if (len < sizeof(*alt) ||
- (len - TLV_HDR_LEN) < ntohs(alt->length)) {
- session_shutdown(nbr, S_BAD_TLV_LEN, addr->msgid, addr->type);
+ if (len < sizeof(alt)) {
+ session_shutdown(nbr, S_BAD_MSG_LEN, addr.msgid, addr.type);
return (-1);
}
- addrs_len = (ntohs(alt->length) - sizeof(alt->family));
+ bcopy(buf, &alt, sizeof(alt));
+
+ if (ntohs(alt.length) != len - TLV_HDR_LEN) {
+ session_shutdown(nbr, S_BAD_TLV_LEN, addr.msgid, addr.type);
+ return (-1);
+ }
- if (alt->type != TLV_TYPE_ADDRLIST) {
- session_shutdown(nbr, S_UNKNOWN_TLV, addr->msgid, addr->type);
+ if (ntohs(alt.type) != TLV_TYPE_ADDRLIST) {
+ session_shutdown(nbr, S_UNKNOWN_TLV, addr.msgid, addr.type);
return (-1);
}
/* For now we only support IPv4 */
- if (alt->family != htons(ADDR_IPV4)) {
- send_notification_nbr(nbr, S_UNSUP_ADDR, addr->msgid,
- addr->type);
+ if (alt.family != htons(ADDR_IPV4)) {
+ send_notification_nbr(nbr, S_UNSUP_ADDR, addr.msgid, addr.type);
return (-1);
}
- buf += sizeof(*alt);
- len -= sizeof(*alt);
- address = (struct in_addr *)buf;
+ buf += sizeof(alt);
+ len -= sizeof(alt);
- while (addrs_len >= sizeof(address)) {
- ldpe_imsg_compose_lde(IMSG_ADDRESS_ADD, nbr->peerid, 0,
- address, sizeof(*address));
+ while (len >= sizeof(struct in_addr)) {
+ ldpe_imsg_compose_lde(type, nbr->peerid, 0,
+ buf, sizeof(struct in_addr));
- address++;
- addrs_len -= sizeof(*address);
+ buf += sizeof(struct in_addr);
+ len -= sizeof(struct in_addr);
}
- return (ntohs(addr->length));
+ if (len != 0) {
+ session_shutdown(nbr, S_BAD_TLV_LEN, addr.msgid, addr.type);
+ return (-1);
+ }
+
+ return (ntohs(addr.length));
}
void
@@ -193,56 +199,3 @@ send_address_withdraw(struct nbr *nbr, struct iface *iface)
evbuf_enqueue(&nbr->wbuf, buf);
}
-
-int
-recv_address_withdraw(struct nbr *nbr, char *buf, u_int16_t len)
-{
- struct ldp_msg *aw;
- struct address_list_tlv *alt;
- struct in_addr *address;
-
- log_debug("recv_address_withdraw: neighbor ID %s", inet_ntoa(nbr->id));
-
- aw = (struct ldp_msg *)buf;
-
- if ((len - TLV_HDR_LEN) < ntohs(aw->length)) {
- session_shutdown(nbr, S_BAD_MSG_LEN, aw->msgid, aw->type);
- return (-1);
- }
-
- buf += sizeof(struct ldp_msg);
- len -= sizeof(struct ldp_msg);
-
- alt = (struct address_list_tlv *)buf;
-
- if (len < sizeof(*alt) ||
- (len - TLV_HDR_LEN) < ntohs(alt->length)) {
- session_shutdown(nbr, S_BAD_TLV_LEN, aw->msgid, aw->type);
- return (-1);
- }
-
- if (alt->type != TLV_TYPE_ADDRLIST) {
- session_shutdown(nbr, S_UNKNOWN_TLV, aw->msgid, aw->type);
- return (-1);
- }
-
- /* For now we just support IPv4 */
- if (alt->family != AF_INET) {
- send_notification_nbr(nbr, S_UNSUP_ADDR, aw->msgid, aw->type);
- return (-1);
- }
-
- buf += sizeof(*alt);
- len -= sizeof(*alt);
- address = (struct in_addr *)buf;
-
- while (len >= sizeof(address)) {
- ldpe_imsg_compose_lde(IMSG_ADDRESS_DEL, nbr->peerid, 0,
- address, sizeof(*address));
-
- address++;
- len -= sizeof(*address);
- }
-
- return (ntohs(aw->length));
-}
diff --git a/usr.sbin/ldpd/hello.c b/usr.sbin/ldpd/hello.c
index d6cb184727e..4a506c1d6d2 100644
--- a/usr.sbin/ldpd/hello.c
+++ b/usr.sbin/ldpd/hello.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: hello.c,v 1.6 2010/05/26 13:56:07 nicm Exp $ */
+/* $OpenBSD: hello.c,v 1.7 2010/11/04 09:52:16 claudio Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
@@ -36,11 +36,10 @@
#include "log.h"
#include "ldpe.h"
-struct hello_prms_tlv *tlv_decode_hello_prms(char *, u_int16_t);
-int tlv_decode_opt_hello_prms(char *, u_int16_t,
- struct in_addr *, u_int32_t *);
-int gen_hello_prms_tlv(struct iface *, struct ibuf *,
- u_int16_t);
+int tlv_decode_hello_prms(char *, u_int16_t, u_int16_t *, u_int16_t *);
+int tlv_decode_opt_hello_prms(char *, u_int16_t, struct in_addr *,
+ u_int32_t *);
+int gen_hello_prms_tlv(struct iface *, struct ibuf *, u_int16_t);
int
send_hello(struct iface *iface)
@@ -82,41 +81,50 @@ send_hello(struct iface *iface)
void
recv_hello(struct iface *iface, struct in_addr src, char *buf, u_int16_t len)
{
- struct ldp_msg *hello;
- u_int32_t messageid;
+ struct ldp_msg hello;
+ struct ldp_hdr ldp;
struct nbr *nbr = NULL;
- struct hello_prms_tlv *cpt;
- struct ldp_hdr *ldp;
struct in_addr address;
u_int32_t conf_number;
+ u_int16_t holdtime, flags;
+ int r;
- ldp = (struct ldp_hdr *)buf;
-
+ bcopy(buf, &ldp, sizeof(ldp));
buf += LDP_HDR_SIZE;
len -= LDP_HDR_SIZE;
- hello = (struct ldp_msg *)buf;
-
- if ((len - TLV_HDR_LEN) < ntohs(hello->length))
- return;
-
- messageid = hello->msgid;
-
+ bcopy(buf, &hello, sizeof(hello));
buf += sizeof(struct ldp_msg);
len -= sizeof(struct ldp_msg);
- cpt = tlv_decode_hello_prms(buf, len);
- if (cpt == NULL)
+ r = tlv_decode_hello_prms(buf, len, &holdtime, &flags);
+ if (r == -1) {
+ address.s_addr = ldp.lsr_id;
+ log_debug("recv_hello: neighbor %s: failed to decode params",
+ inet_ntoa(address));
return;
+ }
- buf += sizeof(struct hello_prms_tlv);
- len -= sizeof(struct hello_prms_tlv);
+ buf += r;
+ len -= r;
- tlv_decode_opt_hello_prms(buf, len, &address, &conf_number);
+ r = tlv_decode_opt_hello_prms(buf, len, &address, &conf_number);
+ if (r == -1) {
+ address.s_addr = ldp.lsr_id;
+ log_debug("recv_hello: neighbor %s: failed to decode "
+ "optional params", inet_ntoa(address));
+ return;
+ }
+ if (r != len) {
+ address.s_addr = ldp.lsr_id;
+ log_debug("recv_hello: neighbor %s: unexpected data in message",
+ inet_ntoa(address));
+ return;
+ }
- nbr = nbr_find_ldpid(iface, ldp->lsr_id, ldp->lspace_id);
+ nbr = nbr_find_ldpid(iface, ldp.lsr_id, ldp.lspace_id);
if (!nbr) {
- nbr = nbr_new(ldp->lsr_id, ldp->lspace_id, iface);
+ nbr = nbr_new(ldp.lsr_id, ldp.lspace_id, iface);
/* set neighbor parameters */
if (address.s_addr == INADDR_ANY)
@@ -124,22 +132,22 @@ recv_hello(struct iface *iface, struct in_addr src, char *buf, u_int16_t len)
else
nbr->addr.s_addr = address.s_addr;
- nbr->hello_type = cpt->reserved;
+ nbr->hello_type = flags;
- if (cpt->holdtime == 0) {
+ if (holdtime == 0) {
/* XXX: lacks support for targeted hellos */
if (iface->holdtime < LINK_DFLT_HOLDTIME)
nbr->holdtime = iface->holdtime;
else
nbr->holdtime = LINK_DFLT_HOLDTIME;
- } else if (cpt->holdtime == INFINITE_HOLDTIME) {
+ } else if (holdtime == INFINITE_HOLDTIME) {
/* No timeout for this neighbor */
nbr->holdtime = iface->holdtime;
} else {
- if (iface->holdtime < ntohs(cpt->holdtime))
+ if (iface->holdtime < holdtime)
nbr->holdtime = iface->holdtime;
else
- nbr->holdtime = ntohs(cpt->holdtime);
+ nbr->holdtime = holdtime;
}
}
@@ -163,60 +171,64 @@ gen_hello_prms_tlv(struct iface *iface, struct ibuf *buf, u_int16_t size)
parms.length = htons(size);
/* XXX */
parms.holdtime = htons(iface->holdtime);
- parms.reserved = 0;
+ parms.flags = 0;
return (ibuf_add(buf, &parms, sizeof(parms)));
}
-struct hello_prms_tlv *
-tlv_decode_hello_prms(char *buf, u_int16_t len)
+int
+tlv_decode_hello_prms(char *buf, u_int16_t len, u_int16_t *holdtime,
+ u_int16_t *flags)
{
- struct hello_prms_tlv *tlv;
+ struct hello_prms_tlv tlv;
- tlv = (struct hello_prms_tlv *)buf;
+ if (len < sizeof(tlv))
+ return (-1);
+ bcopy(buf, &tlv, sizeof(tlv));
- if (len < sizeof(*tlv) || ntohs(tlv->length) !=
- (sizeof(tlv->holdtime) + sizeof(tlv->reserved)))
- return (NULL);
+ if (ntohs(tlv.length) != sizeof(tlv) - TLV_HDR_LEN)
+ return (-1);
- if ((tlv->type & ~UNKNOWN_FLAGS_MASK) != htons(TLV_TYPE_COMMONHELLO))
- return (NULL);
+ if (tlv.type != htons(TLV_TYPE_COMMONHELLO))
+ return (-1);
- if ((tlv->type & UNKNOWN_FLAGS_MASK) != 0)
- return (NULL);
+ *holdtime = ntohs(tlv.holdtime);
+ *flags = ntohs(tlv.flags);
- return (tlv);
+ return (sizeof(tlv));
}
int
tlv_decode_opt_hello_prms(char *buf, u_int16_t len, struct in_addr *addr,
u_int32_t *conf_number)
{
- struct hello_opt_parms_tlv *tlv;
+ struct hello_opt_parms_tlv tlv;
+ int cons = 0;
bzero(addr, sizeof(*addr));
*conf_number = 0;
- while (len >= sizeof(*tlv)) {
- tlv = (struct hello_opt_parms_tlv *)buf;
+ while (len >= sizeof(tlv)) {
+ bcopy(buf, &tlv, sizeof(tlv));
- if (tlv->length < sizeof(u_int32_t))
+ if (ntohs(tlv.length) < sizeof(u_int32_t))
return (-1);
- switch (ntohs(tlv->type)) {
+ switch (ntohs(tlv.type)) {
case TLV_TYPE_IPV4TRANSADDR:
- addr->s_addr = tlv->value;
+ addr->s_addr = tlv.value;
break;
case TLV_TYPE_CONFIG:
- *conf_number = ntohl(tlv->value);
+ *conf_number = ntohl(tlv.value);
break;
default:
return (-1);
}
- len -= sizeof(*tlv);
- buf += sizeof(*tlv);
+ len -= sizeof(tlv);
+ buf += sizeof(tlv);
+ cons += sizeof(cons);
}
- return (0);
+ return (cons);
}
diff --git a/usr.sbin/ldpd/init.c b/usr.sbin/ldpd/init.c
index 31556a670e2..2004bc71bcf 100644
--- a/usr.sbin/ldpd/init.c
+++ b/usr.sbin/ldpd/init.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: init.c,v 1.5 2010/05/26 13:56:07 nicm Exp $ */
+/* $OpenBSD: init.c,v 1.6 2010/11/04 09:52:16 claudio Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
@@ -71,37 +71,38 @@ send_init(struct nbr *nbr)
int
recv_init(struct nbr *nbr, char *buf, u_int16_t len)
{
- struct ldp_msg *init;
- struct sess_prms_tlv *sess_tlv;
+ struct ldp_msg init;
+ struct sess_prms_tlv sess;
log_debug("recv_init: neighbor ID %s", inet_ntoa(nbr->id));
- init = (struct ldp_msg *)buf;
-
- if ((len - TLV_HDR_LEN) < ntohs(init->length)) {
- session_shutdown(nbr, S_BAD_MSG_LEN, init->msgid, init->type);
- return (-1);
- }
+ bcopy(buf, &init, sizeof(init));
buf += sizeof(struct ldp_msg);
len -= sizeof(struct ldp_msg);
- sess_tlv = (struct sess_prms_tlv *)buf;
+ if (len < SESS_PRMS_SIZE) {
+ session_shutdown(nbr, S_BAD_MSG_LEN, init.msgid, init.type);
+ return (-1);
+ }
+ bcopy(buf, &sess, sizeof(sess));
- if (len < SESS_PRMS_SIZE ||
- ntohs(sess_tlv->length) != (SESS_PRMS_SIZE - TLV_HDR_LEN)) {
- session_shutdown(nbr, S_BAD_TLV_LEN, init->msgid, init->type);
+ if (ntohs(sess.length) != SESS_PRMS_SIZE - TLV_HDR_LEN ||
+ ntohs(sess.length) != len - TLV_HDR_LEN) {
+ session_shutdown(nbr, S_BAD_TLV_LEN, init.msgid, init.type);
return (-1);
}
- if (nbr->iface->keepalive < ntohs(sess_tlv->keepalive_time))
+ /* ATM and Frame Relay optional attributes not supported */
+
+ if (nbr->iface->keepalive < ntohs(sess.keepalive_time))
nbr->keepalive = nbr->iface->keepalive;
else
- nbr->keepalive = ntohs(sess_tlv->keepalive_time);
+ nbr->keepalive = ntohs(sess.keepalive_time);
nbr_fsm(nbr, NBR_EVT_INIT_RCVD);
- return (ntohs(init->length));
+ return (ntohs(init.length));
}
int
diff --git a/usr.sbin/ldpd/keepalive.c b/usr.sbin/ldpd/keepalive.c
index 2e9152a1b4e..933e3093aaf 100644
--- a/usr.sbin/ldpd/keepalive.c
+++ b/usr.sbin/ldpd/keepalive.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: keepalive.c,v 1.6 2010/05/26 13:56:07 nicm Exp $ */
+/* $OpenBSD: keepalive.c,v 1.7 2010/11/04 09:52:16 claudio Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
@@ -63,22 +63,19 @@ send_keepalive(struct nbr *nbr)
int
recv_keepalive(struct nbr *nbr, char *buf, u_int16_t len)
{
- struct ldp_msg *ka;
+ struct ldp_msg ka;
- ka = (struct ldp_msg *)buf;
+ bcopy(buf, &ka, sizeof(ka));
- if ((len - TLV_HDR_LEN) < ntohs(ka->length)) {
- session_shutdown(nbr, S_BAD_MSG_LEN, ka->msgid, ka->type);
+ if (len != LDP_MSG_LEN) {
+ session_shutdown(nbr, S_BAD_MSG_LEN, ka.msgid, ka.type);
return (-1);
}
- buf += sizeof(struct ldp_msg);
- len -= sizeof(struct ldp_msg);
-
if (nbr->state != NBR_STA_OPER)
nbr_fsm(nbr, NBR_EVT_KEEPALIVE_RCVD);
else
nbr_fsm(nbr, NBR_EVT_PDU_RCVD);
- return (ntohs(ka->length));
+ return (ntohs(ka.length));
}
diff --git a/usr.sbin/ldpd/labelmapping.c b/usr.sbin/ldpd/labelmapping.c
index eb60ecd1e97..8b325cbb908 100644
--- a/usr.sbin/ldpd/labelmapping.c
+++ b/usr.sbin/ldpd/labelmapping.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: labelmapping.c,v 1.16 2010/10/26 12:59:03 claudio Exp $ */
+/* $OpenBSD: labelmapping.c,v 1.17 2010/11/04 09:52:16 claudio Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
@@ -41,10 +41,10 @@ void gen_label_tlv(struct ibuf *, u_int32_t);
void gen_reqid_tlv(struct ibuf *, u_int32_t);
void gen_fec_tlv(struct ibuf *, struct in_addr, u_int8_t);
-u_int32_t tlv_decode_label(struct label_tlv *);
-u_int32_t tlv_decode_reqid(struct reqid_tlv *);
-int tlv_decode_fec_elm(char *, u_int16_t, u_int8_t *, u_int32_t *,
- u_int8_t *);
+int tlv_decode_label(char *, u_int16_t, u_int32_t *);
+int tlv_decode_reqid(char *, u_int16_t, u_int32_t *);
+int tlv_decode_fec_elm(char *, u_int16_t, u_int8_t *, u_int32_t *,
+ u_int8_t *);
/* Label Mapping Message */
void
@@ -91,60 +91,60 @@ send_labelmapping(struct nbr *nbr)
int
recv_labelmapping(struct nbr *nbr, char *buf, u_int16_t len)
{
- struct ldp_msg *lm;
- struct fec_tlv *ft;
- struct label_tlv *lt;
- struct map map;
- int feclen, tlen;
- u_int8_t addr_type;
-
- if (nbr->state != NBR_STA_OPER)
- return (-1);
-
- lm = (struct ldp_msg *)buf;
-
- if ((len - TLV_HDR_LEN) < ntohs(lm->length)) {
- session_shutdown(nbr, S_BAD_MSG_LEN, lm->msgid, lm->type);
+ struct ldp_msg lm;
+ struct fec_tlv ft;
+ struct map map;
+ u_int32_t label;
+ int feclen, lbllen, tlen;
+ u_int8_t addr_type;
+
+ if (nbr->state != NBR_STA_OPER) {
+ log_debug("recv_labelmapping: neighbor ID %s not operational",
+ inet_ntoa(nbr->id));
return (-1);
}
+ bcopy(buf, &lm, sizeof(lm));
+
buf += sizeof(struct ldp_msg);
len -= sizeof(struct ldp_msg);
- ft = (struct fec_tlv *)buf;
-
- if (len < sizeof(*ft) ||
- (len - TLV_HDR_LEN) < ntohs(ft->length)) {
- session_shutdown(nbr, S_BAD_TLV_LEN, lm->msgid, lm->type);
+ if (len < sizeof(ft)) {
+ session_shutdown(nbr, S_BAD_TLV_LEN, lm.msgid, lm.type);
return (-1);
}
- feclen = ntohs(ft->length);
- buf += sizeof(struct fec_tlv);
- len -= sizeof(struct fec_tlv);
+ bcopy(buf, &ft, sizeof(ft));
+ feclen = ntohs(ft.length);
- if (len < feclen + LABEL_TLV_LEN) {
- session_shutdown(nbr, S_BAD_TLV_LEN, lm->msgid, lm->type);
+ if (feclen > len - TLV_HDR_LEN) {
+ session_shutdown(nbr, S_BAD_TLV_LEN, lm.msgid, lm.type);
return (-1);
}
- bzero(&map, sizeof(map));
- map.messageid = lm->msgid;
+ buf += TLV_HDR_LEN; /* just advance to the end of the fec header */
+ len -= TLV_HDR_LEN;
- lt = (struct label_tlv *)(buf + feclen);
- map.label = tlv_decode_label(lt);
- if (map.label == NO_LABEL) {
- session_shutdown(nbr, S_BAD_TLV_VAL, lm->msgid, lm->type);
+ lbllen = tlv_decode_label(buf + feclen, len - feclen, &label);
+ if (lbllen == -1) {
+ session_shutdown(nbr, S_BAD_TLV_LEN, lm.msgid, lm.type);
return (-1);
}
- /* TODO opt label request msg id */
+ if (label == NO_LABEL) {
+ session_shutdown(nbr, S_BAD_TLV_VAL, lm.msgid, lm.type);
+ return (-1);
+ }
+
+ /* TODO opt label request msg id, hop cnt and path vektor TLV */
+ bzero(&map, sizeof(map));
+ map.messageid = lm.msgid;
+ map.label = label;
do {
if ((tlen = tlv_decode_fec_elm(buf, feclen, &addr_type,
&map.prefix.s_addr, &map.prefixlen)) == -1 ||
addr_type == FEC_WILDCARD) {
- session_shutdown(nbr, S_BAD_TLV_VAL, lm->msgid,
- lm->type);
+ session_shutdown(nbr, S_BAD_TLV_VAL, lm.msgid, lm.type);
return (-1);
}
@@ -157,7 +157,7 @@ recv_labelmapping(struct nbr *nbr, char *buf, u_int16_t len)
nbr_fsm(nbr, NBR_EVT_PDU_RCVD);
- return (ntohs(lm->length));
+ return (ntohs(lm.length));
}
/* Label Request Message */
@@ -200,46 +200,48 @@ send_labelrequest(struct nbr *nbr)
int
recv_labelrequest(struct nbr *nbr, char *buf, u_int16_t len)
{
- struct ldp_msg *lr;
- struct fec_tlv *ft;
- struct map map;
- int feclen, tlen;
- u_int8_t addr_type;
-
- if (nbr->state != NBR_STA_OPER)
- return (-1);
-
- lr = (struct ldp_msg *)buf;
+ struct ldp_msg lr;
+ struct fec_tlv ft;
+ struct map map;
+ int feclen, tlen;
+ u_int8_t addr_type;
- if ((len - TLV_HDR_LEN) < ntohs(lr->length)) {
- session_shutdown(nbr, S_BAD_MSG_LEN, lr->msgid, lr->type);
+ if (nbr->state != NBR_STA_OPER) {
+ log_debug("recv_labelrequest: neighbor ID %s not operational",
+ inet_ntoa(nbr->id));
return (-1);
}
+ bcopy(buf, &lr, sizeof(lr));
+
buf += sizeof(struct ldp_msg);
len -= sizeof(struct ldp_msg);
- ft = (struct fec_tlv *)buf;
+ if (len < sizeof(ft)) {
+ session_shutdown(nbr, S_BAD_MSG_LEN, lr.msgid, lr.type);
+ return (-1);
+ }
+
+ bcopy(buf, &ft, sizeof(ft));
+ feclen = ntohs(ft.length);
- if (len < sizeof(*ft) ||
- (len - TLV_HDR_LEN) < ntohs(ft->length)) {
- session_shutdown(nbr, S_BAD_TLV_LEN, lr->msgid, lr->type);
+ if (feclen > len - TLV_HDR_LEN) {
+ session_shutdown(nbr, S_BAD_TLV_LEN, lr.msgid, lr.type);
return (-1);
}
- feclen = ntohs(ft->length);
- buf += sizeof(struct fec_tlv);
- len -= sizeof(struct fec_tlv);
+ buf += TLV_HDR_LEN; /* just advance to the end of the fec header */
+ len -= TLV_HDR_LEN;
- bzero(&map, sizeof(map));
- map.messageid = lr->msgid;
+ /* TODO opt hop cnt and path vektor TLV */
+ bzero(&map, sizeof(map));
+ map.messageid = lr.msgid;
do {
if ((tlen = tlv_decode_fec_elm(buf, feclen, &addr_type,
&map.prefix.s_addr, &map.prefixlen)) == -1 ||
addr_type == FEC_WILDCARD) {
- session_shutdown(nbr, S_BAD_TLV_VAL, lr->msgid,
- lr->type);
+ session_shutdown(nbr, S_BAD_TLV_VAL, lr.msgid, lr.type);
return (-1);
}
@@ -252,7 +254,7 @@ recv_labelrequest(struct nbr *nbr, char *buf, u_int16_t len)
nbr_fsm(nbr, NBR_EVT_PDU_RCVD);
- return (ntohs(lr->length));
+ return (ntohs(lr.length));
}
/* Label Withdraw Message */
@@ -303,70 +305,70 @@ send_labelwithdraw(struct nbr *nbr)
int
recv_labelwithdraw(struct nbr *nbr, char *buf, u_int16_t len)
{
- struct map map;
- struct ldp_msg *lw;
- struct fec_tlv *ft;
- u_int32_t optlabel = NO_LABEL;
- int feclen, tlen, numfec = 0;
- u_int8_t addr_type;
-
- if (nbr->state != NBR_STA_OPER)
- return (-1);
-
- lw = (struct ldp_msg *)buf;
+ struct map map;
+ struct ldp_msg lw;
+ struct fec_tlv ft;
+ u_int32_t label = NO_LABEL;
+ int feclen, tlen, numfec = 0;
+ u_int8_t addr_type;
- if ((len - TLV_HDR_LEN) < ntohs(lw->length)) {
- session_shutdown(nbr, S_BAD_MSG_LEN, lw->msgid, lw->type);
+ if (nbr->state != NBR_STA_OPER) {
+ log_debug("recv_labelwithdraw: neighbor ID %s not operational",
+ inet_ntoa(nbr->id));
return (-1);
}
+ bcopy(buf, &lw, sizeof(lw));
+
buf += sizeof(struct ldp_msg);
len -= sizeof(struct ldp_msg);
- ft = (struct fec_tlv *)buf;
+ if (len < sizeof(ft)) {
+ session_shutdown(nbr, S_BAD_MSG_LEN, lw.msgid, lw.type);
+ return (-1);
+ }
+
+ bcopy(buf, &ft, sizeof(ft));
+ feclen = ntohs(ft.length);
- if (len < sizeof(*ft) ||
- (len - TLV_HDR_LEN) < ntohs(ft->length)) {
- session_shutdown(nbr, S_BAD_TLV_LEN, lw->msgid, lw->type);
+ if (feclen > len - TLV_HDR_LEN) {
+ session_shutdown(nbr, S_BAD_TLV_LEN, lw.msgid, lw.type);
return (-1);
}
- feclen = ntohs(ft->length);
- buf += sizeof(struct fec_tlv);
- len -= sizeof(struct fec_tlv);
+ buf += TLV_HDR_LEN; /* just advance to the end of the fec header */
+ len -= TLV_HDR_LEN;
- /* release may include optional label */
- if (len >= feclen) {
- struct label_tlv *lt;
-
- lt = (struct label_tlv *)(buf + feclen);
- optlabel = tlv_decode_label(lt);
- if (optlabel == NO_LABEL) {
- session_shutdown(nbr, S_BAD_TLV_VAL, lw->msgid,
- lw->type);
+ /* withdraw may include optional label */
+ if (len > feclen) {
+ int r;
+
+ r = tlv_decode_label(buf + feclen, len - feclen, &label);
+ if (r == -1 || len != feclen + r) {
+ session_shutdown(nbr, S_BAD_TLV_VAL, lw.msgid,
+ lw.type);
return (-1);
}
}
bzero(&map, sizeof(map));
- map.messageid = lw->msgid;
- if (optlabel != NO_LABEL) {
- map.label = optlabel;
+ map.messageid = lw.msgid;
+ if (label != NO_LABEL) {
+ map.label = label;
map.flags = F_MAP_OPTLABEL;
}
do {
if ((tlen = tlv_decode_fec_elm(buf, feclen, &addr_type,
&map.prefix.s_addr, &map.prefixlen)) == -1) {
- session_shutdown(nbr, S_BAD_TLV_VAL, lw->msgid,
- lw->type);
+ session_shutdown(nbr, S_BAD_TLV_VAL, lw.msgid, lw.type);
return (-1);
}
if (addr_type == FEC_WILDCARD) {
/* Wildcard FEC must be the only FEC element */
if (numfec != 0) {
- session_shutdown(nbr, S_BAD_TLV_VAL, lw->msgid,
- lw->type);
+ session_shutdown(nbr, S_BAD_TLV_VAL, lw.msgid,
+ lw.type);
return (-1);
}
map.prefix.s_addr = 0;
@@ -376,8 +378,8 @@ recv_labelwithdraw(struct nbr *nbr, char *buf, u_int16_t len)
} else {
/* Wildcard FEC must be the only FEC element */
if (numfec == -1) {
- session_shutdown(nbr, S_BAD_TLV_VAL, lw->msgid,
- lw->type);
+ session_shutdown(nbr, S_BAD_TLV_VAL, lw.msgid,
+ lw.type);
return (-1);
}
numfec++;
@@ -393,7 +395,7 @@ recv_labelwithdraw(struct nbr *nbr, char *buf, u_int16_t len)
nbr_fsm(nbr, NBR_EVT_PDU_RCVD);
- return (ntohs(lw->length));
+ return (ntohs(lw.length));
}
/* Label Release Message */
@@ -444,70 +446,70 @@ send_labelrelease(struct nbr *nbr)
int
recv_labelrelease(struct nbr *nbr, char *buf, u_int16_t len)
{
- struct map map;
- struct ldp_msg *lr;
- struct fec_tlv *ft;
- u_int32_t optlabel = NO_LABEL;
- int feclen, tlen, numfec = 0;
- u_int8_t addr_type;
-
- if (nbr->state != NBR_STA_OPER)
- return (-1);
-
- lr = (struct ldp_msg *)buf;
+ struct map map;
+ struct ldp_msg lr;
+ struct fec_tlv ft;
+ u_int32_t label = NO_LABEL;
+ int feclen, tlen, numfec = 0;
+ u_int8_t addr_type;
- if ((len - TLV_HDR_LEN) < ntohs(lr->length)) {
- session_shutdown(nbr, S_BAD_MSG_LEN, lr->msgid, lr->type);
+ if (nbr->state != NBR_STA_OPER) {
+ log_debug("recv_labelrelease: neighbor ID %s not operational",
+ inet_ntoa(nbr->id));
return (-1);
}
+ bcopy(buf, &lr, sizeof(lr));
+
buf += sizeof(struct ldp_msg);
len -= sizeof(struct ldp_msg);
- ft = (struct fec_tlv *)buf;
+ if (len < sizeof(ft)) {
+ session_shutdown(nbr, S_BAD_MSG_LEN, lr.msgid, lr.type);
+ return (-1);
+ }
+
+ bcopy(buf, &ft, sizeof(ft));
+ feclen = ntohs(ft.length);
- if (len < sizeof(*ft) ||
- (len - TLV_HDR_LEN) < ntohs(ft->length)) {
- session_shutdown(nbr, S_BAD_TLV_LEN, lr->msgid, lr->type);
+ if (feclen > len - TLV_HDR_LEN) {
+ session_shutdown(nbr, S_BAD_TLV_LEN, lr.msgid, lr.type);
return (-1);
}
- feclen = ntohs(ft->length);
- buf += sizeof(struct fec_tlv);
- len -= sizeof(struct fec_tlv);
+ buf += TLV_HDR_LEN; /* just advance to the end of the fec header */
+ len -= TLV_HDR_LEN;
/* release may include optional label */
- if (len >= feclen) {
- struct label_tlv *lt;
-
- lt = (struct label_tlv *)(buf + feclen);
- optlabel = tlv_decode_label(lt);
- if (optlabel == NO_LABEL) {
- session_shutdown(nbr, S_BAD_TLV_VAL, lr->msgid,
- lr->type);
+ if (len > feclen) {
+ int r;
+
+ r = tlv_decode_label(buf + feclen, len - feclen, &label);
+ if (r == -1 || len != feclen + r) {
+ session_shutdown(nbr, S_BAD_TLV_VAL, lr.msgid,
+ lr.type);
return (-1);
}
}
bzero(&map, sizeof(map));
- map.messageid = lr->msgid;
- if (optlabel != NO_LABEL) {
- map.label = optlabel;
+ map.messageid = lr.msgid;
+ if (label != NO_LABEL) {
+ map.label = label;
map.flags = F_MAP_OPTLABEL;
}
do {
if ((tlen = tlv_decode_fec_elm(buf, feclen, &addr_type,
&map.prefix.s_addr, &map.prefixlen)) == -1) {
- session_shutdown(nbr, S_BAD_TLV_VAL, lr->msgid,
- lr->type);
+ session_shutdown(nbr, S_BAD_TLV_VAL, lr.msgid, lr.type);
return (-1);
}
if (addr_type == FEC_WILDCARD) {
/* Wildcard FEC must be the only FEC element */
if (numfec != 0) {
- session_shutdown(nbr, S_BAD_TLV_VAL, lr->msgid,
- lr->type);
+ session_shutdown(nbr, S_BAD_TLV_VAL, lr.msgid,
+ lr.type);
return (-1);
}
map.prefix.s_addr = 0;
@@ -517,8 +519,8 @@ recv_labelrelease(struct nbr *nbr, char *buf, u_int16_t len)
} else {
/* Wildcard FEC must be the only FEC element */
if (numfec == -1) {
- session_shutdown(nbr, S_BAD_TLV_VAL, lr->msgid,
- lr->type);
+ session_shutdown(nbr, S_BAD_TLV_VAL, lr.msgid,
+ lr.type);
return (-1);
}
map.flags &= ~F_MAP_WILDCARD;
@@ -533,7 +535,7 @@ recv_labelrelease(struct nbr *nbr, char *buf, u_int16_t len)
nbr_fsm(nbr, NBR_EVT_PDU_RCVD);
- return (ntohs(lr->length));
+ return (ntohs(lr.length));
}
/* Label Abort Req Message */
@@ -563,28 +565,76 @@ send_labelabortreq(struct nbr *nbr)
int
recv_labelabortreq(struct nbr *nbr, char *buf, u_int16_t len)
{
- struct ldp_msg *la;
+ struct map map;
+ struct ldp_msg la;
+ struct fec_tlv ft;
+ int feclen, tlen;
+ u_int8_t addr_type;
+
+ if (nbr->state != NBR_STA_OPER) {
+ log_debug("recv_labelabortreq: neighbor ID %s not operational",
+ inet_ntoa(nbr->id));
+ return (-1);
+ }
log_debug("recv_labelabortreq: neighbor ID %s", inet_ntoa(nbr->id));
- if (nbr->state != NBR_STA_OPER)
+ bcopy(buf, &la, sizeof(la));
+
+ buf += sizeof(struct ldp_msg);
+ len -= sizeof(struct ldp_msg);
+
+ if (len < sizeof(ft)) {
+ session_shutdown(nbr, S_BAD_MSG_LEN, la.msgid, la.type);
return (-1);
+ }
- la = (struct ldp_msg *)buf;
+ bcopy(buf, &ft, sizeof(ft));
+ feclen = ntohs(ft.length);
- if ((len - TLV_HDR_LEN) < ntohs(la->length)) {
- session_shutdown(nbr, S_BAD_MSG_LEN, la->msgid, la->type);
+ if (feclen > len - TLV_HDR_LEN) {
+ session_shutdown(nbr, S_BAD_TLV_LEN, la.msgid, la.type);
return (-1);
}
- buf += sizeof(struct ldp_msg);
- len -= sizeof(struct ldp_msg);
+ buf += TLV_HDR_LEN; /* just advance to the end of the fec header */
+ len -= TLV_HDR_LEN;
+
+ bzero(&map, sizeof(map));
+ map.messageid = la.msgid;
- /* XXX XXX XXX */
+ /* abort request may include optional request msg id */
+ if (len > feclen) {
+ int r;
+
+ r = tlv_decode_reqid(buf + feclen, len - feclen,
+ &map.requestid);
+ if (r == -1 || len != feclen + r) {
+ session_shutdown(nbr, S_BAD_TLV_VAL, la.msgid,
+ la.type);
+ return (-1);
+ }
+ map.flags = F_MAP_REQ_ID;
+ }
+
+ do {
+ if ((tlen = tlv_decode_fec_elm(buf, feclen, &addr_type,
+ &map.prefix.s_addr, &map.prefixlen)) == -1 ||
+ addr_type == FEC_WILDCARD) {
+ session_shutdown(nbr, S_BAD_TLV_VAL, la.msgid, la.type);
+ return (-1);
+ }
+
+ ldpe_imsg_compose_lde(IMSG_LABEL_ABORT, nbr->peerid, 0, &map,
+ sizeof(map));
+
+ buf += tlen;
+ feclen -= tlen;
+ } while (feclen > 0);
nbr_fsm(nbr, NBR_EVT_PDU_RCVD);
- return (ntohs(la->length));
+ return (ntohs(la.length));
}
/* Other TLV related functions */
@@ -600,16 +650,24 @@ gen_label_tlv(struct ibuf *buf, u_int32_t label)
ibuf_add(buf, &lt, sizeof(lt));
}
-u_int32_t
-tlv_decode_label(struct label_tlv *lt)
+int
+tlv_decode_label(char *buf, u_int16_t len, u_int32_t *label)
{
- if (lt->type != htons(TLV_TYPE_GENERICLABEL))
- return (NO_LABEL);
+ struct label_tlv lt;
+
+ if (len < sizeof(lt))
+ return (-1);
+ bcopy(buf, &lt, sizeof(lt));
+
+ if (ntohs(lt.length) != sizeof(lt) - TLV_HDR_LEN)
+ return (-1);
- if (ntohs(lt->length) != sizeof(lt->label))
- return (NO_LABEL);
+ if (lt.type != htons(TLV_TYPE_GENERICLABEL))
+ return (-1);
+
+ *label = ntohl(lt.label);
- return (ntohl(lt->label));
+ return (sizeof(lt));
}
void
@@ -624,18 +682,27 @@ gen_reqid_tlv(struct ibuf *buf, u_int32_t reqid)
ibuf_add(buf, &rt, sizeof(rt));
}
-u_int32_t
-tlv_decode_reqid(struct reqid_tlv *rt)
+int
+tlv_decode_reqid(char *buf, u_int16_t len, u_int32_t *reqid)
{
- if (rt->type != htons(TLV_TYPE_LABELREQUEST))
- return (NO_LABEL);
+ struct reqid_tlv rt;
+
+ if (len < sizeof(rt))
+ return (-1);
+ bcopy(buf, &rt, sizeof(rt));
- if (ntohs(rt->length) != sizeof(rt->reqid))
- return (NO_LABEL);
+ if (ntohs(rt.length) != sizeof(rt) - TLV_HDR_LEN)
+ return (-1);
+
+ if (rt.type != htons(TLV_TYPE_LABELREQUEST))
+ return (-1);
- return (ntohl(rt->reqid));
+ *reqid = ntohl(rt.reqid);
+
+ return (sizeof(rt));
}
+
void
gen_fec_tlv(struct ibuf *buf, struct in_addr prefix, u_int8_t prefixlen)
{
diff --git a/usr.sbin/ldpd/ldp.h b/usr.sbin/ldpd/ldp.h
index 40ca600f160..83a3a179e01 100644
--- a/usr.sbin/ldpd/ldp.h
+++ b/usr.sbin/ldpd/ldp.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldp.h,v 1.6 2010/10/26 12:59:03 claudio Exp $ */
+/* $OpenBSD: ldp.h,v 1.7 2010/11/04 09:52:16 claudio Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
@@ -103,7 +103,7 @@ struct ldp_msg {
u_int32_t msgid;
/* Mandatory Parameters */
/* Optional Parameters */
-};
+} __packed;
#define LDP_MSG_LEN 8
#define TLV_HDR_LEN 4
@@ -119,9 +119,11 @@ struct hello_prms_tlv {
u_int16_t type;
u_int16_t length;
u_int16_t holdtime;
- u_int16_t reserved;
+ u_int16_t flags;
};
+#define HELLO_PRMS_SIZE 8
+
#define S_SUCCESS 0x00000000
#define S_BAD_LDP_ID 0x80000001
#define S_BAD_PROTO_VER 0x80000002
@@ -159,7 +161,7 @@ struct sess_prms_tlv {
u_int16_t max_pdu_len;
u_int32_t lsr_id;
u_int16_t lspace_id;
-};
+} __packed;
#define SESS_PRMS_SIZE 18
@@ -169,7 +171,7 @@ struct status_tlv {
u_int32_t status_code;
u_int32_t msg_id;
u_int16_t msg_type;
-};
+} __packed;
#define STATUS_SIZE 14
#define STATUS_TLV_LEN 10
@@ -180,7 +182,7 @@ struct address_list_tlv {
u_int16_t length;
u_int16_t family;
/* address entries */
-};
+} __packed;
#define BASIC_LABEL_MAP_LEN 24
diff --git a/usr.sbin/ldpd/ldpe.h b/usr.sbin/ldpd/ldpe.h
index 4691859adf8..ff651b7a9d8 100644
--- a/usr.sbin/ldpd/ldpe.h
+++ b/usr.sbin/ldpd/ldpe.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldpe.h,v 1.12 2010/10/26 12:22:35 claudio Exp $ */
+/* $OpenBSD: ldpe.h,v 1.13 2010/11/04 09:52:16 claudio Exp $ */
/*
* Copyright (c) 2004, 2005, 2008 Esben Norby <norby@openbsd.org>
@@ -95,7 +95,6 @@ int recv_notification(struct nbr *, char *, u_int16_t);
void send_address(struct nbr *, struct iface *);
int recv_address(struct nbr *, char *, u_int16_t);
void send_address_withdraw(struct nbr *, struct iface *);
-int recv_address_withdraw(struct nbr *, char *, u_int16_t);
/* labelmapping.c */
#define PREFIX_SIZE(x) (((x) + 7) / 8)
diff --git a/usr.sbin/ldpd/notification.c b/usr.sbin/ldpd/notification.c
index 52650908a09..0c9b1b06166 100644
--- a/usr.sbin/ldpd/notification.c
+++ b/usr.sbin/ldpd/notification.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: notification.c,v 1.7 2010/05/26 13:56:08 nicm Exp $ */
+/* $OpenBSD: notification.c,v 1.8 2010/11/04 09:52:16 claudio Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
@@ -80,44 +80,46 @@ send_notification(u_int32_t status, struct iface *iface, u_int32_t msgid,
int
recv_notification(struct nbr *nbr, char *buf, u_int16_t len)
{
- struct ldp_msg *not;
- struct status_tlv *st;
+ struct ldp_msg not;
+ struct status_tlv st;
log_debug("recv_notification: neighbor ID %s", inet_ntoa(nbr->id));
- not = (struct ldp_msg *)buf;
-
- if ((len - TLV_HDR_LEN) < ntohs(not->length)) {
- session_shutdown(nbr, S_BAD_MSG_LEN, not->msgid, not->type);
- return (-1);
- }
+ bcopy(buf, &not, sizeof(not));
buf += sizeof(struct ldp_msg);
len -= sizeof(struct ldp_msg);
- st = (struct status_tlv *)buf;
+ if (len < STATUS_SIZE) {
+ session_shutdown(nbr, S_BAD_MSG_LEN, not.msgid, not.type);
+ return (-1);
+ }
+ bcopy(buf, &st, sizeof(st));
- if (len < STATUS_SIZE ||
- (STATUS_SIZE - TLV_HDR_LEN) != ntohs(st->length)) {
- session_shutdown(nbr, S_BAD_TLV_LEN, not->msgid, not->type);
+ if (ntohs(st.length) > STATUS_SIZE - TLV_HDR_LEN ||
+ ntohs(st.length) > len - TLV_HDR_LEN) {
+ session_shutdown(nbr, S_BAD_TLV_LEN, not.msgid, not.type);
return (-1);
}
- if (st->status_code & htonl(STATUS_FATAL))
+ /* TODO optional parameters: ext status, returned PDU and msg */
+
+ if (st.status_code & htonl(STATUS_FATAL))
log_warnx("recieved notification from neighbor %s: %s",
inet_ntoa(nbr->id),
- notification_name(ntohl(st->status_code)));
+ notification_name(ntohl(st.status_code)));
else
log_debug("recieved non-fatal notification from neighbor "
"%s: %s", inet_ntoa(nbr->id),
- notification_name(ntohl(st->status_code)));
+ notification_name(ntohl(st.status_code)));
- if (st->status_code & htonl(STATUS_FATAL)) {
+ if (st.status_code & htonl(STATUS_FATAL)) {
nbr_fsm(nbr, NBR_EVT_CLOSE_SESSION);
return (-1);
}
+ /* XXX in some cases we should inform the RDE about non-fatal ones */
- return (ntohs(not->length));
+ return (ntohs(not.length));
}
int
diff --git a/usr.sbin/ldpd/packet.c b/usr.sbin/ldpd/packet.c
index 12613b7c454..932e1daad3e 100644
--- a/usr.sbin/ldpd/packet.c
+++ b/usr.sbin/ldpd/packet.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: packet.c,v 1.12 2010/05/26 13:56:08 nicm Exp $ */
+/* $OpenBSD: packet.c,v 1.13 2010/11/04 09:52:16 claudio Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
@@ -115,8 +115,8 @@ disc_recv_packet(int fd, short event, void *bula)
struct msghdr msg;
struct iovec iov;
struct ldpd_conf *xconf = bula;
- struct ldp_hdr *ldp_hdr;
- struct ldp_msg *ldp_msg;
+ struct ldp_hdr ldp_hdr;
+ struct ldp_msg ldp_msg;
struct iface *iface;
char *buf;
struct cmsghdr *cmsg;
@@ -168,33 +168,34 @@ disc_recv_packet(int fd, short event, void *bula)
log_debug("disc_recv_packet: bad packet size");
return;
}
- ldp_hdr = (struct ldp_hdr *)buf;
+ bcopy(buf, &ldp_hdr, sizeof(ldp_hdr));
- if (ntohs(ldp_hdr->version) != LDP_VERSION) {
+ if (ntohs(ldp_hdr.version) != LDP_VERSION) {
log_debug("dsc_recv_packet: invalid LDP version %d",
- ldp_hdr->version);
+ ldp_hdr.version);
return;
}
- if ((l = ldp_hdr_sanity_check(ldp_hdr, len, iface)) == -1)
+ if ((l = ldp_hdr_sanity_check(&ldp_hdr, len, iface)) == -1)
return;
if (l > len) {
log_debug("disc_recv_packet: invalid LDP packet length %d",
- ntohs(ldp_hdr->length));
+ ntohs(ldp_hdr.length));
return;
}
- ldp_msg = (struct ldp_msg *)(buf + LDP_HDR_SIZE);
-
if (len < LDP_HDR_SIZE + LDP_MSG_LEN) {
log_debug("disc_recv_packet: invalid LDP packet length %d",
- ntohs(ldp_hdr->length));
+ ntohs(ldp_hdr.length));
return;
}
+ bcopy(buf + LDP_HDR_SIZE, &ldp_msg, sizeof(ldp_msg));
+
+
/* switch LDP packet type */
- switch (ntohs(ldp_msg->type)) {
+ switch (ntohs(ldp_msg.type)) {
case MSG_TYPE_HELLO:
recv_hello(iface, src.sin_addr, buf, len);
break;
@@ -373,10 +374,8 @@ session_read(int fd, short event, void *arg)
msg_size = recv_keepalive(nbr, pdu, pdu_len);
break;
case MSG_TYPE_ADDR:
- msg_size = recv_address(nbr, pdu, pdu_len);
- break;
case MSG_TYPE_ADDRWITHDRAW:
- msg_size = recv_address_withdraw(nbr, pdu, pdu_len);
+ msg_size = recv_address(nbr, pdu, pdu_len);
break;
case MSG_TYPE_LABELMAPPING:
msg_size = recv_labelmapping(nbr, pdu, pdu_len);
@@ -393,8 +392,8 @@ session_read(int fd, short event, void *arg)
case MSG_TYPE_LABELABORTREQ:
case MSG_TYPE_HELLO:
default:
- log_debug("session_read: unknown LDP packet type "
- "interface %s", iface->name);
+ log_debug("session_read: unknown LDP packet "
+ "type interface %s", iface->name);
free(buf);
return;
}