/*
 * netsniff-ng - the packet sniffing beast
 * Copyright 2012 Markus Amend <markus@netsniff-ng.org>, Deutsche Flugsicherung GmbH
 * Subject to the GPL, version 2.
 *
 * http://www.ieee802.org/1/pages/802.1ad.html
 */

#include <stdio.h>
#include <stdint.h>
#include <netinet/in.h>    /* for ntohs() */

#include "proto.h"
#include "protos.h"
#include "dissector_eth.h"
#include "built_in.h"
#include "pkt_buff.h"

struct QinQhdr {
	uint16_t TCI;
	uint16_t TPID;
} __packed;

static void QinQ_full(struct pkt_buff *pkt)
{
	uint16_t tci;
	struct QinQhdr *QinQ = (struct QinQhdr *) pkt_pull(pkt, sizeof(*QinQ));

	if (QinQ == NULL)
		return;

	tci = ntohs(QinQ->TCI);

	tprintf(" [ VLAN QinQ ");
	tprintf("Prio (%d), ", (tci & 0xE000) >> 13);
	tprintf("DEI (%d), ", (tci & 0x1000) >> 12);
	tprintf("ID (%d), ", (tci & 0x0FFF));
	tprintf("Proto (0x%.4x)", ntohs(QinQ->TPID));
	tprintf(" ]\n");

	pkt_set_proto(pkt, &eth_lay2, ntohs(QinQ->TPID));
}

static void QinQ_less(struct pkt_buff *pkt)
{
	uint16_t tci;
	struct QinQhdr *QinQ = (struct QinQhdr *) pkt_pull(pkt, sizeof(*QinQ));

	if (QinQ == NULL)
		return;

	tci = ntohs(QinQ->TCI);

	tprintf(" VLAN%d", (tci & 0x0FFF));

	pkt_set_proto(pkt, &eth_lay2, ntohs(QinQ->TPID));
}

struct protocol QinQ_ops = {
	.key = 0x88a8,
	.print_full = QinQ_full,
	.print_less = QinQ_less,
};
value='switch'/></form></td></tr>
<tr><td class='sub'>net-next plumbings</td><td class='sub right'>Tobias Klauser</td></tr></table>
<table class='tabs'><tr><td>
<a href='/cgit.cgi/linux/net-next.git/'>summary</a><a href='/cgit.cgi/linux/net-next.git/refs/?id=a960dec98861b009b4227d2ae3b94a142c83eb96'>refs</a><a class='active' href='/cgit.cgi/linux/net-next.git/log/include/trace/events/module.h'>log</a><a href='/cgit.cgi/linux/net-next.git/tree/include/trace/events/module.h?id=a960dec98861b009b4227d2ae3b94a142c83eb96'>tree</a><a href='/cgit.cgi/linux/net-next.git/commit/include/trace/events/module.h?id=a960dec98861b009b4227d2ae3b94a142c83eb96'>commit</a><a href='/cgit.cgi/linux/net-next.git/diff/include/trace/events/module.h?id=a960dec98861b009b4227d2ae3b94a142c83eb96'>diff</a></td><td class='form'><form class='right' method='get' action='/cgit.cgi/linux/net-next.git/log/include/trace/events/module.h'>
<input type='hidden' name='id' value='a960dec98861b009b4227d2ae3b94a142c83eb96'/><select name='qt'>
<option value='grep'>log msg</option>
<option value='author'>author</option>
<option value='committer'>committer</option>
<option value='range'>range</option>
</select>
<input class='txt' type='search' size='10' name='q' value=''/>
<input type='submit' value='search'/>
</form>
</td></tr></table>
<div class='path'>path: <a href='/cgit.cgi/linux/net-next.git/log/?id=a960dec98861b009b4227d2ae3b94a142c83eb96'>root</a>/<a href='/cgit.cgi/linux/net-next.git/log/include?id=a960dec98861b009b4227d2ae3b94a142c83eb96'>include</a>/<a href='/cgit.cgi/linux/net-next.git/log/include/trace?id=a960dec98861b009b4227d2ae3b94a142c83eb96'>trace</a>/<a href='/cgit.cgi/linux/net-next.git/log/include/trace/events?id=a960dec98861b009b4227d2ae3b94a142c83eb96'>events</a>/<a href='/cgit.cgi/linux/net-next.git/log/include/trace/events/module.h?id=a960dec98861b009b4227d2ae3b94a142c83eb96'>module.h</a></div><div class='content'><table class='list nowrap'><tr class='nohover'><th class='left'>Age</th><th class='left'>Commit message (<a href='/cgit.cgi/linux/net-next.git/log/include/trace/events/module.h?id=a960dec98861b009b4227d2ae3b94a142c83eb96&amp;showmsg=1'>Expand</a>)</th><th class='left'>Author</th><th class='left'>Files</th><th class='left'>Lines</th></tr>