#region subclasses //private class Header public class Header { // Everything is zeroed out by default. // As this is an explicit sequence, bytesex is irrelevant. //private byte[] packedheader = new byte[12]; public byte foo; public byte[] packedheader = new byte[12]; // Query/Response Bit // Get/set the MSB in the 3rd octet. public byte QR { // Note that the '&' operator is only defined for integers and booleans. // Fucked if I know what I'll do if this isn't endian-safe. get { //Console.WriteLine("raw packedheader[2]:{0}", packedheader[2]); return (byte)( packedheader[2] >> 7 ); } set { // It's unsigned, so I can't use a greater-than comparison. // As a result, I'm checking explicitly for 1 or 0. if ( (value != 1) && (value !=0) ) { throw new System.OverflowException(); } // The addition here is an ugly, simple way to bitmask things. // This is how I would do it in C, so I suppose "ugly" went without saying. packedheader[2] = (byte)(((value << 7) + (packedheader[2] & 127)) & 255); } } // Authoritative Answer Bit // Get/set the third bit from the right in the 3rd octet. public byte AA { // It's shifted left and *then* right in order to zero out all other bits. get { //Console.WriteLine("raw packedheader[2]:{0}", packedheader[2]); return (byte)((packedheader[2] & 4) >> 2);} /* 1. Clear Foo's lowest 3 bits. 2. Set the third bit to my value with (value << 2) 3. Add Foo's lowest two bits back in. */ set { if ( (value != 1) && (value != 0) ) { throw new System.OverflowException(); } packedheader[2] = (byte)((packedheader[2] & 248) + (value << 2) + (packedheader[2] & 3));} } // Truncated bit // Get/set the second bit from the right in the 3rd octet. public byte TC { get { //Console.WriteLine("raw packedheader[2]:{0}", packedheader[2]); return (byte)((packedheader[2] & 2) >> 1);} set { if ( (value != 1) && (value != 0) ) { throw new System.OverflowException(); } else { packedheader[2] = (byte)((byte)((int)packedheader[2] & (int)253) + (2 * value));}} } // I don't know what this is for, but if it's non-zero, ignore the packet. // Get the least significant half of the fourth byte. Set nothing. public byte RCode { get { return (byte)(packedheader[3] & 15); } set { throw new System.NotSupportedException(); } } }