crip/ripv2/ripv2.go
Jim Colderwood 83bbd52cee Route slice
2024-04-10 16:33:33 +01:00

87 lines
1.9 KiB
Go

package ripv2
import (
"bytes"
"encoding/binary"
"errors"
"fmt"
"net"
)
func New() Message {
return Message{}
}
func (m *Message) MParse(b *[]byte, n int) error {
if n == 0 {
return errors.New("can't parse empty data")
}
if (n-4)/20 > 25 {
return errors.New("rip table exceeds limit")
}
m.Command = Command((*b)[0])
m.Version = Version((*b)[1])
if m.Version > RIPv2 {
return errors.New("unknown version")
}
var indexA, indexB = 4, 25
ripentry := (*b)[indexA:indexB]
switch m.Command {
case REQUEST:
return nil
case RESPONSE:
for i := 0; i < (n-4)/20; i++ {
m.RIP[i].AFI = binary.BigEndian.Uint16(ripentry[0:2])
m.RIP[i].RouteTag = binary.BigEndian.Uint16(ripentry[2:4])
m.RIP[i].Addr = binary.BigEndian.Uint32(ripentry[4:8]) //net.IPv4(ripentry[4], ripentry[5], ripentry[6], ripentry[7])
m.RIP[i].Subnet = binary.BigEndian.Uint32(ripentry[8:12]) //net.IPv4Mask(ripentry[8], ripentry[9], ripentry[10], ripentry[11])
m.RIP[i].Nexthop = binary.BigEndian.Uint32(ripentry[12:16]) //net.IPv4(ripentry[12], ripentry[13], ripentry[14], ripentry[15])
m.RIP[i].Metric = binary.BigEndian.Uint32(ripentry[16:20])
indexA += 20
indexB += 20
ripentry = (*b)[indexA:indexB]
}
default:
return errors.New("unknown command type")
}
return nil
}
/* Basic parsing */
func (m *Message) Parse(b *[]byte) error {
if len(*b) == 0 {
return fmt.Errorf("can't parse empty data")
}
bytes := bytes.NewBuffer(*b)
if err := binary.Read(bytes, binary.BigEndian, m); err != nil {
return err
}
if m.Version != 2 {
return fmt.Errorf("version: %d", m.Version)
}
return nil
}
func (m *Message) Request(conn *net.UDPConn) ([]byte, error) {
var buffer = make([]byte, 24)
m.Command = REQUEST
m.Version = 2
m.RIP[0].Metric = 16
buff := bytes.NewBuffer(buffer)
buff.Reset()
if err := binary.Write(buff, binary.BigEndian, m); err != nil {
return []byte{}, err
}
return buffer, nil
}