1/* 2 PIM for Quagga 3 Copyright (C) 2008 Everton da Silva Marques 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 2 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, but 11 WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program; see the file COPYING; if not, write to the 17 Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, 18 MA 02110-1301 USA 19 20 $QuaggaId: $Format:%an, %ai, %h$ $ 21*/ 22 23#include <zebra.h> 24 25#include "pimd.h" 26#include "pim_pim.h" 27#include "pim_msg.h" 28#include "pim_util.h" 29 30void pim_msg_build_header(uint8_t *pim_msg, int pim_msg_size, 31 uint8_t pim_msg_type) 32{ 33 uint16_t checksum; 34 35 zassert(pim_msg_size >= PIM_PIM_MIN_LEN); 36 37 /* 38 * Write header 39 */ 40 41 *(uint8_t *) PIM_MSG_HDR_OFFSET_VERSION(pim_msg) = (PIM_PROTO_VERSION << 4) | pim_msg_type; 42 *(uint8_t *) PIM_MSG_HDR_OFFSET_RESERVED(pim_msg) = 0; 43 44 /* 45 * Compute checksum 46 */ 47 48 *(uint16_t *) PIM_MSG_HDR_OFFSET_CHECKSUM(pim_msg) = 0; 49 checksum = in_cksum(pim_msg, pim_msg_size); 50 *(uint16_t *) PIM_MSG_HDR_OFFSET_CHECKSUM(pim_msg) = checksum; 51} 52 53uint8_t *pim_msg_addr_encode_ipv4_ucast(uint8_t *buf, 54 int buf_size, 55 struct in_addr addr) 56{ 57 const int ENCODED_IPV4_UCAST_SIZE = 6; 58 59 if (buf_size < ENCODED_IPV4_UCAST_SIZE) { 60 return 0; 61 } 62 63 buf[0] = PIM_MSG_ADDRESS_FAMILY_IPV4; /* addr family */ 64 buf[1] = '\0'; /* native encoding */ 65 memcpy(buf+2, &addr, sizeof(struct in_addr)); 66 67 return buf + ENCODED_IPV4_UCAST_SIZE; 68} 69 70uint8_t *pim_msg_addr_encode_ipv4_group(uint8_t *buf, 71 int buf_size, 72 struct in_addr addr) 73{ 74 const int ENCODED_IPV4_GROUP_SIZE = 8; 75 76 if (buf_size < ENCODED_IPV4_GROUP_SIZE) { 77 return 0; 78 } 79 80 buf[0] = PIM_MSG_ADDRESS_FAMILY_IPV4; /* addr family */ 81 buf[1] = '\0'; /* native encoding */ 82 buf[2] = '\0'; /* reserved */ 83 buf[3] = 32; /* mask len */ 84 memcpy(buf+4, &addr, sizeof(struct in_addr)); 85 86 return buf + ENCODED_IPV4_GROUP_SIZE; 87} 88 89uint8_t *pim_msg_addr_encode_ipv4_source(uint8_t *buf, 90 int buf_size, 91 struct in_addr addr) 92{ 93 const int ENCODED_IPV4_SOURCE_SIZE = 8; 94 95 if (buf_size < ENCODED_IPV4_SOURCE_SIZE) { 96 return 0; 97 } 98 99 buf[0] = PIM_MSG_ADDRESS_FAMILY_IPV4; /* addr family */ 100 buf[1] = '\0'; /* native encoding */ 101 buf[2] = 4; /* reserved = 0 | S bit = 1 | W bit = 0 | R bit = 0 */ 102 buf[3] = 32; /* mask len */ 103 memcpy(buf+4, &addr, sizeof(struct in_addr)); 104 105 return buf + ENCODED_IPV4_SOURCE_SIZE; 106} 107