print-ipfc.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /*
  2. * Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997
  3. * The Regents of the University of California. All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that: (1) source code distributions
  7. * retain the above copyright notice and this paragraph in its entirety, (2)
  8. * distributions including binary code include the above copyright notice and
  9. * this paragraph in its entirety in the documentation or other materials
  10. * provided with the distribution, and (3) all advertising materials mentioning
  11. * features or use of this software display the following acknowledgement:
  12. * ``This product includes software developed by the University of California,
  13. * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  14. * the University nor the names of its contributors may be used to endorse
  15. * or promote products derived from this software without specific prior
  16. * written permission.
  17. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  18. * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  19. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  20. */
  21. /* \summary: IP over Fibre Channel printer */
  22. /* specification: RFC 2625 */
  23. #ifdef HAVE_CONFIG_H
  24. #include "config.h"
  25. #endif
  26. #include <netdissect-stdinc.h>
  27. #include <string.h>
  28. #include "netdissect.h"
  29. #include "addrtoname.h"
  30. #include "ether.h"
  31. struct ipfc_header {
  32. u_char ipfc_dhost[8];
  33. u_char ipfc_shost[8];
  34. };
  35. #define IPFC_HDRLEN 16
  36. /* Extract src, dst addresses */
  37. static inline void
  38. extract_ipfc_addrs(const struct ipfc_header *ipfcp, char *ipfcsrc,
  39. char *ipfcdst)
  40. {
  41. /*
  42. * We assume that, as per RFC 2625, the lower 48 bits of the
  43. * source and destination addresses are MAC addresses.
  44. */
  45. memcpy(ipfcdst, (const char *)&ipfcp->ipfc_dhost[2], 6);
  46. memcpy(ipfcsrc, (const char *)&ipfcp->ipfc_shost[2], 6);
  47. }
  48. /*
  49. * Print the Network_Header
  50. */
  51. static inline void
  52. ipfc_hdr_print(netdissect_options *ndo,
  53. register const struct ipfc_header *ipfcp _U_,
  54. register u_int length, register const u_char *ipfcsrc,
  55. register const u_char *ipfcdst)
  56. {
  57. const char *srcname, *dstname;
  58. srcname = etheraddr_string(ndo, ipfcsrc);
  59. dstname = etheraddr_string(ndo, ipfcdst);
  60. /*
  61. * XXX - should we show the upper 16 bits of the addresses?
  62. * Do so only if "vflag" is set?
  63. * Section 3.3 "FC Port and Node Network Addresses" says that
  64. *
  65. * In this specification, both the Source and Destination
  66. * 4-bit NAA identifiers SHALL be set to binary '0001'
  67. * indicating that an IEEE 48-bit MAC address is contained
  68. * in the lower 48 bits of the network address fields. The
  69. * high order 12 bits in the network address fields SHALL
  70. * be set to 0x0000.
  71. *
  72. * so, for captures following this specification, the upper 16
  73. * bits should be 0x1000, followed by a MAC address.
  74. */
  75. ND_PRINT((ndo, "%s > %s, length %u: ", srcname, dstname, length));
  76. }
  77. static u_int
  78. ipfc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen)
  79. {
  80. const struct ipfc_header *ipfcp = (const struct ipfc_header *)p;
  81. struct ether_header ehdr;
  82. struct lladdr_info src, dst;
  83. int llc_hdrlen;
  84. if (caplen < IPFC_HDRLEN) {
  85. ND_PRINT((ndo, "[|ipfc]"));
  86. return (caplen);
  87. }
  88. /*
  89. * Get the network addresses into a canonical form
  90. */
  91. extract_ipfc_addrs(ipfcp, (char *)ESRC(&ehdr), (char *)EDST(&ehdr));
  92. if (ndo->ndo_eflag)
  93. ipfc_hdr_print(ndo, ipfcp, length, ESRC(&ehdr), EDST(&ehdr));
  94. src.addr = ESRC(&ehdr);
  95. src.addr_string = etheraddr_string;
  96. dst.addr = EDST(&ehdr);
  97. dst.addr_string = etheraddr_string;
  98. /* Skip over Network_Header */
  99. length -= IPFC_HDRLEN;
  100. p += IPFC_HDRLEN;
  101. caplen -= IPFC_HDRLEN;
  102. /* Try to print the LLC-layer header & higher layers */
  103. llc_hdrlen = llc_print(ndo, p, length, caplen, &src, &dst);
  104. if (llc_hdrlen < 0) {
  105. /*
  106. * Some kinds of LLC packet we cannot
  107. * handle intelligently
  108. */
  109. if (!ndo->ndo_suppress_default_print)
  110. ND_DEFAULTPRINT(p, caplen);
  111. llc_hdrlen = -llc_hdrlen;
  112. }
  113. return (IPFC_HDRLEN + llc_hdrlen);
  114. }
  115. /*
  116. * This is the top level routine of the printer. 'p' points
  117. * to the Network_Header of the packet, 'h->ts' is the timestamp,
  118. * 'h->len' is the length of the packet off the wire, and 'h->caplen'
  119. * is the number of bytes actually captured.
  120. */
  121. u_int
  122. ipfc_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, register const u_char *p)
  123. {
  124. return (ipfc_print(ndo, p, h->len, h->caplen));
  125. }