diff --git a/scripts/base/frameworks/openflow/utils/const.bro b/scripts/base/frameworks/openflow/utils/const.bro new file mode 100644 index 0000000000..18c79eb28e --- /dev/null +++ b/scripts/base/frameworks/openflow/utils/const.bro @@ -0,0 +1,104 @@ +# All types/constants not specific to Openflow will be defined here +# unitl they somehow get into bro. + +module Openflow; + +export { + # All ethertypes can be found at + # http://standards.ieee.org/develop/regauth/ethertype/eth.txt + # but are not interesting for us at this point +#type ethertype: enum { + # Internet protocol version 4 + const ETH_IPv4 = 0x0800; + # Address resolution protocol + const ETH_ARP = 0x0806; + # Wake on LAN + const ETH_WOL = 0x0842; + # Reverse address resolution protocol + const ETH_RARP = 0x8035; + # Appletalk + const ETH_APPLETALK = 0x809B; + # Appletalk address resolution protocol + const ETH_APPLETALK_ARP = 0x80F3; + # IEEE 802.1q & IEEE 802.1aq + const ETH_VLAN = 0x8100; + # Novell IPX old + const ETH_IPX_OLD = 0x8137; + # Novell IPX + const ETH_IPX = 0x8138; + # Internet protocol version 6 + const ETH_IPv6 = 0x86DD; + # IEEE 802.3x + const ETH_ETHER_FLOW_CONTROL = 0x8808; + # Multiprotocol Label Switching unicast + const ETH_MPLS_UNICAST = 0x8847; + # Multiprotocol Label Switching multicast + const ETH_MPLS_MULTICAST = 0x8848; + # Point-to-point protocol over Ethernet discovery phase (rfc2516) + const ETH_PPPOE_DISCOVERY = 0x8863; + # Point-to-point protocol over Ethernet session phase (rfc2516) + const ETH_PPPOE_SESSION = 0x8864; + # Jumbo frames + const ETH_JUMBO_FRAMES = 0x8870; + # IEEE 802.1X + const ETH_EAP_OVER_LAN = 0x888E; + # IEEE 802.1ad & IEEE 802.1aq + const ETH_PROVIDER_BRIDING = 0x88A8; + # IEEE 802.1ae + const ETH_MAC_SECURITY = 0x88E5; + # IEEE 802.1ad (QinQ) + const ETH_QINQ = 0x9100; +#}; + + # A list of ip protocol numbers can be found at + # http://en.wikipedia.org/wiki/List_of_IP_protocol_numbers +#type iptype: enum { + # IPv6 Hop-by-Hop Option (RFC2460) + const IP_HOPOPT = 0x00; + # Internet Control Message Protocol (RFC792) + const IP_ICMP = 0x01; + # Internet Group Management Protocol (RFC1112) + const IP_IGMP = 0x02; + # Gateway-to-Gateway Protocol (RFC823) + const IP_GGP = 0x03; + # IP-Within-IP (encapsulation) (RFC2003) + const IP_IPIP = 0x04; + # Internet Stream Protocol (RFC1190;RFC1819) + const IP_ST = 0x05; + # Tansmission Control Protocol (RFC793) + const IP_TCP = 0x06; + # Core-based trees (RFC2189) + const IP_CBT = 0x07; + # Exterior Gateway Protocol (RFC888) + const IP_EGP = 0x08; + # Interior Gateway Protocol (any private interior + # gateway (used by Cisco for their IGRP)) + const IP_IGP = 0x09; + # User Datagram Protocol (RFC768) + const IP_UDP = 0x11; + # Reliable Datagram Protocol (RFC908) + const IP_RDP = 0x1B; + # IPv6 Encapsulation (RFC2473) + const IP_IPv6 = 0x29; + # Resource Reservation Protocol (RFC2205) + const IP_RSVP = 0x2E; + # Generic Routing Encapsulation (RFC2784;RFC2890) + const IP_GRE = 0x2F; + # Open Shortest Path First (RFC1583) + const IP_OSPF = 0x59; + # Multicast Transport Protocol + const IP_MTP = 0x5C; + # IP-within-IP Encapsulation Protocol (RFC2003) + ### error 0x5E; + # Ethernet-within-IP Encapsulation Protocol (RFC3378) + const IP_ETHERIP = 0x61; + # Layer Two Tunneling Protocol Version 3 (RFC3931) + const IP_L2TP = 0x73; + # Intermediate System to Intermediate System (IS-IS) Protocol over IPv4 (RFC1142;RFC1195) + const IP_ISIS = 0x7C; + # Fibre Channel + const IP_FC = 0x85; + # Multiprotocol Label Switching Encapsulated in IP (RFC4023) + const IP_MPLS = 0x89; +#}; +} \ No newline at end of file diff --git a/scripts/base/frameworks/openflow/utils/json.bro b/scripts/base/frameworks/openflow/utils/json.bro new file mode 100644 index 0000000000..c482314698 --- /dev/null +++ b/scripts/base/frameworks/openflow/utils/json.bro @@ -0,0 +1,108 @@ +@load base/utils/strings + +module JSON; + +export { + ## A function to convert arbitrary Bro data into a JSON string. + ## + ## v: The value to convert to JSON. Typically a record. + ## + ## only_loggable: If the v value is a record this will only cause + ## fields with the &log attribute to be included in the JSON. + ## + ## returns: a JSON formatted string. + global convert: function(v: any, only_loggable: bool &default=F, field_escape_pattern: pattern &default=/^_/): string; +} + +function convert(v: any, only_loggable: bool &default=F, field_escape_pattern: pattern &default=/^_/): string + { + local tn = type_name(v); + switch ( tn ) + { + case "type": + return ""; + + case "string": + return cat("\"", gsub(gsub(clean(v), /\\/, "\\\\"), /\"/, "\\\""), "\""); + + case "port": + return cat(port_to_count(to_port(cat(v)))); + + case "addr": + return cat("\"", v, "\""); + + case "int": + fallthrough; + case "count": + fallthrough; + case "time": + fallthrough; + case "double": + fallthrough; + case "bool": + fallthrough; + case "enum": + return cat(v); + + default: + break; + } + + if ( /^record/ in tn ) + { + local rec_parts: string_vec = vector(); + + local ft = record_fields(v); + for ( field in ft ) + { + local field_desc = ft[field]; + # replace the escape pattern in the field. + if( field_escape_pattern in field ) + { + field = cat(sub(field, field_escape_pattern, "")); + } + if ( field_desc?$value && (!only_loggable || field_desc$log) ) + { + local onepart = cat("\"", field, "\": ", JSON::convert(field_desc$value, only_loggable)); + rec_parts[|rec_parts|] = onepart; + } + } + return cat("{", join_string_vec(rec_parts, ", "), "}"); + } + + # None of the following are supported. + else if ( /^set/ in tn ) + { + local set_parts: string_vec = vector(); + local sa: set[bool] = v; + for ( sv in sa ) + { + set_parts[|set_parts|] = JSON::convert(sv, only_loggable); + } + return cat("[", join_string_vec(set_parts, ", "), "]"); + } + else if ( /^table/ in tn ) + { + local tab_parts: vector of string = vector(); + local ta: table[bool] of any = v; + for ( ti in ta ) + { + local ts = JSON::convert(ti); + local if_quotes = (ts[0] == "\"") ? "" : "\""; + tab_parts[|tab_parts|] = cat(if_quotes, ts, if_quotes, ": ", JSON::convert(ta[ti], only_loggable)); + } + return cat("{", join_string_vec(tab_parts, ", "), "}"); + } + else if ( /^vector/ in tn ) + { + local vec_parts: string_vec = vector(); + local va: vector of any = v; + for ( vi in va ) + { + vec_parts[|vec_parts|] = JSON::convert(va[vi], only_loggable); + } + return cat("[", join_string_vec(vec_parts, ", "), "]"); + } + + return "\"\""; + } \ No newline at end of file