diff options
author | IWASE Yusuke <iwase.yusuke0@gmail.com> | 2017-11-20 11:06:12 +0900 |
---|---|---|
committer | IWASE Yusuke <iwase.yusuke0@gmail.com> | 2017-11-24 12:55:34 +0900 |
commit | 35c79d833feafb7fa12afa90e984e6f1f474675e (patch) | |
tree | bd73abccfb9235e83d2aa7738ab324a78e1b2d9f /packet | |
parent | 8e98018c75db0d5cadb9f12d4e8f2cf24ad59e08 (diff) |
packet/bgp: Refactor construction of FlowSpec rules string
This patch introduces String() functions for the flags and reserved
values related to the FlowSpec rules.
Also removes the unused types and functions.
Signed-off-by: IWASE Yusuke <iwase.yusuke0@gmail.com>
Diffstat (limited to 'packet')
-rw-r--r-- | packet/bgp/bgp.go | 133 | ||||
-rw-r--r-- | packet/bgp/constant.go | 227 |
2 files changed, 140 insertions, 220 deletions
diff --git a/packet/bgp/bgp.go b/packet/bgp/bgp.go index bf90cfc6..57afae9a 100644 --- a/packet/bgp/bgp.go +++ b/packet/bgp/bgp.go @@ -3451,7 +3451,7 @@ func (p *flowSpecPrefix) Type() BGPFlowSpecType { } func (p *flowSpecPrefix) String() string { - return fmt.Sprintf("[%s:%s]", p.Type(), p.Prefix.String()) + return fmt.Sprintf("[%s: %s]", p.Type(), p.Prefix.String()) } func (p *flowSpecPrefix) MarshalJSON() ([]byte, error) { @@ -3500,7 +3500,7 @@ func (p *flowSpecPrefix6) Type() BGPFlowSpecType { } func (p *flowSpecPrefix6) String() string { - return fmt.Sprintf("[%s:%s/%d]", p.Type(), p.Prefix.String(), p.Offset) + return fmt.Sprintf("[%s: %s/%d]", p.Type(), p.Prefix.String(), p.Offset) } func (p *flowSpecPrefix6) MarshalJSON() ([]byte, error) { @@ -3578,7 +3578,7 @@ func (p *flowSpecMac) Type() BGPFlowSpecType { } func (p *flowSpecMac) String() string { - return fmt.Sprintf("[%s:%s]", p.Type(), p.Mac.String()) + return fmt.Sprintf("[%s: %s]", p.Type(), p.Mac.String()) } func (p *flowSpecMac) MarshalJSON() ([]byte, error) { @@ -3715,7 +3715,7 @@ func (p *FlowSpecComponent) Serialize(options ...*MarshallingOption) ([]byte, er func (p *FlowSpecComponent) Len(options ...*MarshallingOption) int { l := 1 for _, item := range p.Items { - l += (item.Len() + 1) + l += item.Len() + 1 } return l } @@ -3725,113 +3725,42 @@ func (p *FlowSpecComponent) Type() BGPFlowSpecType { } func formatRaw(op int, value int) string { - return fmt.Sprintf("op: %b, value: %d", op, value) -} - -func formatNumericOp(op int) string { - var opstr string - if op&0x40 > 0 { - opstr = "&" - } else { - opstr = " " - } - if op&0x2 > 0 { - opstr += ">" - } - if op&0x4 > 0 { - opstr += "<" - } - if op&0x1 > 0 { - opstr += "=" - } - return opstr -} - -func formatNumericOpFrontQty(op int) string { - gtlteqOnly := op & 0x07 - return fmt.Sprintf("%s", DECNumOpNameMap[DECNumOp(gtlteqOnly)]) -} - -func formatNumericOpBackLogic(op int) string { - andOrOnly := op & 0x40 // let's ignore the END bit to avoid having an E at the end of the string - return fmt.Sprintf("%s", DECLogicOpNameMap[DECLogicOp(andOrOnly)]) + return fmt.Sprintf("op:%b,value:%d", op, value) } func formatNumeric(op int, value int) string { - gtlteqOnly := op & 0x07 - if DECNumOp(gtlteqOnly) == DECNumOpValueMap[DECNumOpNameMap[DEC_NUM_OP_FALSE]] || DECNumOp(gtlteqOnly) == DECNumOpValueMap[DECNumOpNameMap[DEC_NUM_OP_TRUE]] { - return fmt.Sprintf("%s%s", formatNumericOpFrontQty(op), formatNumericOpBackLogic(op)) - } else { - return fmt.Sprintf("%s%s%d", formatNumericOpBackLogic(op), formatNumericOpFrontQty(op), value) + cmpFlag := DECNumOp(op & 0x7) // lower 3 bits + if cmpFlag == DEC_NUM_OP_TRUE || cmpFlag == DEC_NUM_OP_FALSE { + // Omit value field + return DECNumOp(op).String() } + return fmt.Sprint(DECNumOp(op).String(), strconv.Itoa(value)) } func formatProto(op int, value int) string { - return fmt.Sprintf("%s%s%s", formatNumericOpFrontQty(op), Protocol(value).String(), formatNumericOpBackLogic(op)) + cmpFlag := DECNumOp(op & 0x7) // lower 3 bits + if cmpFlag == DEC_NUM_OP_TRUE || cmpFlag == DEC_NUM_OP_FALSE { + // Omit value field + return DECNumOp(op).String() + } + return fmt.Sprint(DECNumOp(op).String(), Protocol(value).String()) } func formatTCPFlag(op int, value int) string { - var retString string - if op&BITMASK_FLAG_OP_NOT > 0 { - retString = fmt.Sprintf("%s%s", retString, BitmaskFlagOpNameMap[BITMASK_FLAG_OP_NOT]) - } - if op&BITMASK_FLAG_OP_MATCH > 0 { - retString = fmt.Sprintf("%s%s", retString, BitmaskFlagOpNameMap[BITMASK_FLAG_OP_MATCH]) - } - - // Prepare a sorted list of flags because map iterations does not happen - // in a consistent order in Golang. - vs := make([]int, 0) - for _, v := range TCPFlagValueMap { - vs = append(vs, int(v)) - } - sort.Ints(vs) - for _, v := range vs { - if value&v > 0 { - retString = fmt.Sprintf("%s%s", retString, TCPFlagNameMap[TCPFlag(v)]) - } - } - - if op&BITMASK_FLAG_OP_AND > 0 { - retString = fmt.Sprintf("%s%s", BitmaskFlagOpNameMap[BITMASK_FLAG_OP_AND], retString) - } else { // default is or - retString = fmt.Sprintf("%s%s", BitmaskFlagOpNameMap[BITMASK_FLAG_OP_OR], retString) - } - return retString + return fmt.Sprint(BitmaskFlagOp(op).String(), TCPFlag(value).String()) } func formatFragment(op int, value int) string { - var retString string - if op&BITMASK_FLAG_OP_NOT > 0 { - retString = fmt.Sprintf("%s%s", retString, BitmaskFlagOpNameMap[BITMASK_FLAG_OP_NOT]) - } - if op&BITMASK_FLAG_OP_MATCH > 0 { - retString = fmt.Sprintf("%s%s", retString, BitmaskFlagOpNameMap[BITMASK_FLAG_OP_MATCH]) - } - - // Prepare a sorted list of flags because map iterations does not happen - // in a consistent order in Golang. - vs := make([]int, 0) - for _, v := range FragmentFlagValueMap { - vs = append(vs, int(v)) - } - sort.Ints(vs) - for _, v := range vs { - if value&v > 0 { - retString = fmt.Sprintf("%s%s", retString, FragmentFlagNameMap[FragmentFlag(v)]) - } - } - - if op&BITMASK_FLAG_OP_AND > 0 { - retString = fmt.Sprintf("%s%s", BitmaskFlagOpNameMap[BITMASK_FLAG_OP_AND], retString) - } else { // default is or - retString = fmt.Sprintf("%s%s", BitmaskFlagOpNameMap[BITMASK_FLAG_OP_OR], retString) - } - return retString + return fmt.Sprint(BitmaskFlagOp(op).String(), FragmentFlag(value).String()) } func formatEtherType(op int, value int) string { - return fmt.Sprintf("%s%s", formatNumericOp(op), EthernetType(value).String()) + cmpFlag := DECNumOp(op & 0x7) // lower 3 bits + if cmpFlag == DEC_NUM_OP_TRUE || cmpFlag == DEC_NUM_OP_FALSE { + // Omit value field + return DECNumOp(op).String() + } + return fmt.Sprint(DECNumOp(op).String(), EthernetType(value).String()) } var flowSpecFormatMap = map[BGPFlowSpecType]func(op int, value int) string{ @@ -3860,14 +3789,18 @@ var flowSpecFormatMap = map[BGPFlowSpecType]func(op int, value int) string{ func (p *FlowSpecComponent) String() string { f := flowSpecFormatMap[FLOW_SPEC_TYPE_UNKNOWN] - if _, ok := flowSpecFormatMap[p.Type()]; ok { - f = flowSpecFormatMap[p.Type()] + if _, ok := flowSpecFormatMap[p.typ]; ok { + f = flowSpecFormatMap[p.typ] } - buf := bytes.NewBuffer(make([]byte, 0, 32)) + + items := make([]string, 0, len(p.Items)) for _, i := range p.Items { - buf.WriteString(f(i.Op, i.Value)) + items = append(items, f(i.Op, i.Value)) } - return fmt.Sprintf("[%s:%s]", p.typ, buf.String()) + // Removes leading and tailing spaces + value := strings.TrimSpace(strings.Join(items, "")) + + return fmt.Sprintf("[%s: %s]", p.typ, value) } func (p *FlowSpecComponent) MarshalJSON() ([]byte, error) { diff --git a/packet/bgp/constant.go b/packet/bgp/constant.go index 0741d8e8..f743e331 100644 --- a/packet/bgp/constant.go +++ b/packet/bgp/constant.go @@ -70,21 +70,6 @@ var ProtocolNameMap = map[Protocol]string{ SCTP: "sctp", } -var ProtocolValueMap = map[string]Protocol{ - ProtocolNameMap[ICMP]: ICMP, - ProtocolNameMap[IGMP]: IGMP, - ProtocolNameMap[TCP]: TCP, - ProtocolNameMap[EGP]: EGP, - ProtocolNameMap[IGP]: IGP, - ProtocolNameMap[UDP]: UDP, - ProtocolNameMap[RSVP]: RSVP, - ProtocolNameMap[GRE]: GRE, - ProtocolNameMap[OSPF]: OSPF, - ProtocolNameMap[IPIP]: IPIP, - ProtocolNameMap[PIM]: PIM, - ProtocolNameMap[SCTP]: SCTP, -} - func (p Protocol) String() string { name, ok := ProtocolNameMap[p] if !ok { @@ -96,14 +81,15 @@ func (p Protocol) String() string { type TCPFlag int const ( - TCP_FLAG_FIN = 0x01 - TCP_FLAG_SYN = 0x02 - TCP_FLAG_RST = 0x04 - TCP_FLAG_PUSH = 0x08 - TCP_FLAG_ACK = 0x10 - TCP_FLAG_URGENT = 0x20 - TCP_FLAG_ECE = 0x40 - TCP_FLAG_CWR = 0x80 + _ TCPFlag = iota + TCP_FLAG_FIN = 0x01 + TCP_FLAG_SYN = 0x02 + TCP_FLAG_RST = 0x04 + TCP_FLAG_PUSH = 0x08 + TCP_FLAG_ACK = 0x10 + TCP_FLAG_URGENT = 0x20 + TCP_FLAG_ECE = 0x40 + TCP_FLAG_CWR = 0x80 ) var TCPFlagNameMap = map[TCPFlag]string{ @@ -117,25 +103,38 @@ var TCPFlagNameMap = map[TCPFlag]string{ TCP_FLAG_ECE: "E", } -var TCPFlagValueMap = map[string]TCPFlag{ - TCPFlagNameMap[TCP_FLAG_FIN]: TCP_FLAG_FIN, - TCPFlagNameMap[TCP_FLAG_SYN]: TCP_FLAG_SYN, - TCPFlagNameMap[TCP_FLAG_RST]: TCP_FLAG_RST, - TCPFlagNameMap[TCP_FLAG_PUSH]: TCP_FLAG_PUSH, - TCPFlagNameMap[TCP_FLAG_ACK]: TCP_FLAG_ACK, - TCPFlagNameMap[TCP_FLAG_URGENT]: TCP_FLAG_URGENT, - TCPFlagNameMap[TCP_FLAG_CWR]: TCP_FLAG_CWR, - TCPFlagNameMap[TCP_FLAG_ECE]: TCP_FLAG_ECE, +// Prepares a sorted list of flags because map iterations does not happen +// in a consistent order in Golang. +var TCPSortedFlags = []TCPFlag{ + TCP_FLAG_FIN, + TCP_FLAG_SYN, + TCP_FLAG_RST, + TCP_FLAG_PUSH, + TCP_FLAG_ACK, + TCP_FLAG_URGENT, + TCP_FLAG_ECE, + TCP_FLAG_CWR, +} + +func (f TCPFlag) String() string { + flags := make([]string, 0, len(TCPSortedFlags)) + for _, v := range TCPSortedFlags { + if f&v > 0 { + flags = append(flags, TCPFlagNameMap[v]) + } + } + return strings.Join(flags, "") } type BitmaskFlagOp int const ( - BITMASK_FLAG_OP_OR = 0x00 - BITMASK_FLAG_OP_AND = 0x40 - BITMASK_FLAG_OP_END = 0x80 - BITMASK_FLAG_OP_NOT = 0x02 - BITMASK_FLAG_OP_MATCH = 0x01 + BITMASK_FLAG_OP_OR BitmaskFlagOp = iota + BITMASK_FLAG_OP_MATCH = 0x01 + BITMASK_FLAG_OP_NOT = 0x02 + BITMASK_FLAG_OP_NOT_MATCH = 0x03 + BITMASK_FLAG_OP_AND = 0x40 + BITMASK_FLAG_OP_END = 0x80 ) var BitmaskFlagOpNameMap = map[BitmaskFlagOp]string{ @@ -146,22 +145,30 @@ var BitmaskFlagOpNameMap = map[BitmaskFlagOp]string{ BITMASK_FLAG_OP_MATCH: "=", } -var BitmaskFlagOpValueMap = map[string]BitmaskFlagOp{ - BitmaskFlagOpNameMap[BITMASK_FLAG_OP_OR]: BITMASK_FLAG_OP_OR, - BitmaskFlagOpNameMap[BITMASK_FLAG_OP_AND]: BITMASK_FLAG_OP_AND, - BitmaskFlagOpNameMap[BITMASK_FLAG_OP_END]: BITMASK_FLAG_OP_END, - BitmaskFlagOpNameMap[BITMASK_FLAG_OP_NOT]: BITMASK_FLAG_OP_NOT, - BitmaskFlagOpNameMap[BITMASK_FLAG_OP_MATCH]: BITMASK_FLAG_OP_MATCH, +func (f BitmaskFlagOp) String() string { + ops := make([]string, 0) + if f&BITMASK_FLAG_OP_AND > 0 { + ops = append(ops, BitmaskFlagOpNameMap[BITMASK_FLAG_OP_AND]) + } else { + ops = append(ops, BitmaskFlagOpNameMap[BITMASK_FLAG_OP_OR]) + } + if f&BITMASK_FLAG_OP_NOT > 0 { + ops = append(ops, BitmaskFlagOpNameMap[BITMASK_FLAG_OP_NOT]) + } + if f&BITMASK_FLAG_OP_MATCH > 0 { + ops = append(ops, BitmaskFlagOpNameMap[BITMASK_FLAG_OP_MATCH]) + } + return strings.Join(ops, "") } type FragmentFlag int const ( - FRAG_FLAG_NOT = 0x00 - FRAG_FLAG_DONT = 0x01 - FRAG_FLAG_IS = 0x02 - FRAG_FLAG_FIRST = 0x04 - FRAG_FLAG_LAST = 0x08 + FRAG_FLAG_NOT FragmentFlag = iota + FRAG_FLAG_DONT = 0x01 + FRAG_FLAG_IS = 0x02 + FRAG_FLAG_FIRST = 0x04 + FRAG_FLAG_LAST = 0x08 ) var FragmentFlagNameMap = map[FragmentFlag]string{ @@ -172,25 +179,41 @@ var FragmentFlagNameMap = map[FragmentFlag]string{ FRAG_FLAG_LAST: "last-fragment", } -var FragmentFlagValueMap = map[string]FragmentFlag{ - FragmentFlagNameMap[FRAG_FLAG_NOT]: FRAG_FLAG_NOT, - FragmentFlagNameMap[FRAG_FLAG_DONT]: FRAG_FLAG_DONT, - FragmentFlagNameMap[FRAG_FLAG_IS]: FRAG_FLAG_IS, - FragmentFlagNameMap[FRAG_FLAG_FIRST]: FRAG_FLAG_FIRST, - FragmentFlagNameMap[FRAG_FLAG_LAST]: FRAG_FLAG_LAST, +// Prepares a sorted list of flags because map iterations does not happen +// in a consistent order in Golang. +var FragmentSortedFlags = []FragmentFlag{ + FRAG_FLAG_NOT, + FRAG_FLAG_DONT, + FRAG_FLAG_IS, + FRAG_FLAG_FIRST, + FRAG_FLAG_LAST, +} + +func (f FragmentFlag) String() string { + flags := make([]string, 0, len(FragmentSortedFlags)) + for _, v := range FragmentSortedFlags { + if f&v > 0 { + flags = append(flags, FragmentFlagNameMap[v]) + } + } + // Note: If multiple bits are set, joins them with "+". + return strings.Join(flags, "+") } type DECNumOp int const ( - DEC_NUM_OP_TRUE = 0x00 // true always with END bit set - DEC_NUM_OP_EQ = 0x01 - DEC_NUM_OP_GT = 0x02 - DEC_NUM_OP_GT_EQ = 0x03 - DEC_NUM_OP_LT = 0x04 - DEC_NUM_OP_LT_EQ = 0x05 - DEC_NUM_OP_NOT_EQ = 0x06 - DEC_NUM_OP_FALSE = 0x07 // true always with END bit set + DEC_NUM_OP_TRUE DECNumOp = iota // true always with END bit set + DEC_NUM_OP_EQ = 0x01 + DEC_NUM_OP_GT = 0x02 + DEC_NUM_OP_GT_EQ = 0x03 + DEC_NUM_OP_LT = 0x04 + DEC_NUM_OP_LT_EQ = 0x05 + DEC_NUM_OP_NOT_EQ = 0x06 + DEC_NUM_OP_FALSE = 0x07 // false always with END bit set + DEC_NUM_OP_OR = 0x00 + DEC_NUM_OP_AND = 0x40 + DEC_NUM_OP_END = 0x80 ) var DECNumOpNameMap = map[DECNumOp]string{ @@ -202,49 +225,31 @@ var DECNumOpNameMap = map[DECNumOp]string{ DEC_NUM_OP_LT_EQ: "<=", DEC_NUM_OP_NOT_EQ: "!=", DEC_NUM_OP_FALSE: "false", + //DEC_NUM_OP_OR: " ", // duplicate with DEC_NUM_OP_TRUE + DEC_NUM_OP_AND: "&", + DEC_NUM_OP_END: "E", } -var DECNumOpValueMap = map[string]DECNumOp{ - DECNumOpNameMap[DEC_NUM_OP_TRUE]: DEC_NUM_OP_TRUE, - DECNumOpNameMap[DEC_NUM_OP_EQ]: DEC_NUM_OP_EQ, - DECNumOpNameMap[DEC_NUM_OP_GT]: DEC_NUM_OP_GT, - DECNumOpNameMap[DEC_NUM_OP_GT_EQ]: DEC_NUM_OP_GT_EQ, - DECNumOpNameMap[DEC_NUM_OP_LT]: DEC_NUM_OP_LT, - DECNumOpNameMap[DEC_NUM_OP_LT_EQ]: DEC_NUM_OP_LT_EQ, - DECNumOpNameMap[DEC_NUM_OP_NOT_EQ]: DEC_NUM_OP_NOT_EQ, - DECNumOpNameMap[DEC_NUM_OP_FALSE]: DEC_NUM_OP_FALSE, -} - -type DECLogicOp int - -const ( - DEC_LOGIC_OP_END = 0x80 - DEC_LOGIC_OP_OR = 0x00 - DEC_LOGIC_OP_AND = 0x40 -) - -var DECLogicOpNameMap = map[DECLogicOp]string{ - DEC_LOGIC_OP_OR: " ", - DEC_LOGIC_OP_AND: "&", - DEC_LOGIC_OP_END: "E", -} - -var DECLogicOpValueMap = map[string]DECLogicOp{ - DECLogicOpNameMap[DEC_LOGIC_OP_OR]: DEC_LOGIC_OP_OR, - DECLogicOpNameMap[DEC_LOGIC_OP_AND]: DEC_LOGIC_OP_AND, - DECLogicOpNameMap[DEC_LOGIC_OP_END]: DEC_LOGIC_OP_END, -} - -func (f TCPFlag) String() string { - ss := make([]string, 0, 6) - for _, v := range []TCPFlag{TCP_FLAG_FIN, TCP_FLAG_SYN, TCP_FLAG_RST, TCP_FLAG_PUSH, TCP_FLAG_ACK, TCP_FLAG_URGENT, TCP_FLAG_CWR, TCP_FLAG_ECE} { - if f&v > 0 { - ss = append(ss, TCPFlagNameMap[v]) +func (f DECNumOp) String() string { + ops := make([]string, 0) + logicFlag := DECNumOp(f & 0xc0) // higher 2 bits + if logicFlag&DEC_NUM_OP_AND > 0 { + ops = append(ops, DECNumOpNameMap[DEC_NUM_OP_AND]) + } else { + ops = append(ops, " ") // DEC_NUM_OP_OR + } + // Omits DEC_NUM_OP_END + cmpFlag := DECNumOp(f & 0x7) // lower 3 bits + for v, s := range DECNumOpNameMap { + if cmpFlag == v { + ops = append(ops, s) + break } } - return strings.Join(ss, "|") + return strings.Join(ops, "") } +// Potentially taken from https://www.iana.org/assignments/ieee-802-numbers/ieee-802-numbers.xhtml type EthernetType int const ( @@ -281,27 +286,9 @@ var EthernetTypeNameMap = map[EthernetType]string{ LOOPBACK: "loopback", } -var EthernetTypeValueMap = map[string]EthernetType{ - EthernetTypeNameMap[IPv4]: IPv4, - EthernetTypeNameMap[ARP]: ARP, - EthernetTypeNameMap[RARP]: RARP, - EthernetTypeNameMap[VMTP]: VMTP, - EthernetTypeNameMap[APPLE_TALK]: APPLE_TALK, - EthernetTypeNameMap[AARP]: AARP, - EthernetTypeNameMap[IPX]: IPX, - EthernetTypeNameMap[SNMP]: SNMP, - EthernetTypeNameMap[NET_BIOS]: NET_BIOS, - EthernetTypeNameMap[XTP]: XTP, - EthernetTypeNameMap[IPv6]: IPv6, - EthernetTypeNameMap[PPPoE_DISCOVERY]: PPPoE_DISCOVERY, - EthernetTypeNameMap[PPPoE_SESSION]: PPPoE_SESSION, - EthernetTypeNameMap[LOOPBACK]: LOOPBACK, -} - func (t EthernetType) String() string { - n, ok := EthernetTypeNameMap[t] - if !ok { - return fmt.Sprintf("%d", t) + if name, ok := EthernetTypeNameMap[t]; ok { + return name } - return n + return fmt.Sprintf("%d", t) } |