include IPv4 Option padding and type packing/unpacking
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
`fmt`
|
||||
`log`
|
||||
"fmt"
|
||||
"log"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
`fmt`
|
||||
`log`
|
||||
"fmt"
|
||||
"log"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
|
||||
73
examples/v4optspad.go
Normal file
73
examples/v4optspad.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
const (
|
||||
padVal uint8 = 0x00 // Padded with NUL/null-bytes
|
||||
alignLen int = 4 // 4-Byte alignment
|
||||
)
|
||||
|
||||
var (
|
||||
// See the examples/v4opts.go for how these bytes are constructed.
|
||||
opts []byte = []byte{
|
||||
// This is an example.
|
||||
// Option 1
|
||||
0x94, // Type 148, RTRALT (Router Alert) (RFC 2113)
|
||||
0x04, // Length (4 bytes)
|
||||
0x00, 0x00, // "Router shall examine packet"
|
||||
// EOOL
|
||||
0x00,
|
||||
// Padding will go here.
|
||||
}
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
var optLen int
|
||||
var padLen int
|
||||
var pad []byte
|
||||
|
||||
optLen = len(opts)
|
||||
|
||||
fmt.Println("Before padding:")
|
||||
// Prints:
|
||||
/*
|
||||
0x9404000000
|
||||
(Length: 5)
|
||||
*/
|
||||
fmt.Printf("%#02x\n(Length: %d)\n\n", opts, optLen)
|
||||
|
||||
/*
|
||||
The remainder of the current length divided by
|
||||
alignLen (4) (modulo) is subtracted from the alignLen
|
||||
to determine how much must be added to reach the next
|
||||
"boundary". It's then modulo'd *again* to rule out
|
||||
currently being on an alignment bounary.
|
||||
*/
|
||||
padLen = (alignLen - (optLen % alignLen)) % alignLen
|
||||
// Prints:
|
||||
/*
|
||||
Pad length needed: 3
|
||||
*/
|
||||
fmt.Printf("Pad length needed:\t%d\n\n", padLen)
|
||||
pad = bytes.Repeat([]byte{padVal}, padLen)
|
||||
|
||||
opts = append(opts, pad...)
|
||||
|
||||
// Alternatively, this can be implemented with a loop, though it's likely less efficient:
|
||||
/*
|
||||
for len(opts) % alignLen != 0 {}
|
||||
opts = append(opts, padVal)
|
||||
}
|
||||
*/
|
||||
|
||||
// Prints:
|
||||
/*
|
||||
Padded:
|
||||
0x9404000000000000
|
||||
*/
|
||||
fmt.Printf("Padded:\n%#x\n", opts)
|
||||
}
|
||||
111
examples/v4optstype.go
Normal file
111
examples/v4optstype.go
Normal file
@@ -0,0 +1,111 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const (
|
||||
ClassControl uint8 = iota
|
||||
ClassReserved
|
||||
ClassDebug
|
||||
ClassReserved2
|
||||
)
|
||||
|
||||
var (
|
||||
classStr map[uint8]string = map[uint8]string{
|
||||
ClassControl: "Control",
|
||||
ClassReserved: "Reserved (1)",
|
||||
ClassDebug: "Debugging/Measurement",
|
||||
ClassReserved2: "Reserved (2)",
|
||||
}
|
||||
)
|
||||
|
||||
const (
|
||||
/// This is the same type from examples/v4optspad.go.
|
||||
ip4OptTypBits string = "10010100" // [1001 0100], or 148 (0x94)
|
||||
)
|
||||
|
||||
var (
|
||||
v4TypCpyOffset uint8 = 0x80 // 128
|
||||
v4TypCpyMask uint8 = 0x01 // Mask to 1 bit
|
||||
v4TypCpyPos uint8 = 8 - v4TypCpyMask // 7 or 0x07 (8 (bits) - mask = Shifted to 7th bit)
|
||||
|
||||
v4TypClsOffset uint8 = 0x60 // 96
|
||||
v4TypClsMask uint8 = 0x05 // mask to 5 bits
|
||||
v4TypClsPos uint8 = 8 - v4TypClsMask
|
||||
|
||||
v4TypNumOffset uint8 = 0x1f // 31
|
||||
)
|
||||
|
||||
func ToV4OptTyp(copied, class, num uint8) (typ uint8) {
|
||||
|
||||
typ = ((copied & v4TypCpyMask) << v4TypCpyPos) | ((class & v4TypClsMask) << v4TypClsPos) | (num & v4TypNumOffset)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func FromV4OptTyp(typ uint8) (copied, class, num uint8) {
|
||||
|
||||
copied = (typ & v4TypCpyOffset) >> v4TypCpyPos
|
||||
class = (typ & v4TypClsOffset) >> v4TypClsPos
|
||||
num = (typ & v4TypNumOffset)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
var err error
|
||||
var u64 uint64
|
||||
var typ uint8
|
||||
var cpd uint8
|
||||
var cls uint8
|
||||
var num uint8
|
||||
|
||||
// Given a type of ip4OptTypBits (see const at top)...
|
||||
if u64, err = strconv.ParseUint(ip4OptTypBits, 2, 8); err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
typ = uint8(u64)
|
||||
// Prints:
|
||||
/*
|
||||
Type is: 148 (0x0094)
|
||||
*/
|
||||
fmt.Printf("Type is:\t%d (%#04x)\n", typ, typ)
|
||||
|
||||
cpd, cls, num = FromV4OptTyp(typ)
|
||||
// Prints:
|
||||
/*
|
||||
Copied: 1 (0x0001)
|
||||
Class: 0 (0x0000)
|
||||
Number: 20 (0x0014)
|
||||
*/
|
||||
fmt.Printf(
|
||||
"Copied:\t\t%d %#04x)\n"+
|
||||
"Class:\t\t%d (%#04x)\n"+
|
||||
"Number:\t\t%d (%#04x)\n",
|
||||
cpd, cpd,
|
||||
cls, cls,
|
||||
num, num,
|
||||
)
|
||||
|
||||
typ = ToV4OptTyp(cpd, cls, num)
|
||||
// Prints:
|
||||
/*
|
||||
Confirmed Type: 148 (0x94)
|
||||
*/
|
||||
fmt.Printf("Confirmed Type:\t%d (%#02x)\n\n", typ, typ)
|
||||
|
||||
fmt.Println("Class Name:")
|
||||
// Prints:
|
||||
/*
|
||||
Control
|
||||
*/
|
||||
for c, cNm := range classStr {
|
||||
if c == cls {
|
||||
fmt.Println(cNm)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
`fmt`
|
||||
`log`
|
||||
"fmt"
|
||||
"log"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
`fmt`
|
||||
`log`
|
||||
"fmt"
|
||||
"log"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user