mausezahn: use getopt_long instead of getopt
[netsniff-ng.git] / proto_mpls_unicast.c
blob69c01f3fa8cc1aed1afa57e926e0a9c3c7dc44c6
1 /*
2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2012 Markus Amend <markus@netsniff-ng.org>, Deutsche Flugsicherung GmbH
4 * Subject to the GPL, version 2.
6 * http://tools.ietf.org/html/rfc3032
7 */
9 #include <stdio.h>
10 #include <stdint.h>
11 #include <netinet/in.h> /* for ntohs() */
12 #include <errno.h>
14 #include "proto.h"
15 #include "dissector_eth.h"
16 #include "built_in.h"
17 #include "pkt_buff.h"
19 struct mpls_uchdr {
20 uint32_t mpls_uc_hdr;
21 } __packed;
23 static int mpls_uc_next_proto(struct pkt_buff *pkt)
25 uint8_t proto;
26 uint16_t key = 0;
28 if (pkt_len(pkt))
29 proto = *(pkt->data);
30 else
31 return -EIO;
33 /* FIXME: Right now only test for IP Version field */
34 switch (proto >> 4) {
35 case 4:
36 key = 0x0800; /* IPv4*/
37 break;
38 case 6:
39 key = 0x86DD; /* IPv6*/
40 break;
41 default:
42 /* Nothing detected ... */
43 return -ENOENT;
46 return key;
49 static void mpls_uc_full(struct pkt_buff *pkt)
51 int next;
52 uint32_t mpls_uc_data;
53 struct mpls_uchdr *mpls_uc;
54 uint8_t s = 0;
56 do {
57 mpls_uc = (struct mpls_uchdr *) pkt_pull(pkt, sizeof(*mpls_uc));
58 if (mpls_uc == NULL)
59 return;
61 mpls_uc_data = ntohl(mpls_uc->mpls_uc_hdr);
62 s = (mpls_uc_data >> 8) & 0x1;
64 tprintf(" [ MPLS ");
65 tprintf("Label (%u), ", mpls_uc_data >> 12);
66 tprintf("Exp (%u), ", (mpls_uc_data >> 9) & 0x7);
67 tprintf("S (%u), ", s);
68 tprintf("TTL (%u)", (mpls_uc_data & 0xFF));
69 tprintf(" ]\n");
70 } while (!s);
72 next = mpls_uc_next_proto(pkt);
73 if (next < 0)
74 return;
76 pkt_set_dissector(pkt, &eth_lay2, (uint16_t) next);
79 static void mpls_uc_less(struct pkt_buff *pkt)
81 int next;
82 uint32_t mpls_uc_data;
83 struct mpls_uchdr *mpls_uc;
84 uint8_t s = 0;
86 do {
87 mpls_uc = (struct mpls_uchdr *) pkt_pull(pkt, sizeof(*mpls_uc));
88 if (mpls_uc == NULL)
89 return;
91 mpls_uc_data = ntohl(mpls_uc->mpls_uc_hdr);
92 s = (mpls_uc_data >> 8) & 0x1;
94 tprintf(" MPLS/%u", mpls_uc_data >> 12);
95 } while (!s);
97 next = mpls_uc_next_proto(pkt);
98 if (next < 0)
99 return;
101 pkt_set_dissector(pkt, &eth_lay2, (uint16_t) next);
104 struct protocol mpls_uc_ops = {
105 .key = 0x8847,
106 .print_full = mpls_uc_full,
107 .print_less = mpls_uc_less,