diff options
Diffstat (limited to 'zebra/zapi.go')
-rw-r--r-- | zebra/zapi.go | 90 |
1 files changed, 77 insertions, 13 deletions
diff --git a/zebra/zapi.go b/zebra/zapi.go index 9afdefae..e768eb0e 100644 --- a/zebra/zapi.go +++ b/zebra/zapi.go @@ -39,6 +39,61 @@ const ( INTERFACE_LINKDETECTION = 0x04 ) +type LINK_TYPE uint32 + +const ( + LINK_TYPE_UNKNOWN LINK_TYPE = iota + LINK_TYPE_ETHER + LINK_TYPE_EETHER + LINK_TYPE_AX25 + LINK_TYPE_PRONET + LINK_TYPE_IEEE802 + LINK_TYPE_ARCNET + LINK_TYPE_APPLETLK + LINK_TYPE_DLCI + LINK_TYPE_ATM + LINK_TYPE_METRICOM + LINK_TYPE_IEEE1394 + LINK_TYPE_EUI64 + LINK_TYPE_INFINIBAND + LINK_TYPE_SLIP + LINK_TYPE_CSLIP + LINK_TYPE_SLIP6 + LINK_TYPE_CSLIP6 + LINK_TYPE_RSRVD + LINK_TYPE_ADAPT + LINK_TYPE_ROSE + LINK_TYPE_X25 + LINK_TYPE_PPP + LINK_TYPE_CHDLC + LINK_TYPE_LAPB + LINK_TYPE_RAWHDLC + LINK_TYPE_IPIP + LINK_TYPE_IPIP6 + LINK_TYPE_FRAD + LINK_TYPE_SKIP + LINK_TYPE_LOOPBACK + LINK_TYPE_LOCALTLK + LINK_TYPE_FDDI + LINK_TYPE_SIT + LINK_TYPE_IPDDP + LINK_TYPE_IPGRE + LINK_TYPE_IP6GRE + LINK_TYPE_PIMREG + LINK_TYPE_HIPPI + LINK_TYPE_ECONET + LINK_TYPE_IRDA + LINK_TYPE_FCPP + LINK_TYPE_FCAL + LINK_TYPE_FCPL + LINK_TYPE_FCFABRIC + LINK_TYPE_IEEE802_TR + LINK_TYPE_IEEE80211 + LINK_TYPE_IEEE80211_RADIOTAP + LINK_TYPE_IEEE802154 + LINK_TYPE_IEEE802154_PHY +) + func HeaderSize(version uint8) uint16 { switch version { case 3: @@ -447,7 +502,7 @@ func (h *Header) DecodeFromBytes(data []byte) error { } type Body interface { - DecodeFromBytes([]byte) error + DecodeFromBytes([]byte, uint8) error Serialize() ([]byte, error) } @@ -455,7 +510,7 @@ type HelloBody struct { RedistDefault ROUTE_TYPE } -func (b *HelloBody) DecodeFromBytes(data []byte) error { +func (b *HelloBody) DecodeFromBytes(data []byte, version uint8) error { b.RedistDefault = ROUTE_TYPE(data[0]) return nil } @@ -468,7 +523,7 @@ type RedistributeBody struct { Redist ROUTE_TYPE } -func (b *RedistributeBody) DecodeFromBytes(data []byte) error { +func (b *RedistributeBody) DecodeFromBytes(data []byte, version uint8) error { b.Redist = ROUTE_TYPE(data[0]) return nil } @@ -486,10 +541,11 @@ type InterfaceUpdateBody struct { MTU uint32 MTU6 uint32 Bandwidth uint32 + Linktype LINK_TYPE HardwareAddr net.HardwareAddr } -func (b *InterfaceUpdateBody) DecodeFromBytes(data []byte) error { +func (b *InterfaceUpdateBody) DecodeFromBytes(data []byte, version uint8) error { if len(data) < INTERFACE_NAMSIZ+29 { return fmt.Errorf("lack of bytes. need %d but %d", INTERFACE_NAMSIZ+29, len(data)) } @@ -503,9 +559,17 @@ func (b *InterfaceUpdateBody) DecodeFromBytes(data []byte) error { b.MTU = binary.BigEndian.Uint32(data[17:21]) b.MTU6 = binary.BigEndian.Uint32(data[21:25]) b.Bandwidth = binary.BigEndian.Uint32(data[25:29]) - l := binary.BigEndian.Uint32(data[29:33]) + data = data[29:] + if version > 2 { + b.Linktype = LINK_TYPE(binary.BigEndian.Uint32(data[:4])) + data = data[4:] + } + l := binary.BigEndian.Uint32(data[:4]) if l > 0 { - b.HardwareAddr = data[33 : 33+l] + if len(data) < 4+int(l) { + return fmt.Errorf("lack of bytes. need %d but %d", 4+l, len(data)) + } + b.HardwareAddr = data[4 : 4+l] } return nil } @@ -515,7 +579,7 @@ func (b *InterfaceUpdateBody) Serialize() ([]byte, error) { } func (b *InterfaceUpdateBody) String() string { - s := fmt.Sprintf("name: %s, idx: %d, status: %s, flags: %s, metric: %d, mtu: %d, mtu6: %d, bandwidth: %d", b.Name, b.Index, b.Status, intfflag2string(b.Flags), b.Metric, b.MTU, b.MTU6, b.Bandwidth) + s := fmt.Sprintf("name: %s, idx: %d, status: %s, flags: %s, metric: %d, mtu: %d, mtu6: %d, bandwidth: %d, linktype: %s", b.Name, b.Index, b.Status, intfflag2string(b.Flags), b.Metric, b.MTU, b.MTU6, b.Bandwidth, b.Linktype) if len(b.HardwareAddr) > 0 { return s + fmt.Sprintf(", mac: %s", b.HardwareAddr) } @@ -529,7 +593,7 @@ type InterfaceAddressUpdateBody struct { Length uint8 } -func (b *InterfaceAddressUpdateBody) DecodeFromBytes(data []byte) error { +func (b *InterfaceAddressUpdateBody) DecodeFromBytes(data []byte, version uint8) error { b.Index = binary.BigEndian.Uint32(data[:4]) b.Flags = data[4] family := data[5] @@ -560,7 +624,7 @@ type RouterIDUpdateBody struct { Prefix net.IP } -func (b *RouterIDUpdateBody) DecodeFromBytes(data []byte) error { +func (b *RouterIDUpdateBody) DecodeFromBytes(data []byte, version uint8) error { family := data[0] var addrlen int8 switch family { @@ -652,7 +716,7 @@ func (b *IPRouteBody) Serialize() ([]byte, error) { return buf, nil } -func (b *IPRouteBody) DecodeFromBytes(data []byte) error { +func (b *IPRouteBody) DecodeFromBytes(data []byte, version uint8) error { isV4 := b.Api == IPV4_ROUTE_ADD || b.Api == IPV4_ROUTE_DELETE var addrLen uint8 = net.IPv4len @@ -778,7 +842,7 @@ func (b *NexthopLookupBody) Serialize() ([]byte, error) { return buf, nil } -func (b *NexthopLookupBody) DecodeFromBytes(data []byte) error { +func (b *NexthopLookupBody) DecodeFromBytes(data []byte, version uint8) error { isV4 := b.Api == IPV4_NEXTHOP_LOOKUP var addrLen uint8 = net.IPv4len @@ -874,7 +938,7 @@ func (b *ImportLookupBody) Serialize() ([]byte, error) { return buf, nil } -func (b *ImportLookupBody) DecodeFromBytes(data []byte) error { +func (b *ImportLookupBody) DecodeFromBytes(data []byte, version uint8) error { var addrLen uint8 = net.IPv4len @@ -987,7 +1051,7 @@ func ParseMessage(hdr *Header, data []byte) (*Message, error) { default: return nil, fmt.Errorf("Unknown zapi command: %d", m.Header.Command) } - err := m.Body.DecodeFromBytes(data) + err := m.Body.DecodeFromBytes(data, m.Header.Version) if err != nil { return nil, err } |