On Wednesday, 11 March 2020 at 05:25:43 UTC, kookman wrote:
I am using libpcap to read from stored pcap files, and want to use std.bitmanip.bitfields to read TCP flags from the file, using a struct like:

struct TcpHeader {
    align(1):
    ushort srcPort;
    ushort dstPort;
    uint seqNo;
    uint ackNo;
    mixin(bitfields!(
        bool, "flagFin", 1,
        bool, "flagSyn", 1,
        bool, "flagRst", 1,
        bool, "flagPsh", 1,
        bool, "flagAck", 1,
        bool, "flagUrg", 1,
        bool, "flagEce", 1,
        bool, "flagCwr", 1,
        bool, "flagNs",  1,
        ubyte, "reserved", 3,
ubyte, "dataOffsetWords", 4 // in 32bit words, min=5, max=15
    ));
    ushort windowSize;
    ushort checksum;
    ushort urgentPtr;

    this(inout ubyte[] bytes)
    {
        srcPort = bytes.read!ushort();
        dstPort = bytes.read!ushort();
        seqNo = bytes.read!uint();
        ackNo = bytes.read!uint();
        // now what? how to read bitfields??
    }

const uint dataOffset() // convenience method to get offset in bytes
    {
        return dataOffsetWords * 4;
    }
}

How can I get at the private field behind the bitfields to read into it. I'm using std.bitmanip.read because I need the network order (bigendian) conversion for this data.

Actually, doing it a "smarter" way worked:

struct TcpHeader {
    align(1):
    ushort srcPort;
    ushort dstPort;
    uint seqNo;
    uint ackNo;
    mixin(bitfields!(
        bool, "flagFin", 1,
        bool, "flagSyn", 1,
        bool, "flagRst", 1,
        bool, "flagPsh", 1,
        bool, "flagAck", 1,
        bool, "flagUrg", 1,
        bool, "flagEce", 1,
        bool, "flagCwr", 1,
        bool, "flagNs",  1,
        ubyte, "reserved", 3,
ubyte, "dataOffsetWords", 4 // in 32bit words, min=5, max=15
    ));
    ushort windowSize;
    ushort checksum;
    ushort urgentPtr;

    this(inout(ubyte)[] bytes)
    {
        import std.traits: FieldNameTuple;
        static foreach (f; FieldNameTuple!TcpHeader) {
            pragma(msg, f);
__traits(getMember, this, f) = bytes.read!(typeof(__traits(getMember, this, f)));
        }
    }

const uint dataOffset() // convenience method to get offset in bytes
    {
        return dataOffsetWords * 4;
    }
}

Reply via email to