--- Begin Message ---
On 05/05/2020 21:44, Gert Doering wrote:
> Hi,
> 
> On Tue, May 05, 2020 at 08:47:04PM +0200, Francois-Xavier Le Bail wrote:
>>> So, given that the first 16 bits are "4 bit always 0, and 12 bits
>>> reserved-must-be-set-to-0", using these as heuristics for "if two 0-bytes
>>> are following the MPLS headers, it's a control word, so we skip 4 bytes
>>> and the rest is a regular Ethernet packet" should work.
>>
>> We should print "PW Ethernet Control Word" and the "Sequence Number", 2 last 
>> 2 octets of the 4.
>> Like:
>> PW Ethernet Control Word, Sequence Number xxx
> 
> I think we should only print this if "-v" is given.  Most of the time, 
> both control word and sequence number are of little interest.
> 
> I really like tcpdump's very compact "only the most relevant info" output
> format (by default).

Proposed patch attached.

With new '-T mplsethnocw' option to force 'Ethernet without Control Word' 
decode.
(from Francesco Fondelli comment)
-- 
Francois-Xavier
diff --git a/netdissect.h b/netdissect.h
index 65a0d987..cd76d654 100644
--- a/netdissect.h
+++ b/netdissect.h
@@ -294,6 +294,7 @@ extern void nd_pop_all_packet_info(netdissect_options *);
 #define PT_PTP         18      /* PTP */
 #define PT_SOMEIP      19      /* Autosar SOME/IP Protocol */
 #define PT_DOMAIN      20      /* Domain Name System (DNS) */
+#define PT_MPLSETHNOCW 21      /* MPLS PW Ethernet without Control Word */
 
 #ifndef min
 #define min(a,b) ((a)>(b)?(b):(a))
diff --git a/print-mpls.c b/print-mpls.c
index 62b79957..0c0ab974 100644
--- a/print-mpls.c
+++ b/print-mpls.c
@@ -50,7 +50,8 @@ enum mpls_packet_type {
        PT_UNKNOWN,
        PT_IPV4,
        PT_IPV6,
-       PT_OSI
+       PT_OSI,
+       PT_ETHER
 };
 
 /*
@@ -133,52 +134,68 @@ mpls_print(netdissect_options *ndo, const u_char *bp, 
u_int length)
                        /* nothing to print */
                        return;
                }
-               switch(GET_U_1(p)) {
-
-               case 0x45:
-               case 0x46:
-               case 0x47:
-               case 0x48:
-               case 0x49:
-               case 0x4a:
-               case 0x4b:
-               case 0x4c:
-               case 0x4d:
-               case 0x4e:
-               case 0x4f:
-                       pt = PT_IPV4;
-                       break;
-
-               case 0x60:
-               case 0x61:
-               case 0x62:
-               case 0x63:
-               case 0x64:
-               case 0x65:
-               case 0x66:
-               case 0x67:
-               case 0x68:
-               case 0x69:
-               case 0x6a:
-               case 0x6b:
-               case 0x6c:
-               case 0x6d:
-               case 0x6e:
-               case 0x6f:
-                       pt = PT_IPV6;
-                       break;
-
-               case 0x81:
-               case 0x82:
-               case 0x83:
-                       pt = PT_OSI;
-                       break;
-
-               default:
-                       /* ok bail out - we did not figure out what it is*/
-                       break;
+               if (ndo->ndo_packettype == PT_MPLSETHNOCW)
+                       pt = PT_ETHER;
+               else
+                       switch(GET_U_1(p)) {
+
+                       case 0x45:
+                       case 0x46:
+                       case 0x47:
+                       case 0x48:
+                       case 0x49:
+                       case 0x4a:
+                       case 0x4b:
+                       case 0x4c:
+                       case 0x4d:
+                       case 0x4e:
+                       case 0x4f:
+                               pt = PT_IPV4;
+                               break;
+
+                       case 0x60:
+                       case 0x61:
+                       case 0x62:
+                       case 0x63:
+                       case 0x64:
+                       case 0x65:
+                       case 0x66:
+                       case 0x67:
+                       case 0x68:
+                       case 0x69:
+                       case 0x6a:
+                       case 0x6b:
+                       case 0x6c:
+                       case 0x6d:
+                       case 0x6e:
+                       case 0x6f:
+                               pt = PT_IPV6;
+                               break;
+
+                       case 0x81:
+                       case 0x82:
+                       case 0x83:
+                               pt = PT_OSI;
+                               break;
+
+                       case 0x00:      /* RFC 4448 PW Ethernet Control Word */
+                               if (ndo->ndo_vflag) {
+                                       ND_PRINT("\n\tPW Ethernet Control 
Word");
+                                       p += 2;
+                                       ND_PRINT(", Sequence Number %u", 
GET_BE_U_2(p));
+                                       p += 2;
+                               } else
+                                       ND_PRINT(" PWETHCW");
+                                       p += 4;
+                               length -= 4;
+                               pt = PT_ETHER;
+                               break;
+
+                       default:
+                               /* ok bail out - we did not figure out what it 
is*/
+                               break;
+                       }
                }
-       }
 
        /*
         * Print the payload.
@@ -203,6 +220,10 @@ mpls_print(netdissect_options *ndo, const u_char *bp, 
u_int length)
                isoclns_print(ndo, p, length);
                break;
 
+       case PT_ETHER:
+               ether_print(ndo, p, length, ND_BYTES_AVAILABLE_AFTER(bp), NULL, 
NULL);
+               break;
+
        default:
                break;
        }
diff --git a/tcpdump.c b/tcpdump.c
index 376d9a20..abefb50c 100644
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -1798,6 +1798,8 @@ main(int argc, char **argv)
                                ndo->ndo_packettype = PT_SOMEIP;
                        else if (ascii_strcasecmp(optarg, "domain") == 0)
                                ndo->ndo_packettype = PT_DOMAIN;
+                       else if (ascii_strcasecmp(optarg, "mplsethnocw") == 0)
+                               ndo->ndo_packettype = PT_MPLSETHNOCW;
                        else
                                error("unknown packet type `%s'", optarg);
                        break;

--- End Message ---
_______________________________________________
tcpdump-workers mailing list
tcpdump-workers@lists.tcpdump.org
https://lists.sandelman.ca/mailman/listinfo/tcpdump-workers

Reply via email to