print-lspping.c 52 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085
  1. /*
  2. * Redistribution and use in source and binary forms, with or without
  3. * modification, are permitted provided that: (1) source code
  4. * distributions retain the above copyright notice and this paragraph
  5. * in its entirety, and (2) distributions including binary code include
  6. * the above copyright notice and this paragraph in its entirety in
  7. * the documentation or other materials provided with the distribution.
  8. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
  9. * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
  10. * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  11. * FOR A PARTICULAR PURPOSE.
  12. *
  13. * Original code by Hannes Gredler (hannes@gredler.at)
  14. */
  15. /* \summary: MPLS LSP PING printer */
  16. #ifdef HAVE_CONFIG_H
  17. #include "config.h"
  18. #endif
  19. #include <netdissect-stdinc.h>
  20. #include "netdissect.h"
  21. #include "extract.h"
  22. #include "addrtoname.h"
  23. #include "l2vpn.h"
  24. #include "oui.h"
  25. /* RFC 4349 */
  26. /*
  27. * LSPPING common header
  28. *
  29. * 0 1 2 3
  30. * 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
  31. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  32. * | Version Number | Must Be Zero |
  33. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  34. * | Message Type | Reply mode | Return Code | Return Subcode|
  35. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  36. * | Sender's Handle |
  37. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  38. * | Sequence Number |
  39. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  40. * | TimeStamp Sent (seconds) |
  41. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  42. * | TimeStamp Sent (microseconds) |
  43. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  44. * | TimeStamp Received (seconds) |
  45. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  46. * | TimeStamp Received (microseconds) |
  47. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  48. * | TLVs ... |
  49. * . .
  50. * . .
  51. * . .
  52. */
  53. struct lspping_common_header {
  54. uint8_t version[2];
  55. uint8_t global_flags[2];
  56. uint8_t msg_type;
  57. uint8_t reply_mode;
  58. uint8_t return_code;
  59. uint8_t return_subcode;
  60. uint8_t sender_handle[4];
  61. uint8_t seq_number[4];
  62. uint8_t ts_sent_sec[4];
  63. uint8_t ts_sent_usec[4];
  64. uint8_t ts_rcvd_sec[4];
  65. uint8_t ts_rcvd_usec[4];
  66. };
  67. #define LSPPING_VERSION 1
  68. static const struct tok lspping_msg_type_values[] = {
  69. { 1, "MPLS Echo Request"},
  70. { 2, "MPLS Echo Reply"},
  71. { 0, NULL}
  72. };
  73. static const struct tok lspping_reply_mode_values[] = {
  74. { 1, "Do not reply"},
  75. { 2, "Reply via an IPv4/IPv6 UDP packet"},
  76. { 3, "Reply via an IPv4/IPv6 UDP packet with Router Alert"},
  77. { 4, "Reply via application level control channel"},
  78. { 0, NULL}
  79. };
  80. static const struct tok lspping_return_code_values[] = {
  81. { 0, "No return code or return code contained in the Error Code TLV"},
  82. { 1, "Malformed echo request received"},
  83. { 2, "One or more of the TLVs was not understood"},
  84. { 3, "Replying router is an egress for the FEC at stack depth"},
  85. { 4, "Replying router has no mapping for the FEC at stack depth"},
  86. { 5, "Reserved"},
  87. { 6, "Reserved"},
  88. { 7, "Reserved"},
  89. { 8, "Label switched at stack-depth"},
  90. { 9, "Label switched but no MPLS forwarding at stack-depth"},
  91. { 10, "Mapping for this FEC is not the given label at stack depth"},
  92. { 11, "No label entry at stack-depth"},
  93. { 12, "Protocol not associated with interface at FEC stack depth"},
  94. { 13, "Premature termination of ping due to label stack shrinking to a single label"},
  95. { 0, NULL},
  96. };
  97. /*
  98. * LSPPING TLV header
  99. * 0 1 2 3
  100. * 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
  101. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  102. * | Type | Length |
  103. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  104. * | Value |
  105. * . .
  106. * . .
  107. * . .
  108. * | |
  109. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  110. */
  111. struct lspping_tlv_header {
  112. uint8_t type[2];
  113. uint8_t length[2];
  114. };
  115. #define LSPPING_TLV_TARGET_FEC_STACK 1
  116. #define LSPPING_TLV_DOWNSTREAM_MAPPING 2
  117. #define LSPPING_TLV_PAD 3
  118. /* not assigned 4 */
  119. #define LSPPING_TLV_VENDOR_ENTERPRISE 5
  120. #define LSPPING_TLV_VENDOR_ENTERPRISE_LEN 4
  121. /* not assigned 6 */
  122. #define LSPPING_TLV_INTERFACE_LABEL_STACK 7
  123. /* not assigned 8 */
  124. #define LSPPING_TLV_ERROR_CODE 9
  125. #define LSPPING_TLV_REPLY_TOS_BYTE 10
  126. #define LSPPING_TLV_BFD_DISCRIMINATOR 15 /* draft-ietf-bfd-mpls-02 */
  127. #define LSPPING_TLV_BFD_DISCRIMINATOR_LEN 4
  128. #define LSPPING_TLV_VENDOR_PRIVATE 0xfc00
  129. static const struct tok lspping_tlv_values[] = {
  130. { LSPPING_TLV_TARGET_FEC_STACK, "Target FEC Stack" },
  131. { LSPPING_TLV_DOWNSTREAM_MAPPING, "Downstream Mapping" },
  132. { LSPPING_TLV_PAD, "Pad" },
  133. { LSPPING_TLV_ERROR_CODE, "Error Code" },
  134. { LSPPING_TLV_VENDOR_ENTERPRISE, "Vendor Enterprise Code" },
  135. { LSPPING_TLV_INTERFACE_LABEL_STACK, "Interface Label Stack" },
  136. { LSPPING_TLV_REPLY_TOS_BYTE, "Reply TOS Byte" },
  137. { LSPPING_TLV_BFD_DISCRIMINATOR, "BFD Discriminator" },
  138. { LSPPING_TLV_VENDOR_PRIVATE, "Vendor Private Code" },
  139. { 0, NULL}
  140. };
  141. #define LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV4 1
  142. #define LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV6 2
  143. #define LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV4 3
  144. #define LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV6 4
  145. /* not assigned 5 */
  146. #define LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4 6
  147. #define LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6 7
  148. #define LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT 8
  149. #define LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW_OLD 9
  150. #define LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW 10
  151. #define LSPPING_TLV_TARGETFEC_SUBTLV_FEC_129_PW 11
  152. #define LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4 12
  153. #define LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6 13
  154. #define LSPPING_TLV_TARGETFEC_SUBTLV_GENERIC_IPV4 14
  155. #define LSPPING_TLV_TARGETFEC_SUBTLV_GENERIC_IPV6 15
  156. #define LSPPING_TLV_TARGETFEC_SUBTLV_NIL_FEC 16
  157. static const struct tok lspping_tlvtargetfec_subtlv_values[] = {
  158. { LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV4, "LDP IPv4 prefix"},
  159. { LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV6, "LDP IPv6 prefix"},
  160. { LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV4, "RSVP IPv4 Session Query"},
  161. { LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV6, "RSVP IPv6 Session Query"},
  162. { 5, "Reserved"},
  163. { LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4, "VPN IPv4 prefix"},
  164. { LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6, "VPN IPv6 prefix"},
  165. { LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT, "L2 VPN endpoint"},
  166. { LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW_OLD, "FEC 128 pseudowire (old)"},
  167. { LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW, "FEC 128 pseudowire"},
  168. { LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4, "BGP labeled IPv4 prefix"},
  169. { LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6, "BGP labeled IPv6 prefix"},
  170. { 0, NULL}
  171. };
  172. /*
  173. * 0 1 2 3
  174. * 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
  175. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  176. * | IPv4 prefix |
  177. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  178. * | Prefix Length | Must Be Zero |
  179. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  180. */
  181. struct lspping_tlv_targetfec_subtlv_ldp_ipv4_t {
  182. uint8_t prefix [4];
  183. uint8_t prefix_len;
  184. };
  185. /*
  186. * 0 1 2 3
  187. * 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
  188. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  189. * | IPv6 prefix |
  190. * | (16 octets) |
  191. * | |
  192. * | |
  193. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  194. * | Prefix Length | Must Be Zero |
  195. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  196. */
  197. struct lspping_tlv_targetfec_subtlv_ldp_ipv6_t {
  198. uint8_t prefix [16];
  199. uint8_t prefix_len;
  200. };
  201. /*
  202. * 0 1 2 3
  203. * 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
  204. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  205. * | IPv4 tunnel end point address |
  206. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  207. * | Must Be Zero | Tunnel ID |
  208. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  209. * | Extended Tunnel ID |
  210. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  211. * | IPv4 tunnel sender address |
  212. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  213. * | Must Be Zero | LSP ID |
  214. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  215. */
  216. struct lspping_tlv_targetfec_subtlv_rsvp_ipv4_t {
  217. uint8_t tunnel_endpoint [4];
  218. uint8_t res[2];
  219. uint8_t tunnel_id[2];
  220. uint8_t extended_tunnel_id[4];
  221. uint8_t tunnel_sender [4];
  222. uint8_t res2[2];
  223. uint8_t lsp_id [2];
  224. };
  225. /*
  226. * 0 1 2 3
  227. * 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
  228. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  229. * | IPv6 tunnel end point address |
  230. * | |
  231. * | |
  232. * | |
  233. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  234. * | Must Be Zero | Tunnel ID |
  235. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  236. * | Extended Tunnel ID |
  237. * | |
  238. * | |
  239. * | |
  240. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  241. * | IPv6 tunnel sender address |
  242. * | |
  243. * | |
  244. * | |
  245. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  246. * | Must Be Zero | LSP ID |
  247. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  248. */
  249. struct lspping_tlv_targetfec_subtlv_rsvp_ipv6_t {
  250. uint8_t tunnel_endpoint [16];
  251. uint8_t res[2];
  252. uint8_t tunnel_id[2];
  253. uint8_t extended_tunnel_id[16];
  254. uint8_t tunnel_sender [16];
  255. uint8_t res2[2];
  256. uint8_t lsp_id [2];
  257. };
  258. /*
  259. * 0 1 2 3
  260. * 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
  261. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  262. * | Route Distinguisher |
  263. * | (8 octets) |
  264. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  265. * | IPv4 prefix |
  266. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  267. * | Prefix Length | Must Be Zero |
  268. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  269. */
  270. struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t {
  271. uint8_t rd [8];
  272. uint8_t prefix [4];
  273. uint8_t prefix_len;
  274. };
  275. /*
  276. * 0 1 2 3
  277. * 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
  278. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  279. * | Route Distinguisher |
  280. * | (8 octets) |
  281. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  282. * | IPv6 prefix |
  283. * | (16 octets) |
  284. * | |
  285. * | |
  286. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  287. * | Prefix Length | Must Be Zero |
  288. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  289. */
  290. struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t {
  291. uint8_t rd [8];
  292. uint8_t prefix [16];
  293. uint8_t prefix_len;
  294. };
  295. /*
  296. * 0 1 2 3
  297. * 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
  298. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  299. * | Route Distinguisher |
  300. * | (8 octets) |
  301. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  302. * | Sender's VE ID | Receiver's VE ID |
  303. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  304. * | Encapsulation Type | Must Be Zero |
  305. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  306. * 0 1 2 3
  307. */
  308. struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t {
  309. uint8_t rd [8];
  310. uint8_t sender_ve_id [2];
  311. uint8_t receiver_ve_id [2];
  312. uint8_t encapsulation[2];
  313. };
  314. /*
  315. * 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
  316. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  317. * | Remote PE Address |
  318. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  319. * | PW ID |
  320. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  321. * | PW Type | Must Be Zero |
  322. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  323. */
  324. struct lspping_tlv_targetfec_subtlv_fec_128_pw_old {
  325. uint8_t remote_pe_address [4];
  326. uint8_t pw_id [4];
  327. uint8_t pw_type[2];
  328. };
  329. /*
  330. * 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
  331. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  332. * | Sender's PE Address |
  333. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  334. * | Remote PE Address |
  335. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  336. * | PW ID |
  337. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  338. * | PW Type | Must Be Zero |
  339. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  340. */
  341. struct lspping_tlv_targetfec_subtlv_fec_128_pw {
  342. uint8_t sender_pe_address [4];
  343. uint8_t remote_pe_address [4];
  344. uint8_t pw_id [4];
  345. uint8_t pw_type[2];
  346. };
  347. /*
  348. * 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
  349. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  350. * | IPv4 prefix |
  351. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  352. * | Prefix Length | Must Be Zero |
  353. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  354. */
  355. struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t {
  356. uint8_t prefix [4];
  357. uint8_t prefix_len;
  358. };
  359. /*
  360. * 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
  361. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  362. * | IPv6 prefix |
  363. * | (16 octets) |
  364. * | |
  365. * | |
  366. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  367. * | Prefix Length | Must Be Zero |
  368. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  369. */
  370. struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t {
  371. uint8_t prefix [16];
  372. uint8_t prefix_len;
  373. };
  374. /*
  375. * 0 1 2 3
  376. * 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
  377. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  378. * | MTU | Address Type | Resvd (SBZ) |
  379. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  380. * | Downstream IP Address (4 or 16 octets) |
  381. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  382. * | Downstream Interface Address (4 or 16 octets) |
  383. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  384. * | Multipath Type| Depth Limit | Multipath Length |
  385. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  386. * . .
  387. * . (Multipath Information) .
  388. * . .
  389. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  390. * | Downstream Label | Protocol |
  391. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  392. * . .
  393. * . .
  394. * . .
  395. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  396. * | Downstream Label | Protocol |
  397. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  398. */
  399. /* Enough to get the address type */
  400. struct lspping_tlv_downstream_map_t {
  401. uint8_t mtu [2];
  402. uint8_t address_type;
  403. uint8_t ds_flags;
  404. };
  405. struct lspping_tlv_downstream_map_ipv4_t {
  406. uint8_t mtu [2];
  407. uint8_t address_type;
  408. uint8_t ds_flags;
  409. uint8_t downstream_ip[4];
  410. uint8_t downstream_interface[4];
  411. };
  412. struct lspping_tlv_downstream_map_ipv4_unmb_t {
  413. uint8_t mtu [2];
  414. uint8_t address_type;
  415. uint8_t ds_flags;
  416. uint8_t downstream_ip[4];
  417. uint8_t downstream_interface[4];
  418. };
  419. struct lspping_tlv_downstream_map_ipv6_t {
  420. uint8_t mtu [2];
  421. uint8_t address_type;
  422. uint8_t ds_flags;
  423. uint8_t downstream_ip[16];
  424. uint8_t downstream_interface[16];
  425. };
  426. struct lspping_tlv_downstream_map_ipv6_unmb_t {
  427. uint8_t mtu [2];
  428. uint8_t address_type;
  429. uint8_t ds_flags;
  430. uint8_t downstream_ip[16];
  431. uint8_t downstream_interface[4];
  432. };
  433. struct lspping_tlv_downstream_map_info_t {
  434. uint8_t multipath_type;
  435. uint8_t depth_limit;
  436. uint8_t multipath_length [2];
  437. };
  438. #define LSPPING_AFI_IPV4 1
  439. #define LSPPING_AFI_IPV4_UNMB 2
  440. #define LSPPING_AFI_IPV6 3
  441. #define LSPPING_AFI_IPV6_UNMB 4
  442. static const struct tok lspping_tlv_downstream_addr_values[] = {
  443. { LSPPING_AFI_IPV4, "IPv4"},
  444. { LSPPING_AFI_IPV4_UNMB, "Unnumbered IPv4"},
  445. { LSPPING_AFI_IPV6, "IPv6"},
  446. { LSPPING_AFI_IPV6_UNMB, "IPv6"},
  447. { 0, NULL}
  448. };
  449. void
  450. lspping_print(netdissect_options *ndo,
  451. register const u_char *pptr, register u_int len)
  452. {
  453. const struct lspping_common_header *lspping_com_header;
  454. const struct lspping_tlv_header *lspping_tlv_header;
  455. const struct lspping_tlv_header *lspping_subtlv_header;
  456. const u_char *tptr,*tlv_tptr,*subtlv_tptr;
  457. u_int tlen,lspping_tlv_len,lspping_tlv_type,tlv_tlen;
  458. int tlv_hexdump,subtlv_hexdump;
  459. u_int lspping_subtlv_len,lspping_subtlv_type;
  460. struct timeval timestamp;
  461. union {
  462. const struct lspping_tlv_downstream_map_t *lspping_tlv_downstream_map;
  463. const struct lspping_tlv_downstream_map_ipv4_t *lspping_tlv_downstream_map_ipv4;
  464. const struct lspping_tlv_downstream_map_ipv4_unmb_t *lspping_tlv_downstream_map_ipv4_unmb;
  465. const struct lspping_tlv_downstream_map_ipv6_t *lspping_tlv_downstream_map_ipv6;
  466. const struct lspping_tlv_downstream_map_ipv6_unmb_t *lspping_tlv_downstream_map_ipv6_unmb;
  467. const struct lspping_tlv_downstream_map_info_t *lspping_tlv_downstream_map_info;
  468. } tlv_ptr;
  469. union {
  470. const struct lspping_tlv_targetfec_subtlv_ldp_ipv4_t *lspping_tlv_targetfec_subtlv_ldp_ipv4;
  471. const struct lspping_tlv_targetfec_subtlv_ldp_ipv6_t *lspping_tlv_targetfec_subtlv_ldp_ipv6;
  472. const struct lspping_tlv_targetfec_subtlv_rsvp_ipv4_t *lspping_tlv_targetfec_subtlv_rsvp_ipv4;
  473. const struct lspping_tlv_targetfec_subtlv_rsvp_ipv6_t *lspping_tlv_targetfec_subtlv_rsvp_ipv6;
  474. const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t *lspping_tlv_targetfec_subtlv_l3vpn_ipv4;
  475. const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t *lspping_tlv_targetfec_subtlv_l3vpn_ipv6;
  476. const struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t *lspping_tlv_targetfec_subtlv_l2vpn_endpt;
  477. const struct lspping_tlv_targetfec_subtlv_fec_128_pw_old *lspping_tlv_targetfec_subtlv_l2vpn_vcid_old;
  478. const struct lspping_tlv_targetfec_subtlv_fec_128_pw *lspping_tlv_targetfec_subtlv_l2vpn_vcid;
  479. const struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t *lspping_tlv_targetfec_subtlv_bgp_ipv4;
  480. const struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t *lspping_tlv_targetfec_subtlv_bgp_ipv6;
  481. } subtlv_ptr;
  482. tptr=pptr;
  483. lspping_com_header = (const struct lspping_common_header *)pptr;
  484. if (len < sizeof(const struct lspping_common_header))
  485. goto tooshort;
  486. ND_TCHECK(*lspping_com_header);
  487. /*
  488. * Sanity checking of the header.
  489. */
  490. if (EXTRACT_16BITS(&lspping_com_header->version[0]) != LSPPING_VERSION) {
  491. ND_PRINT((ndo, "LSP-PING version %u packet not supported",
  492. EXTRACT_16BITS(&lspping_com_header->version[0])));
  493. return;
  494. }
  495. /* in non-verbose mode just lets print the basic Message Type*/
  496. if (ndo->ndo_vflag < 1) {
  497. ND_PRINT((ndo, "LSP-PINGv%u, %s, seq %u, length: %u",
  498. EXTRACT_16BITS(&lspping_com_header->version[0]),
  499. tok2str(lspping_msg_type_values, "unknown (%u)",lspping_com_header->msg_type),
  500. EXTRACT_32BITS(lspping_com_header->seq_number),
  501. len));
  502. return;
  503. }
  504. /* ok they seem to want to know everything - lets fully decode it */
  505. tlen=len;
  506. ND_PRINT((ndo, "\n\tLSP-PINGv%u, msg-type: %s (%u), length: %u\n\t reply-mode: %s (%u)",
  507. EXTRACT_16BITS(&lspping_com_header->version[0]),
  508. tok2str(lspping_msg_type_values, "unknown",lspping_com_header->msg_type),
  509. lspping_com_header->msg_type,
  510. len,
  511. tok2str(lspping_reply_mode_values, "unknown",lspping_com_header->reply_mode),
  512. lspping_com_header->reply_mode));
  513. /*
  514. * the following return codes require that the subcode is attached
  515. * at the end of the translated token output
  516. */
  517. if (lspping_com_header->return_code == 3 ||
  518. lspping_com_header->return_code == 4 ||
  519. lspping_com_header->return_code == 8 ||
  520. lspping_com_header->return_code == 10 ||
  521. lspping_com_header->return_code == 11 ||
  522. lspping_com_header->return_code == 12 )
  523. ND_PRINT((ndo, "\n\t Return Code: %s %u (%u)\n\t Return Subcode: (%u)",
  524. tok2str(lspping_return_code_values, "unknown",lspping_com_header->return_code),
  525. lspping_com_header->return_subcode,
  526. lspping_com_header->return_code,
  527. lspping_com_header->return_subcode));
  528. else
  529. ND_PRINT((ndo, "\n\t Return Code: %s (%u)\n\t Return Subcode: (%u)",
  530. tok2str(lspping_return_code_values, "unknown",lspping_com_header->return_code),
  531. lspping_com_header->return_code,
  532. lspping_com_header->return_subcode));
  533. ND_PRINT((ndo, "\n\t Sender Handle: 0x%08x, Sequence: %u",
  534. EXTRACT_32BITS(lspping_com_header->sender_handle),
  535. EXTRACT_32BITS(lspping_com_header->seq_number)));
  536. timestamp.tv_sec=EXTRACT_32BITS(lspping_com_header->ts_sent_sec);
  537. timestamp.tv_usec=EXTRACT_32BITS(lspping_com_header->ts_sent_usec);
  538. ND_PRINT((ndo, "\n\t Sender Timestamp: "));
  539. ts_print(ndo, &timestamp);
  540. timestamp.tv_sec=EXTRACT_32BITS(lspping_com_header->ts_rcvd_sec);
  541. timestamp.tv_usec=EXTRACT_32BITS(lspping_com_header->ts_rcvd_usec);
  542. ND_PRINT((ndo, "Receiver Timestamp: "));
  543. if ((timestamp.tv_sec != 0) && (timestamp.tv_usec != 0))
  544. ts_print(ndo, &timestamp);
  545. else
  546. ND_PRINT((ndo, "no timestamp"));
  547. tptr+=sizeof(const struct lspping_common_header);
  548. tlen-=sizeof(const struct lspping_common_header);
  549. while (tlen != 0) {
  550. /* Does the TLV go past the end of the packet? */
  551. if (tlen < sizeof(struct lspping_tlv_header))
  552. goto tooshort;
  553. /* did we capture enough for fully decoding the tlv header ? */
  554. ND_TCHECK2(*tptr, sizeof(struct lspping_tlv_header));
  555. lspping_tlv_header = (const struct lspping_tlv_header *)tptr;
  556. lspping_tlv_type=EXTRACT_16BITS(lspping_tlv_header->type);
  557. lspping_tlv_len=EXTRACT_16BITS(lspping_tlv_header->length);
  558. ND_PRINT((ndo, "\n\t %s TLV (%u), length: %u",
  559. tok2str(lspping_tlv_values,
  560. "Unknown",
  561. lspping_tlv_type),
  562. lspping_tlv_type,
  563. lspping_tlv_len));
  564. /* some little sanity checking */
  565. if (lspping_tlv_len == 0) {
  566. tptr+=sizeof(struct lspping_tlv_header);
  567. tlen-=sizeof(struct lspping_tlv_header);
  568. continue; /* no value to dissect */
  569. }
  570. tlv_tptr=tptr+sizeof(struct lspping_tlv_header);
  571. tlv_tlen=lspping_tlv_len; /* header not included -> no adjustment */
  572. /* Does the TLV go past the end of the packet? */
  573. if (tlen < lspping_tlv_len+sizeof(struct lspping_tlv_header))
  574. goto tooshort;
  575. /* did we capture enough for fully decoding the tlv ? */
  576. ND_TCHECK2(*tlv_tptr, lspping_tlv_len);
  577. tlv_hexdump=FALSE;
  578. switch(lspping_tlv_type) {
  579. case LSPPING_TLV_TARGET_FEC_STACK:
  580. while (tlv_tlen != 0) {
  581. /* Does the subTLV header go past the end of the TLV? */
  582. if (tlv_tlen < sizeof(struct lspping_tlv_header)) {
  583. ND_PRINT((ndo, "\n\t TLV is too short"));
  584. tlv_hexdump = TRUE;
  585. goto tlv_tooshort;
  586. }
  587. /* did we capture enough for fully decoding the subtlv header ? */
  588. ND_TCHECK2(*tlv_tptr, sizeof(struct lspping_tlv_header));
  589. subtlv_hexdump=FALSE;
  590. lspping_subtlv_header = (const struct lspping_tlv_header *)tlv_tptr;
  591. lspping_subtlv_type=EXTRACT_16BITS(lspping_subtlv_header->type);
  592. lspping_subtlv_len=EXTRACT_16BITS(lspping_subtlv_header->length);
  593. subtlv_tptr=tlv_tptr+sizeof(struct lspping_tlv_header);
  594. /* Does the subTLV go past the end of the TLV? */
  595. if (tlv_tlen < lspping_subtlv_len+sizeof(struct lspping_tlv_header)) {
  596. ND_PRINT((ndo, "\n\t TLV is too short"));
  597. tlv_hexdump = TRUE;
  598. goto tlv_tooshort;
  599. }
  600. /* Did we capture enough for fully decoding the subTLV? */
  601. ND_TCHECK2(*subtlv_tptr, lspping_subtlv_len);
  602. ND_PRINT((ndo, "\n\t %s subTLV (%u), length: %u",
  603. tok2str(lspping_tlvtargetfec_subtlv_values,
  604. "Unknown",
  605. lspping_subtlv_type),
  606. lspping_subtlv_type,
  607. lspping_subtlv_len));
  608. switch(lspping_subtlv_type) {
  609. case LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV4:
  610. /* Is the subTLV length correct? */
  611. if (lspping_subtlv_len != 5) {
  612. ND_PRINT((ndo, "\n\t invalid subTLV length, should be 5"));
  613. subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
  614. } else {
  615. subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv4 = \
  616. (const struct lspping_tlv_targetfec_subtlv_ldp_ipv4_t *)subtlv_tptr;
  617. ND_PRINT((ndo, "\n\t %s/%u",
  618. ipaddr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv4->prefix),
  619. subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv4->prefix_len));
  620. }
  621. break;
  622. case LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV6:
  623. /* Is the subTLV length correct? */
  624. if (lspping_subtlv_len != 17) {
  625. ND_PRINT((ndo, "\n\t invalid subTLV length, should be 17"));
  626. subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
  627. } else {
  628. subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6 = \
  629. (const struct lspping_tlv_targetfec_subtlv_ldp_ipv6_t *)subtlv_tptr;
  630. ND_PRINT((ndo, "\n\t %s/%u",
  631. ip6addr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6->prefix),
  632. subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6->prefix_len));
  633. }
  634. break;
  635. case LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4:
  636. /* Is the subTLV length correct? */
  637. if (lspping_subtlv_len != 5) {
  638. ND_PRINT((ndo, "\n\t invalid subTLV length, should be 5"));
  639. subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
  640. } else {
  641. subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4 = \
  642. (const struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t *)subtlv_tptr;
  643. ND_PRINT((ndo, "\n\t %s/%u",
  644. ipaddr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4->prefix),
  645. subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4->prefix_len));
  646. }
  647. break;
  648. case LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6:
  649. /* Is the subTLV length correct? */
  650. if (lspping_subtlv_len != 17) {
  651. ND_PRINT((ndo, "\n\t invalid subTLV length, should be 17"));
  652. subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
  653. } else {
  654. subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6 = \
  655. (const struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t *)subtlv_tptr;
  656. ND_PRINT((ndo, "\n\t %s/%u",
  657. ip6addr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6->prefix),
  658. subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6->prefix_len));
  659. }
  660. break;
  661. case LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV4:
  662. /* Is the subTLV length correct? */
  663. if (lspping_subtlv_len != 20) {
  664. ND_PRINT((ndo, "\n\t invalid subTLV length, should be 20"));
  665. subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
  666. } else {
  667. subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4 = \
  668. (const struct lspping_tlv_targetfec_subtlv_rsvp_ipv4_t *)subtlv_tptr;
  669. ND_PRINT((ndo, "\n\t tunnel end-point %s, tunnel sender %s, lsp-id 0x%04x" \
  670. "\n\t tunnel-id 0x%04x, extended tunnel-id %s",
  671. ipaddr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_endpoint),
  672. ipaddr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_sender),
  673. EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->lsp_id),
  674. EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_id),
  675. ipaddr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->extended_tunnel_id)));
  676. }
  677. break;
  678. case LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV6:
  679. /* Is the subTLV length correct? */
  680. if (lspping_subtlv_len != 56) {
  681. ND_PRINT((ndo, "\n\t invalid subTLV length, should be 56"));
  682. subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
  683. } else {
  684. subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6 = \
  685. (const struct lspping_tlv_targetfec_subtlv_rsvp_ipv6_t *)subtlv_tptr;
  686. ND_PRINT((ndo, "\n\t tunnel end-point %s, tunnel sender %s, lsp-id 0x%04x" \
  687. "\n\t tunnel-id 0x%04x, extended tunnel-id %s",
  688. ip6addr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_endpoint),
  689. ip6addr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_sender),
  690. EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->lsp_id),
  691. EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_id),
  692. ip6addr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->extended_tunnel_id)));
  693. }
  694. break;
  695. case LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4:
  696. /* Is the subTLV length correct? */
  697. if (lspping_subtlv_len != 13) {
  698. ND_PRINT((ndo, "\n\t invalid subTLV length, should be 13"));
  699. subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
  700. } else {
  701. subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4 = \
  702. (const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t *)subtlv_tptr;
  703. ND_PRINT((ndo, "\n\t RD: %s, %s/%u",
  704. bgp_vpn_rd_print(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->rd),
  705. ipaddr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->prefix),
  706. subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->prefix_len));
  707. }
  708. break;
  709. case LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6:
  710. /* Is the subTLV length correct? */
  711. if (lspping_subtlv_len != 25) {
  712. ND_PRINT((ndo, "\n\t invalid subTLV length, should be 25"));
  713. subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
  714. } else {
  715. subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6 = \
  716. (const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t *)subtlv_tptr;
  717. ND_PRINT((ndo, "\n\t RD: %s, %s/%u",
  718. bgp_vpn_rd_print(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->rd),
  719. ip6addr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->prefix),
  720. subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->prefix_len));
  721. }
  722. break;
  723. case LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT:
  724. /* Is the subTLV length correct? */
  725. if (lspping_subtlv_len != 14) {
  726. ND_PRINT((ndo, "\n\t invalid subTLV length, should be 14"));
  727. subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
  728. } else {
  729. subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt = \
  730. (const struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t *)subtlv_tptr;
  731. ND_PRINT((ndo, "\n\t RD: %s, Sender VE ID: %u, Receiver VE ID: %u" \
  732. "\n\t Encapsulation Type: %s (%u)",
  733. bgp_vpn_rd_print(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->rd),
  734. EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->sender_ve_id),
  735. EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->receiver_ve_id),
  736. tok2str(mpls_pw_types_values,
  737. "unknown",
  738. EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->encapsulation)),
  739. EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->encapsulation)));
  740. }
  741. break;
  742. /* the old L2VPN VCID subTLV does not have support for the sender field */
  743. case LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW_OLD:
  744. /* Is the subTLV length correct? */
  745. if (lspping_subtlv_len != 10) {
  746. ND_PRINT((ndo, "\n\t invalid subTLV length, should be 10"));
  747. subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
  748. } else {
  749. subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old = \
  750. (const struct lspping_tlv_targetfec_subtlv_fec_128_pw_old *)subtlv_tptr;
  751. ND_PRINT((ndo, "\n\t Remote PE: %s" \
  752. "\n\t PW ID: 0x%08x, PW Type: %s (%u)",
  753. ipaddr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->remote_pe_address),
  754. EXTRACT_32BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->pw_id),
  755. tok2str(mpls_pw_types_values,
  756. "unknown",
  757. EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->pw_type)),
  758. EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->pw_type)));
  759. }
  760. break;
  761. case LSPPING_TLV_TARGETFEC_SUBTLV_FEC_128_PW:
  762. /* Is the subTLV length correct? */
  763. if (lspping_subtlv_len != 14) {
  764. ND_PRINT((ndo, "\n\t invalid subTLV length, should be 14"));
  765. subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
  766. } else {
  767. subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid = \
  768. (const struct lspping_tlv_targetfec_subtlv_fec_128_pw *)subtlv_tptr;
  769. ND_PRINT((ndo, "\n\t Sender PE: %s, Remote PE: %s" \
  770. "\n\t PW ID: 0x%08x, PW Type: %s (%u)",
  771. ipaddr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->sender_pe_address),
  772. ipaddr_string(ndo, subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->remote_pe_address),
  773. EXTRACT_32BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->pw_id),
  774. tok2str(mpls_pw_types_values,
  775. "unknown",
  776. EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->pw_type)),
  777. EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->pw_type)));
  778. }
  779. break;
  780. default:
  781. subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
  782. break;
  783. }
  784. /* do we want to see an additionally subtlv hexdump ? */
  785. if (ndo->ndo_vflag > 1 || subtlv_hexdump==TRUE)
  786. print_unknown_data(ndo, tlv_tptr+sizeof(struct lspping_tlv_header), \
  787. "\n\t ",
  788. lspping_subtlv_len);
  789. /* All subTLVs are aligned to four octet boundary */
  790. if (lspping_subtlv_len % 4) {
  791. lspping_subtlv_len += 4 - (lspping_subtlv_len % 4);
  792. /* Does the subTLV, including padding, go past the end of the TLV? */
  793. if (tlv_tlen < lspping_subtlv_len+sizeof(struct lspping_tlv_header)) {
  794. ND_PRINT((ndo, "\n\t\t TLV is too short"));
  795. return;
  796. }
  797. }
  798. tlv_tptr+=lspping_subtlv_len;
  799. tlv_tlen-=lspping_subtlv_len+sizeof(struct lspping_tlv_header);
  800. }
  801. break;
  802. case LSPPING_TLV_DOWNSTREAM_MAPPING:
  803. /* Does the header go past the end of the TLV? */
  804. if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_t)) {
  805. ND_PRINT((ndo, "\n\t TLV is too short"));
  806. tlv_hexdump = TRUE;
  807. goto tlv_tooshort;
  808. }
  809. /* Did we capture enough to get the address family? */
  810. ND_TCHECK2(*tlv_tptr, sizeof(struct lspping_tlv_downstream_map_t));
  811. tlv_ptr.lspping_tlv_downstream_map= \
  812. (const struct lspping_tlv_downstream_map_t *)tlv_tptr;
  813. /* that strange thing with the downstream map TLV is that until now
  814. * we do not know if its IPv4 or IPv6 or is unnumbered; after
  815. * we find the address-type, we recast the tlv_tptr and move on. */
  816. ND_PRINT((ndo, "\n\t MTU: %u, Address-Type: %s (%u)",
  817. EXTRACT_16BITS(tlv_ptr.lspping_tlv_downstream_map->mtu),
  818. tok2str(lspping_tlv_downstream_addr_values,
  819. "unknown",
  820. tlv_ptr.lspping_tlv_downstream_map->address_type),
  821. tlv_ptr.lspping_tlv_downstream_map->address_type));
  822. switch(tlv_ptr.lspping_tlv_downstream_map->address_type) {
  823. case LSPPING_AFI_IPV4:
  824. /* Does the data go past the end of the TLV? */
  825. if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_ipv4_t)) {
  826. ND_PRINT((ndo, "\n\t TLV is too short"));
  827. tlv_hexdump = TRUE;
  828. goto tlv_tooshort;
  829. }
  830. /* Did we capture enough for this part of the TLV? */
  831. ND_TCHECK2(*tlv_tptr, sizeof(struct lspping_tlv_downstream_map_ipv4_t));
  832. tlv_ptr.lspping_tlv_downstream_map_ipv4= \
  833. (const struct lspping_tlv_downstream_map_ipv4_t *)tlv_tptr;
  834. ND_PRINT((ndo, "\n\t Downstream IP: %s" \
  835. "\n\t Downstream Interface IP: %s",
  836. ipaddr_string(ndo, tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_ip),
  837. ipaddr_string(ndo, tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_interface)));
  838. tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv4_t);
  839. tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv4_t);
  840. break;
  841. case LSPPING_AFI_IPV4_UNMB:
  842. /* Does the data go past the end of the TLV? */
  843. if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t)) {
  844. ND_PRINT((ndo, "\n\t TLV is too short"));
  845. tlv_hexdump = TRUE;
  846. goto tlv_tooshort;
  847. }
  848. /* Did we capture enough for this part of the TLV? */
  849. ND_TCHECK2(*tlv_tptr, sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t));
  850. tlv_ptr.lspping_tlv_downstream_map_ipv4_unmb= \
  851. (const struct lspping_tlv_downstream_map_ipv4_unmb_t *)tlv_tptr;
  852. ND_PRINT((ndo, "\n\t Downstream IP: %s" \
  853. "\n\t Downstream Interface Index: 0x%08x",
  854. ipaddr_string(ndo, tlv_ptr.lspping_tlv_downstream_map_ipv4_unmb->downstream_ip),
  855. EXTRACT_32BITS(tlv_ptr.lspping_tlv_downstream_map_ipv4_unmb->downstream_interface)));
  856. tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t);
  857. tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv4_unmb_t);
  858. break;
  859. case LSPPING_AFI_IPV6:
  860. /* Does the data go past the end of the TLV? */
  861. if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_ipv6_t)) {
  862. ND_PRINT((ndo, "\n\t TLV is too short"));
  863. tlv_hexdump = TRUE;
  864. goto tlv_tooshort;
  865. }
  866. /* Did we capture enough for this part of the TLV? */
  867. ND_TCHECK2(*tlv_tptr, sizeof(struct lspping_tlv_downstream_map_ipv6_t));
  868. tlv_ptr.lspping_tlv_downstream_map_ipv6= \
  869. (const struct lspping_tlv_downstream_map_ipv6_t *)tlv_tptr;
  870. ND_PRINT((ndo, "\n\t Downstream IP: %s" \
  871. "\n\t Downstream Interface IP: %s",
  872. ip6addr_string(ndo, tlv_ptr.lspping_tlv_downstream_map_ipv6->downstream_ip),
  873. ip6addr_string(ndo, tlv_ptr.lspping_tlv_downstream_map_ipv6->downstream_interface)));
  874. tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv6_t);
  875. tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv6_t);
  876. break;
  877. case LSPPING_AFI_IPV6_UNMB:
  878. /* Does the data go past the end of the TLV? */
  879. if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t)) {
  880. ND_PRINT((ndo, "\n\t TLV is too short"));
  881. tlv_hexdump = TRUE;
  882. goto tlv_tooshort;
  883. }
  884. /* Did we capture enough for this part of the TLV? */
  885. ND_TCHECK2(*tlv_tptr, sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t));
  886. tlv_ptr.lspping_tlv_downstream_map_ipv6_unmb= \
  887. (const struct lspping_tlv_downstream_map_ipv6_unmb_t *)tlv_tptr;
  888. ND_PRINT((ndo, "\n\t Downstream IP: %s" \
  889. "\n\t Downstream Interface Index: 0x%08x",
  890. ip6addr_string(ndo, tlv_ptr.lspping_tlv_downstream_map_ipv6_unmb->downstream_ip),
  891. EXTRACT_32BITS(tlv_ptr.lspping_tlv_downstream_map_ipv6_unmb->downstream_interface)));
  892. tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t);
  893. tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv6_unmb_t);
  894. break;
  895. default:
  896. /* should not happen ! - no error message - tok2str() has barked already */
  897. break;
  898. }
  899. /* Does the data go past the end of the TLV? */
  900. if (tlv_tlen < sizeof(struct lspping_tlv_downstream_map_info_t)) {
  901. ND_PRINT((ndo, "\n\t TLV is too short"));
  902. tlv_hexdump = TRUE;
  903. goto tlv_tooshort;
  904. }
  905. /* Did we capture enough for this part of the TLV? */
  906. ND_TCHECK2(*tlv_tptr, sizeof(struct lspping_tlv_downstream_map_info_t));
  907. tlv_ptr.lspping_tlv_downstream_map_info= \
  908. (const struct lspping_tlv_downstream_map_info_t *)tlv_tptr;
  909. /* FIXME add hash-key type, depth limit, multipath processing */
  910. tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_info_t);
  911. tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_info_t);
  912. /* FIXME print downstream labels */
  913. tlv_hexdump=TRUE; /* dump the TLV until code complete */
  914. break;
  915. case LSPPING_TLV_BFD_DISCRIMINATOR:
  916. if (tlv_tlen < LSPPING_TLV_BFD_DISCRIMINATOR_LEN) {
  917. ND_PRINT((ndo, "\n\t TLV is too short"));
  918. tlv_hexdump = TRUE;
  919. goto tlv_tooshort;
  920. } else {
  921. ND_TCHECK2(*tptr, LSPPING_TLV_BFD_DISCRIMINATOR_LEN);
  922. ND_PRINT((ndo, "\n\t BFD Discriminator 0x%08x", EXTRACT_32BITS(tptr)));
  923. }
  924. break;
  925. case LSPPING_TLV_VENDOR_ENTERPRISE:
  926. {
  927. uint32_t vendor_id;
  928. if (tlv_tlen < LSPPING_TLV_VENDOR_ENTERPRISE_LEN) {
  929. ND_PRINT((ndo, "\n\t TLV is too short"));
  930. tlv_hexdump = TRUE;
  931. goto tlv_tooshort;
  932. } else {
  933. ND_TCHECK2(*tptr, LSPPING_TLV_VENDOR_ENTERPRISE_LEN);
  934. vendor_id = EXTRACT_32BITS(tlv_tptr);
  935. ND_PRINT((ndo, "\n\t Vendor: %s (0x%04x)",
  936. tok2str(smi_values, "Unknown", vendor_id),
  937. vendor_id));
  938. }
  939. }
  940. break;
  941. /*
  942. * FIXME those are the defined TLVs that lack a decoder
  943. * you are welcome to contribute code ;-)
  944. */
  945. case LSPPING_TLV_PAD:
  946. case LSPPING_TLV_ERROR_CODE:
  947. case LSPPING_TLV_VENDOR_PRIVATE:
  948. default:
  949. if (ndo->ndo_vflag <= 1)
  950. print_unknown_data(ndo, tlv_tptr, "\n\t ", tlv_tlen);
  951. break;
  952. }
  953. /* do we want to see an additionally tlv hexdump ? */
  954. tlv_tooshort:
  955. if (ndo->ndo_vflag > 1 || tlv_hexdump==TRUE)
  956. print_unknown_data(ndo, tptr+sizeof(struct lspping_tlv_header), "\n\t ",
  957. lspping_tlv_len);
  958. /* All TLVs are aligned to four octet boundary */
  959. if (lspping_tlv_len % 4) {
  960. lspping_tlv_len += (4 - lspping_tlv_len % 4);
  961. /* Does the TLV, including padding, go past the end of the packet? */
  962. if (tlen < lspping_tlv_len+sizeof(struct lspping_tlv_header))
  963. goto tooshort;
  964. }
  965. tptr+=lspping_tlv_len+sizeof(struct lspping_tlv_header);
  966. tlen-=lspping_tlv_len+sizeof(struct lspping_tlv_header);
  967. }
  968. return;
  969. tooshort:
  970. ND_PRINT((ndo, "\n\t\t packet is too short"));
  971. return;
  972. trunc:
  973. ND_PRINT((ndo, "\n\t\t packet exceeded snapshot"));
  974. return;
  975. }
  976. /*
  977. * Local Variables:
  978. * c-style: whitesmith
  979. * c-basic-offset: 8
  980. * End:
  981. */