March 11, 2020 std.bitmanip help - how to combine bitfields and read | ||||
---|---|---|---|---|
| ||||
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 Re: std.bitmanip help - how to combine bitfields and read | ||||
---|---|---|---|---|
| ||||
Posted in reply to kookman | 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; } } |
Copyright © 1999-2021 by the D Language Foundation