March 11, 2020
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.
March 11, 2020
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;
    }
}