pim_msg.c 2.8 KB

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