#include "netdissect-stdinc.h"
+#define ND_LONGJMP_FROM_TCHECK
#include "netdissect.h"
#include "ethertype.h"
#include "addrtoname.h"
#include "extract.h"
-struct ether_header {
- nd_mac_addr ether_dhost;
- nd_mac_addr ether_shost;
- nd_uint16_t ether_length_type;
-};
-
-#define ETHER_SA_OFFSET 12
#define ETHER_TYPE_LEN 2
#define BRCM_TAG_LEN 4
{ 0, NULL }
};
-static int brcm_tag_print_full(netdissect_options *ndo, const u_char *bp,
- u_int length)
+static void
+brcm_tag_print(netdissect_options *ndo, const u_char *bp)
{
uint8_t tag[BRCM_TAG_LEN];
uint16_t dst_map;
unsigned int i;
- if (length < BRCM_TAG_LEN)
- return (1);
-
for (i = 0; i < BRCM_TAG_LEN; i++)
tag[i] = GET_U_1(bp + i);
ND_PRINT(", port: %d", tag[3] & BRCM_EG_PID_MASK);
}
ND_PRINT(", ");
-
- return (0);
}
-u_int
+void
brcm_tag_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h,
const u_char *p)
{
- const struct ether_header *ehp;
- int old_eflag = ndo->ndo_eflag;
u_int caplen = h->caplen;
u_int length = h->len;
- int ret;
ndo->ndo_protocol = "brcm-tag";
- if (caplen < ETHER_SA_OFFSET + BRCM_TAG_LEN) {
- nd_print_trunc(ndo);
- return (caplen);
- }
-
- if (length < ETHER_SA_OFFSET + BRCM_TAG_LEN) {
- nd_print_trunc(ndo);
- return (length);
- }
-
- ehp = (const struct ether_header *)p;
- if (ndo->ndo_eflag)
- ND_PRINT("%s > %s, ",
- etheraddr_string(ndo, ehp->ether_shost),
- etheraddr_string(ndo, ehp->ether_dhost));
-
- if (brcm_tag_print_full(ndo, p + ETHER_SA_OFFSET,
- caplen - ETHER_SA_OFFSET))
- return (1);
-
- /* We printed the Ethernet header already */
- ndo->ndo_eflag = 0;
-
- /* Parse the Ethernet frame regularly telling how big the non
- * standard Ethernet header is.
- *
- * +-----------++-----------++----------------++--------------+
- * | MAC DA (6)|| MAC SA (6)||Broadcom tag (4)||Type/Length(2)|
- * +-----------++-----------++----------------++--------------+
- */
- ret = ether_hdr_len_print(ndo, p, length, caplen, NULL, NULL,
- ETHER_SA_OFFSET + BRCM_TAG_LEN + ETHER_TYPE_LEN);
- ndo->ndo_eflag = old_eflag;
- return ret;
-}
-
-static void brcm_tag_print_encap(netdissect_options *ndo,
- const u_char *p)
-{
- brcm_tag_print_full(ndo, p, BRCM_TAG_LEN);
+ ndo->ndo_ll_hdr_len +=
+ ether_switch_tag_print(ndo, p, length, caplen,
+ brcm_tag_print, BRCM_TAG_LEN);
}
-u_int
+void
brcm_tag_prepend_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h,
const u_char *p)
{
u_int length = h->len;
ndo->ndo_protocol = "brcm-tag-prepend";
- if (caplen < BRCM_TAG_LEN) {
- nd_print_trunc(ndo);
- return (caplen);
- }
+ ND_TCHECK_LEN(p, BRCM_TAG_LEN);
+ ndo->ndo_ll_hdr_len += BRCM_TAG_LEN;
- if (length < BRCM_TAG_LEN) {
- nd_print_trunc(ndo);
- return (length);
+ if (ndo->ndo_eflag) {
+ /* Print the prepended Broadcom tag. */
+ brcm_tag_print(ndo, p);
}
+ p += BRCM_TAG_LEN;
+ length -= BRCM_TAG_LEN;
+ caplen -= BRCM_TAG_LEN;
- /* Parse the Ethernet frame regularly and utilize the encapsulation
- * header printing facility to pring the pre-pended Broadcom tag.
- *
- * +-----------------++-----------++-----------++--------------+
- * | Broadcom tag (4)|| MAC DA (6)|| MAC SA (6)||Type/Length(2)|
- * +-----------------++-----------++-----------++--------------+
+ /*
+ * Now print the Ethernet frame following it.
*/
- return ether_print(ndo, p + BRCM_TAG_LEN,
- length - BRCM_TAG_LEN,
- caplen - BRCM_TAG_LEN, brcm_tag_print_encap, p);
+ ndo->ndo_ll_hdr_len +=
+ ether_print(ndo, p, length, caplen, NULL, NULL);
}