Add Ethernet MAC Control PAUSE frame proto header with
two fields - opcode & time.

By default Ethernet header is pushed on header init.

Signed-off-by: Vadim Kochan <vadi...@gmail.com>
---
 trafgen_l2.c    | 27 +++++++++++++++++++++++++++
 trafgen_l2.h    |  5 +++++
 trafgen_proto.h |  1 +
 3 files changed, 33 insertions(+)

diff --git a/trafgen_l2.c b/trafgen_l2.c
index 866559c..8d2d285 100644
--- a/trafgen_l2.c
+++ b/trafgen_l2.c
@@ -30,6 +30,8 @@ static uint16_t pid_to_eth(enum proto_id pid)
                return ETH_P_MPLS_UC;
        case PROTO_VLAN:
                return ETH_P_8021Q;
+       case PROTO_PAUSE:
+               return ETH_P_PAUSE;
        default:
                bug();
        }
@@ -54,6 +56,30 @@ static const struct proto_ops eth_proto_ops = {
        .set_next_proto = eth_set_next_proto,
 };
 
+static struct proto_field pause_fields[] = {
+       { .id = PAUSE_OPCODE,   .len = 2, .offset = 0 },
+       { .id = PAUSE_TIME,     .len = 2, .offset = 2 },
+};
+
+static void pause_header_init(struct proto_hdr *hdr)
+{
+       uint8_t eth_dst[6] = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x01 };
+
+       struct proto_hdr *lower;
+
+       lower = proto_lower_default_add(hdr, PROTO_ETH);
+       proto_field_set_default_bytes(lower, ETH_DST_ADDR, eth_dst);
+
+       proto_header_fields_add(hdr, pause_fields, array_size(pause_fields));
+       proto_field_set_default_be16(hdr, PAUSE_OPCODE, 0x1);
+}
+
+static struct proto_ops pause_proto_ops = {
+       .id             = PROTO_PAUSE,
+       .layer          = PROTO_L2,
+       .header_init    = pause_header_init,
+};
+
 static struct proto_field vlan_fields[] = {
        /* TPID overlaps with Ethernet header and points to ether type */
        { .id = VLAN_TPID, .len = 2, .offset = -2 },
@@ -167,6 +193,7 @@ static const struct proto_ops mpls_proto_ops = {
 void protos_l2_init(void)
 {
        proto_ops_register(&eth_proto_ops);
+       proto_ops_register(&pause_proto_ops);
        proto_ops_register(&vlan_proto_ops);
        proto_ops_register(&arp_proto_ops);
        proto_ops_register(&mpls_proto_ops);
diff --git a/trafgen_l2.h b/trafgen_l2.h
index 14f0e84..7c8ef7d 100644
--- a/trafgen_l2.h
+++ b/trafgen_l2.h
@@ -7,6 +7,11 @@ enum eth_field {
        ETH_TYPE,
 };
 
+enum pause_field {
+       PAUSE_OPCODE,
+       PAUSE_TIME,
+};
+
 enum arp_field {
        ARP_HTYPE,
        ARP_PTYPE,
diff --git a/trafgen_proto.h b/trafgen_proto.h
index a8b97eb..a1f6b66 100644
--- a/trafgen_proto.h
+++ b/trafgen_proto.h
@@ -8,6 +8,7 @@
 enum proto_id {
        PROTO_NONE = 0,
        PROTO_ETH,
+       PROTO_PAUSE,
        PROTO_VLAN,
        PROTO_ARP,
        PROTO_MPLS,
-- 
2.9.3

-- 
You received this message because you are subscribed to the Google Groups 
"netsniff-ng" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to netsniff-ng+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to