diff --git a/main.go b/main.go index 05b4006..fd5bd43 100644 --- a/main.go +++ b/main.go @@ -6,10 +6,12 @@ import ( "net" "github.com/crip/ripv2" + "github.com/crip/ripv2/routes" ) func main() { rip := ripv2.New() + routes := routes.New() addr := net.UDPAddr{ Port: 520, IP: net.ParseIP("224.0.0.9"), @@ -36,14 +38,7 @@ func main() { if err := rip.MParse(&buff, n); err != nil { log.Fatalln(err) } - - /* Just testing the parsing output */ - for i := 0; i < 24; i++ { - if rip.RIP[i].Metric == 0 { - break - } - fmt.Printf("%d\t%s\t%s\t%s\t%d\n", rip.RIP[i].AFI, rip.RIP[i].Addr.String(), rip.RIP[i].Subnet.String(), rip.RIP[i].Nexthop.String(), rip.RIP[i].Metric) - } - fmt.Println("") + routes.ParseRoutes(*UDPAddr, &rip.RIP) + fmt.Println(routes) } } diff --git a/ripv2/ripv2.go b/ripv2/ripv2.go index e4b2977..5e12052 100644 --- a/ripv2/ripv2.go +++ b/ripv2/ripv2.go @@ -21,16 +21,15 @@ func (m *Message) MParse(b *[]byte, n int) error { return errors.New("rip table exceeds limit") } - data := (*b) - m.Command = Command(data[0]) - m.Version = Version(data[1]) + 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 := data[indexA:indexB] + ripentry := (*b)[indexA:indexB] switch m.Command { case REQUEST: return nil @@ -38,13 +37,13 @@ func (m *Message) MParse(b *[]byte, n int) error { 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 = net.IPv4(ripentry[4], ripentry[5], ripentry[6], ripentry[7]) - m.RIP[i].Subnet = net.IPv4Mask(ripentry[8], ripentry[9], ripentry[10], ripentry[11]) - m.RIP[i].Nexthop = net.IPv4(ripentry[12], ripentry[13], ripentry[14], ripentry[15]) + 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 = data[indexA:indexB] + ripentry = (*b)[indexA:indexB] } default: return errors.New("unknown command type") diff --git a/ripv2/routes/routes.go b/ripv2/routes/routes.go new file mode 100644 index 0000000..35894be --- /dev/null +++ b/ripv2/routes/routes.go @@ -0,0 +1,54 @@ +package routes + +import ( + "net" + "time" + + "github.com/crip/ripv2" +) + +type Routes []Route + +type Route struct { + Addr net.IP + Subnet net.IPMask + Nexthop net.IP + Metric uint32 + TTL time.Time +} + +func New() Routes { + var routes Routes + return routes +} + +func (r *Routes) append(route Route) { + *r = append(*r, route) +} + +func (r *Routes) ParseRoutes(addr net.UDPAddr, rip *[25]ripv2.RIP) { + var route Route + for _, rip := range *rip { + /* if not af_inet */ + if rip.AFI != 2 { + continue + } + + if rip.Addr == 0 || rip.Subnet == 0 { + continue + } + + route = Route{} + + route.Addr = net.IPv4(byte(rip.Addr>>24), byte(rip.Addr>>16), byte(rip.Addr>>8), byte(rip.Addr)) + route.Subnet = net.IPv4Mask(byte(rip.Subnet>>24), byte(rip.Subnet>>16), byte(rip.Subnet>>8), byte(rip.Subnet)) + if rip.Nexthop == 0 { + route.Nexthop = addr.IP + } else { + route.Nexthop = net.IPv4(byte(rip.Nexthop>>24), byte(rip.Nexthop>>16), byte(rip.Nexthop>>8), byte(rip.Nexthop)) + } + route.Metric = rip.Metric + route.TTL = time.Now() + r.append(route) + } +} diff --git a/ripv2/types.go b/ripv2/types.go index fbed13d..f01dc77 100644 --- a/ripv2/types.go +++ b/ripv2/types.go @@ -1,7 +1,5 @@ package ripv2 -import "net" - type Command uint8 type Version uint8 @@ -26,8 +24,8 @@ type Message struct { type RIP struct { AFI uint16 RouteTag uint16 - Addr net.IP - Subnet net.IPMask - Nexthop net.IP + Addr uint32 + Subnet uint32 + Nexthop uint32 Metric uint32 }