print-vrrp.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /*
  2. * Copyright (c) 2000 William C. Fenner.
  3. * All rights reserved.
  4. *
  5. * Kevin Steves <ks@hp.se> July 2000
  6. * Modified to:
  7. * - print version, type string and packet length
  8. * - print IP address count if > 1 (-v)
  9. * - verify checksum (-v)
  10. * - print authentication string (-v)
  11. *
  12. * Redistribution and use in source and binary forms, with or without
  13. * modification, are permitted provided that: (1) source code
  14. * distributions retain the above copyright notice and this paragraph
  15. * in its entirety, and (2) distributions including binary code include
  16. * the above copyright notice and this paragraph in its entirety in
  17. * the documentation or other materials provided with the distribution.
  18. * The name of William C. Fenner may not be used to endorse or
  19. * promote products derived from this software without specific prior
  20. * written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND
  21. * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
  22. * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  23. * FOR A PARTICULAR PURPOSE.
  24. */
  25. /* \summary: Virtual Router Redundancy Protocol (VRRP) printer */
  26. #ifdef HAVE_CONFIG_H
  27. #include "config.h"
  28. #endif
  29. #include <netdissect-stdinc.h>
  30. #include "netdissect.h"
  31. #include "extract.h"
  32. #include "addrtoname.h"
  33. #include "ip.h"
  34. #include "ipproto.h"
  35. /*
  36. * RFC 2338 (VRRP v2):
  37. *
  38. * 0 1 2 3
  39. * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  40. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  41. * |Version| Type | Virtual Rtr ID| Priority | Count IP Addrs|
  42. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  43. * | Auth Type | Adver Int | Checksum |
  44. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  45. * | IP Address (1) |
  46. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  47. * | . |
  48. * | . |
  49. * | . |
  50. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  51. * | IP Address (n) |
  52. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  53. * | Authentication Data (1) |
  54. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  55. * | Authentication Data (2) |
  56. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  57. *
  58. *
  59. * RFC 5798 (VRRP v3):
  60. *
  61. * 0 1 2 3
  62. * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  63. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  64. * | IPv4 Fields or IPv6 Fields |
  65. * ... ...
  66. * | |
  67. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  68. * |Version| Type | Virtual Rtr ID| Priority |Count IPvX Addr|
  69. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  70. * |(rsvd) | Max Adver Int | Checksum |
  71. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  72. * | |
  73. * + +
  74. * | IPvX Address(es) |
  75. * + +
  76. * | |
  77. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  78. */
  79. /* Type */
  80. #define VRRP_TYPE_ADVERTISEMENT 1
  81. static const struct tok type2str[] = {
  82. { VRRP_TYPE_ADVERTISEMENT, "Advertisement" },
  83. { 0, NULL }
  84. };
  85. /* Auth Type */
  86. #define VRRP_AUTH_NONE 0
  87. #define VRRP_AUTH_SIMPLE 1
  88. #define VRRP_AUTH_AH 2
  89. static const struct tok auth2str[] = {
  90. { VRRP_AUTH_NONE, "none" },
  91. { VRRP_AUTH_SIMPLE, "simple" },
  92. { VRRP_AUTH_AH, "ah" },
  93. { 0, NULL }
  94. };
  95. void
  96. vrrp_print(netdissect_options *ndo,
  97. register const u_char *bp, register u_int len,
  98. register const u_char *bp2, int ttl)
  99. {
  100. int version, type, auth_type = VRRP_AUTH_NONE; /* keep compiler happy */
  101. const char *type_s;
  102. ND_TCHECK(bp[0]);
  103. version = (bp[0] & 0xf0) >> 4;
  104. type = bp[0] & 0x0f;
  105. type_s = tok2str(type2str, "unknown type (%u)", type);
  106. ND_PRINT((ndo, "VRRPv%u, %s", version, type_s));
  107. if (ttl != 255)
  108. ND_PRINT((ndo, ", (ttl %u)", ttl));
  109. if (version < 2 || version > 3 || type != VRRP_TYPE_ADVERTISEMENT)
  110. return;
  111. ND_TCHECK(bp[2]);
  112. ND_PRINT((ndo, ", vrid %u, prio %u", bp[1], bp[2]));
  113. ND_TCHECK(bp[5]);
  114. if (version == 2) {
  115. auth_type = bp[4];
  116. ND_PRINT((ndo, ", authtype %s", tok2str(auth2str, NULL, auth_type)));
  117. ND_PRINT((ndo, ", intvl %us, length %u", bp[5], len));
  118. } else { /* version == 3 */
  119. uint16_t intvl = (bp[4] & 0x0f) << 8 | bp[5];
  120. ND_PRINT((ndo, ", intvl %ucs, length %u", intvl, len));
  121. }
  122. if (ndo->ndo_vflag) {
  123. int naddrs = bp[3];
  124. int i;
  125. char c;
  126. if (version == 2 && ND_TTEST2(bp[0], len)) {
  127. struct cksum_vec vec[1];
  128. vec[0].ptr = bp;
  129. vec[0].len = len;
  130. if (in_cksum(vec, 1))
  131. ND_PRINT((ndo, ", (bad vrrp cksum %x)",
  132. EXTRACT_16BITS(&bp[6])));
  133. }
  134. if (version == 3 && ND_TTEST2(bp[0], len)) {
  135. uint16_t cksum = nextproto4_cksum(ndo, (const struct ip *)bp2, bp,
  136. len, len, IPPROTO_VRRP);
  137. if (cksum)
  138. ND_PRINT((ndo, ", (bad vrrp cksum %x)",
  139. EXTRACT_16BITS(&bp[6])));
  140. }
  141. ND_PRINT((ndo, ", addrs"));
  142. if (naddrs > 1)
  143. ND_PRINT((ndo, "(%d)", naddrs));
  144. ND_PRINT((ndo, ":"));
  145. c = ' ';
  146. bp += 8;
  147. for (i = 0; i < naddrs; i++) {
  148. ND_TCHECK(bp[3]);
  149. ND_PRINT((ndo, "%c%s", c, ipaddr_string(ndo, bp)));
  150. c = ',';
  151. bp += 4;
  152. }
  153. if (version == 2 && auth_type == VRRP_AUTH_SIMPLE) { /* simple text password */
  154. ND_TCHECK(bp[7]);
  155. ND_PRINT((ndo, " auth \""));
  156. if (fn_printn(ndo, bp, 8, ndo->ndo_snapend)) {
  157. ND_PRINT((ndo, "\""));
  158. goto trunc;
  159. }
  160. ND_PRINT((ndo, "\""));
  161. }
  162. }
  163. return;
  164. trunc:
  165. ND_PRINT((ndo, "[|vrrp]"));
  166. }