Home | History | Annotate | Line # | Download | only in ldpd
      1  1.5  kefren /* $NetBSD: pdu.c,v 1.5 2013/07/11 05:45:23 kefren Exp $ */
      2  1.1  kefren 
      3  1.1  kefren /*-
      4  1.1  kefren  * Copyright (c) 2010 The NetBSD Foundation, Inc.
      5  1.1  kefren  * All rights reserved.
      6  1.1  kefren  *
      7  1.1  kefren  * This code is derived from software contributed to The NetBSD Foundation
      8  1.1  kefren  * by Mihai Chelaru <kefren (at) NetBSD.org>
      9  1.1  kefren  *
     10  1.1  kefren  * Redistribution and use in source and binary forms, with or without
     11  1.1  kefren  * modification, are permitted provided that the following conditions
     12  1.1  kefren  * are met:
     13  1.1  kefren  * 1. Redistributions of source code must retain the above copyright
     14  1.1  kefren  *    notice, this list of conditions and the following disclaimer.
     15  1.1  kefren  * 2. Redistributions in binary form must reproduce the above copyright
     16  1.1  kefren  *    notice, this list of conditions and the following disclaimer in the
     17  1.1  kefren  *    documentation and/or other materials provided with the distribution.
     18  1.1  kefren  *
     19  1.1  kefren  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  1.1  kefren  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  1.1  kefren  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  1.1  kefren  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  1.1  kefren  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  1.1  kefren  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  1.1  kefren  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  1.1  kefren  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  1.1  kefren  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  1.1  kefren  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  1.1  kefren  * POSSIBILITY OF SUCH DAMAGE.
     30  1.1  kefren  */
     31  1.1  kefren 
     32  1.1  kefren #include <arpa/inet.h>
     33  1.1  kefren 
     34  1.1  kefren #include <stdio.h>
     35  1.1  kefren #include <strings.h>
     36  1.1  kefren #include <stdlib.h>
     37  1.1  kefren 
     38  1.1  kefren #include "socketops.h"
     39  1.1  kefren #include "ldp_errors.h"
     40  1.1  kefren #include "ldp.h"
     41  1.1  kefren #include "ldp_peer.h"
     42  1.1  kefren #include "notifications.h"
     43  1.1  kefren #include "pdu.h"
     44  1.1  kefren 
     45  1.1  kefren uint
     46  1.5  kefren get_pdu(const unsigned char *s, struct ldp_pdu * p)
     47  1.1  kefren {
     48  1.5  kefren 	const struct ldp_pdu *p1 = (const struct ldp_pdu *) s;
     49  1.1  kefren 
     50  1.1  kefren 	p->version = ntohs(p1->version);
     51  1.1  kefren 	p->length = ntohs(p1->length);
     52  1.1  kefren 	memcpy(&p->ldp_id, &p1->ldp_id, sizeof(struct in_addr));
     53  1.1  kefren 	p->label_space = ntohs(p1->label_space);
     54  1.1  kefren 
     55  1.1  kefren 	return MIN_PDU_SIZE;
     56  1.1  kefren }
     57  1.1  kefren 
     58  1.1  kefren /* Checks an incoming PDU for size and version */
     59  1.1  kefren int
     60  1.5  kefren check_recv_pdu(const struct ldp_peer * p, const struct ldp_pdu * rpdu, int c)
     61  1.1  kefren {
     62  1.1  kefren 	struct notification_tlv *notiftlv;
     63  1.1  kefren 
     64  1.1  kefren 	/* Avoid underflow */
     65  1.1  kefren 	if (c < MIN_PDU_SIZE)
     66  1.1  kefren 		return LDP_E_BAD_LENGTH;
     67  1.1  kefren 
     68  1.3  kefren 	if (p->ldp_id.s_addr != rpdu->ldp_id.s_addr) {
     69  1.4  kefren 		fatalp("Invalid LDP ID %s received from ",
     70  1.4  kefren 		    inet_ntoa(rpdu->ldp_id));
     71  1.4  kefren 		fatalp("%s\n", inet_ntoa(p->ldp_id));
     72  1.3  kefren 		notiftlv = build_notification(0,
     73  1.3  kefren 		    NOTIF_FATAL | NOTIF_BAD_LDP_ID);
     74  1.3  kefren 		send_tlv(p, (struct tlv *) notiftlv);
     75  1.3  kefren 		free(notiftlv);
     76  1.3  kefren 		return LDP_E_BAD_ID;
     77  1.3  kefren 	}
     78  1.1  kefren 
     79  1.1  kefren 	/* Check PDU for right LDP version */
     80  1.1  kefren 	if (ntohs(rpdu->version) != LDP_VERSION) {
     81  1.1  kefren 		fatalp("Invalid PDU version received from %s (%d)\n",
     82  1.2  kefren 		       satos(p->address), ntohs(rpdu->version));
     83  1.3  kefren 		notiftlv = build_notification(0,
     84  1.3  kefren 		    NOTIF_FATAL | NOTIF_BAD_LDP_VER);
     85  1.1  kefren 		send_tlv(p, (struct tlv *) notiftlv);
     86  1.1  kefren 		free(notiftlv);
     87  1.1  kefren 		return LDP_E_BAD_VERSION;
     88  1.1  kefren 	}
     89  1.1  kefren 	/* Check PDU for length validity */
     90  1.1  kefren 	if (ntohs(rpdu->length) > c - PDU_VER_LENGTH) {
     91  1.1  kefren 		fatalp("Invalid PDU length received from %s (announced %d, "
     92  1.2  kefren 		    "received %d)\n", satos(p->address),
     93  1.1  kefren 		    ntohs(rpdu->length), (int) (c - PDU_VER_LENGTH));
     94  1.3  kefren 		notiftlv = build_notification(0,
     95  1.3  kefren 		    NOTIF_FATAL | NOTIF_BAD_PDU_LEN);
     96  1.1  kefren 		send_tlv(p, (struct tlv *) notiftlv);
     97  1.1  kefren 		free(notiftlv);
     98  1.1  kefren 		return LDP_E_BAD_LENGTH;
     99  1.1  kefren 	}
    100  1.1  kefren 	return LDP_E_OK;
    101  1.1  kefren }
    102