From 5e36e85d0cae68740829f2f1cbf839dbc4b2c18f Mon Sep 17 00:00:00 2001 From: brian Date: Mon, 18 Jun 2018 18:18:31 -0700 Subject: [PATCH 01/10] Add DHCP protocol handling for packetbeat --- packetbeat/protos/dhcp/_meta/fields.yml | 59 +++++++ packetbeat/protos/dhcp/config.go | 13 ++ packetbeat/protos/dhcp/dhcp.go | 195 ++++++++++++++++++++++++ packetbeat/protos/dhcp/dhcp_test.go | 70 +++++++++ 4 files changed, 337 insertions(+) create mode 100644 packetbeat/protos/dhcp/_meta/fields.yml create mode 100644 packetbeat/protos/dhcp/config.go create mode 100644 packetbeat/protos/dhcp/dhcp.go create mode 100644 packetbeat/protos/dhcp/dhcp_test.go diff --git a/packetbeat/protos/dhcp/_meta/fields.yml b/packetbeat/protos/dhcp/_meta/fields.yml new file mode 100644 index 000000000000..fcbf9f4f5d7a --- /dev/null +++ b/packetbeat/protos/dhcp/_meta/fields.yml @@ -0,0 +1,59 @@ +- key: dhcp + title: "DHCP" + description: DHCP-specific event fields + fields: + - name: dhcp + type: group + fields: + - name: transaction_id + type: string + description: Generated by the client, allows the client to correctly match requests and responses. + + - name: client_ip + type: string + description: The current IP address of the client. + + - name: assigned_ip + type: string + description: The IP address that the DHCP server is assigning to the client. + + - name: server_ip + type: string + description: The IP address of the DHCP server that the client should use for the next step in the bootstrap process. + + - name: gateway_ip + type: string + description: The gateway IP address used by the client to contact the server. + + - name: client_hwaddr + type: string + description: The client's hardware (layer two) address. + + - name: server_name + type: string + description: Optional, for DHCPOFFER or DHCPACK messages, the name of the server sending the message. + + - name: op_code + type: int + description: The general type of DHCP message. + + - name: hops + type: int + description: The number of hops the DHCP message went through. + + - name: hardware_type + type: string + description: The type of hardware used for the local network (Ethernet, LocalTalk, etc) + + - name: message_type + type: string + description: The specific type of DHCP message being sent (DHCPOFFER, DCHPREQUEST, etc) + + - name: server_identifier + type: string + description: IP address of the individual DHCP server which handled this message. + + - name: subnet_mask + type: string + description: The subnet mask that the client should use on the currnet network. + diff --git a/packetbeat/protos/dhcp/config.go b/packetbeat/protos/dhcp/config.go new file mode 100644 index 000000000000..91865f5ab6e4 --- /dev/null +++ b/packetbeat/protos/dhcp/config.go @@ -0,0 +1,13 @@ +package dhcp + +import ( + "github.com/elastic/beats/packetbeat/config" +) + +type dhcpConfig struct { + config.ProtocolCommon `config:",inline"` +} + +var ( + defaultConfig = dhcpConfig{} +) diff --git a/packetbeat/protos/dhcp/dhcp.go b/packetbeat/protos/dhcp/dhcp.go new file mode 100644 index 000000000000..ea92030706f5 --- /dev/null +++ b/packetbeat/protos/dhcp/dhcp.go @@ -0,0 +1,195 @@ +package dhcp + +import ( + "bytes" + "encoding/hex" + "github.com/elastic/beats/libbeat/beat" + "github.com/elastic/beats/libbeat/common" + "github.com/elastic/beats/libbeat/logp" + "github.com/elastic/beats/packetbeat/protos" + "net" +) + +var hardwareTypes = map[int]string{ + 1: "ethernet", + 6: "ieee_802", + 7: "arcnet", + 11: "localtalk", + 12: "localnet", + 14: "smds", + 15: "frame_relay", + 16: "atm", + 17: "hdlc", + 18: "fibre_channel", + 19: "atm", + 20: "serial_line", +} + +var messageTypes = []string{ + "DHCPDISCOVER", + "DHCPOFFER", + "DHCPREQUEST", + "DHCPDECLINE", + "DHCPACK", + "DHCPNAK", + "DHCPRELEASE", + "DHCPINFORM", +} + +type dhcpPlugin struct { + ports []int + results protos.Reporter +} + +func (dhcp *dhcpPlugin) init(results protos.Reporter, config *dhcpConfig) { + dhcp.ports = config.Ports + dhcp.results = results +} + +func (dhcp *dhcpPlugin) GetPorts() []int { + return dhcp.ports +} + +func payloadToRows(payload []byte) [][]byte { + result := make([][]byte, 0) + var idx = 0 + for idx < len(payload) { + result = append(result, []byte{payload[idx], payload[idx+1], payload[idx+2], payload[idx+3]}) + idx += 4 + } + return result +} + +func bytesToIPv4(bytes []byte) string { + ip := net.IPv4(bytes[0], bytes[1], bytes[2], bytes[3]) + str := ip.String() + if str == "0.0.0.0" { + return "" + } + return str +} + +func bytesToHardwareAddress(bytes []byte, length int) string { + return net.HardwareAddr(bytes[0:length]).String() +} + +func combineRows(rows [][]byte, start int, length int) []byte { + combined := make([]byte, 0) + end := start + length + var idx = start + for idx < end { + combined = append(combined, rows[idx]...) + idx++ + } + return combined +} + +func trimNullBytes(b []byte) []byte { + index := bytes.Index(b, []byte{0}) + return b[0:index] +} + +func extractOptions(payload []byte) []byte { + result := make([]byte, 0) + var idx = 240 + for idx < len(payload) { + result = append(result, payload[idx]) + idx++ + } + return result +} + +func parseOptions(options []byte) map[int][]byte { + result := make(map[int][]byte) + var remaining = 0 + var option = 0 + var body = make([]byte, 0) + var idx = 0 + for idx < len(options) { + if remaining == 0 { + if option != 0 { + result[option] = body + body = make([]byte, 0) + } + option = int(options[idx]) + if option == 0 || option == 255 { + idx = len(options) + } else { + idx++ + remaining = int(options[idx]) + } + } else { + body = append(body, options[idx]) + remaining-- + } + idx++ + } + return result +} + +func (dhcp *dhcpPlugin) parsePacket(pkt *protos.Packet) beat.Event { + dhcpFields := make(map[string]interface{}) + rows := payloadToRows(pkt.Payload) + dhcpFields["transaction_id"] = hex.EncodeToString(rows[1]) + dhcpFields["client_ip"] = bytesToIPv4(rows[3]) + dhcpFields["assigned_ip"] = bytesToIPv4(rows[4]) + dhcpFields["server_ip"] = bytesToIPv4(rows[5]) + dhcpFields["gateway_ip"] = bytesToIPv4(rows[6]) + hwaddr := combineRows(rows, 7, 4) + dhcpFields["client_hwaddr"] = bytesToHardwareAddress(hwaddr, int(pkt.Payload[2])) + serverName := trimNullBytes(combineRows(rows, 11, 16)) + dhcpFields["server_name"] = string(serverName) + dhcpFields["op_code"] = int(pkt.Payload[0]) + dhcpFields["hops"] = int(pkt.Payload[3]) + dhcpFields["hardware_type"] = hardwareTypes[int(pkt.Payload[1])] + options := extractOptions(pkt.Payload) + parsedOptions := parseOptions(options) + if parsedOptions[53] != nil { + dhcpFields["message_type"] = messageTypes[int(parsedOptions[53][0])-1] + } + if parsedOptions[54] != nil { + dhcpFields["server_identifier"] = bytesToIPv4(parsedOptions[54]) + } + if parsedOptions[1] != nil { + dhcpFields["subnet_mask"] = bytesToIPv4(parsedOptions[1]) + } + event := beat.Event{ + Timestamp: pkt.Ts, + Fields: map[string]interface{}{ + "transport": "udp", + "ip": pkt.Tuple.DstIP.String(), + "client_ip": pkt.Tuple.SrcIP.String(), + "port": pkt.Tuple.DstPort, + "client_port": pkt.Tuple.SrcPort, + "type": "dhcp", + "dhcp": dhcpFields, + }, + } + return event +} + +func (dhcp *dhcpPlugin) ParseUDP(pkt *protos.Packet) { + event := dhcp.parsePacket(pkt) + dhcp.results(event) +} + +func init() { + protos.Register("dhcp", New) +} + +func New( + testMode bool, + results protos.Reporter, + cfg *common.Config, +) (protos.Plugin, error) { + p := &dhcpPlugin{} + config := defaultConfig + if !testMode { + if err := cfg.Unpack(&config); err != nil { + logp.Err("Error unpacking configuration: %s", err) + return nil, err + } + } + p.init(results, &config) + return p, nil +} diff --git a/packetbeat/protos/dhcp/dhcp_test.go b/packetbeat/protos/dhcp/dhcp_test.go new file mode 100644 index 000000000000..deba6d93a686 --- /dev/null +++ b/packetbeat/protos/dhcp/dhcp_test.go @@ -0,0 +1,70 @@ +package dhcp + +import ( + "fmt" + "github.com/elastic/beats/libbeat/beat" + "github.com/elastic/beats/libbeat/common" + "github.com/elastic/beats/packetbeat/protos" + "github.com/stretchr/testify/assert" + "net" + "testing" + "time" +) + +var ( + payload = []byte{ + 0x02, 0x01, 0x06, 0x00, 0x00, 0x00, 0x3d, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x00, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x82, 0x01, 0xfc, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, 0x53, 0x63, + 0x35, 0x01, 0x05, 0x3a, 0x04, 0x00, 0x00, 0x07, 0x08, 0x3b, 0x04, 0x00, 0x00, 0x0c, 0x4e, 0x33, 0x04, 0x00, 0x00, 0x0e, + 0x10, 0x36, 0x04, 0xc0, 0xa8, 0x00, 0x01, 0x01, 0x04, 0xff, 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + } +) + +var _ protos.UDPPlugin = &dhcpPlugin{} + +func get(event beat.Event, fieldName string) interface{} { + value, _ := event.Fields.GetValue(fieldName) + return value +} + +func TestParsePacket(t *testing.T) { + plugin := dhcpPlugin{} + ipTuple := common.NewIPPortTuple(4, net.IP{192, 168, 0, 10}, 67, net.IP{192, 168, 0, 1}, 68) + pkt := &protos.Packet{ + Ts: time.Now(), + Tuple: ipTuple, + Payload: payload, + } + expectedDhcpFields := map[string]interface{}{ + "client_ip": "", + "client_hwaddr": "00:0b:82:01:fc:42", + "gateway_ip": "", + "hardware_type": "ethernet", + "hops": int(0), + "message_type": "DHCPACK", + "op_code": int(2), + "server_identifier": "192.168.0.1", + "server_ip": "", + "server_name": "", + "subnet_mask": "255.255.255.0", + "transaction_id": "00003d1e", + "assigned_ip": "192.168.0.10", + } + event := plugin.parsePacket(pkt) + fmt.Printf("Gpt event: %+v", event) + assert.Equal(t, "192.168.0.1", get(event, "ip").(string), "Wrong ip") + assert.Equal(t, "192.168.0.10", get(event, "client_ip").(string), "Wrong client_ip") + dhcpFields := get(event, "dhcp").(map[string]interface{}) + assert.Equal(t, expectedDhcpFields, dhcpFields) +} From e80125fbe6fd9f62e37d0348b44906824b3f64aa Mon Sep 17 00:00:00 2001 From: brian Date: Mon, 18 Jun 2018 18:23:26 -0700 Subject: [PATCH 02/10] add comment --- packetbeat/protos/dhcp/dhcp.go | 1 + 1 file changed, 1 insertion(+) diff --git a/packetbeat/protos/dhcp/dhcp.go b/packetbeat/protos/dhcp/dhcp.go index ea92030706f5..ac1d74c6a742 100644 --- a/packetbeat/protos/dhcp/dhcp.go +++ b/packetbeat/protos/dhcp/dhcp.go @@ -177,6 +177,7 @@ func init() { protos.Register("dhcp", New) } +// Creates and returns a new dhcpPlugin. func New( testMode bool, results protos.Reporter, From ac054a9131acda6b0d429c30f910a926f6633c80 Mon Sep 17 00:00:00 2001 From: brian Date: Mon, 18 Jun 2018 18:24:23 -0700 Subject: [PATCH 03/10] add comment --- packetbeat/protos/dhcp/dhcp.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packetbeat/protos/dhcp/dhcp.go b/packetbeat/protos/dhcp/dhcp.go index ac1d74c6a742..0115922b440d 100644 --- a/packetbeat/protos/dhcp/dhcp.go +++ b/packetbeat/protos/dhcp/dhcp.go @@ -177,7 +177,7 @@ func init() { protos.Register("dhcp", New) } -// Creates and returns a new dhcpPlugin. +// New dhcpPlugin is created. func New( testMode bool, results protos.Reporter, From 03f9f215171dcba6c2a7f6a6438c52b8f1fa176a Mon Sep 17 00:00:00 2001 From: brian Date: Tue, 19 Jun 2018 17:52:11 -0700 Subject: [PATCH 04/10] formatting --- packetbeat/protos/dhcp/dhcp.go | 3 ++- packetbeat/protos/dhcp/dhcp_test.go | 10 ++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/packetbeat/protos/dhcp/dhcp.go b/packetbeat/protos/dhcp/dhcp.go index 0115922b440d..a528eb0a77a9 100644 --- a/packetbeat/protos/dhcp/dhcp.go +++ b/packetbeat/protos/dhcp/dhcp.go @@ -3,11 +3,12 @@ package dhcp import ( "bytes" "encoding/hex" + "net" + "github.com/elastic/beats/libbeat/beat" "github.com/elastic/beats/libbeat/common" "github.com/elastic/beats/libbeat/logp" "github.com/elastic/beats/packetbeat/protos" - "net" ) var hardwareTypes = map[int]string{ diff --git a/packetbeat/protos/dhcp/dhcp_test.go b/packetbeat/protos/dhcp/dhcp_test.go index deba6d93a686..77729d94dba3 100644 --- a/packetbeat/protos/dhcp/dhcp_test.go +++ b/packetbeat/protos/dhcp/dhcp_test.go @@ -2,13 +2,15 @@ package dhcp import ( "fmt" - "github.com/elastic/beats/libbeat/beat" - "github.com/elastic/beats/libbeat/common" - "github.com/elastic/beats/packetbeat/protos" - "github.com/stretchr/testify/assert" "net" "testing" "time" + + "github.com/stretchr/testify/assert" + + "github.com/elastic/beats/libbeat/beat" + "github.com/elastic/beats/libbeat/common" + "github.com/elastic/beats/packetbeat/protos" ) var ( From 88a3cf9ca7d0ca7c15afb03073f17479a61874c2 Mon Sep 17 00:00:00 2001 From: brian Date: Tue, 19 Jun 2018 20:07:54 -0700 Subject: [PATCH 05/10] add test --- packetbeat/tests/system/pcaps/dhcp.pcap | Bin 0 -> 1400 bytes packetbeat/tests/system/test_0066_dhcp.py | 32 ++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 packetbeat/tests/system/pcaps/dhcp.pcap create mode 100644 packetbeat/tests/system/test_0066_dhcp.py diff --git a/packetbeat/tests/system/pcaps/dhcp.pcap b/packetbeat/tests/system/pcaps/dhcp.pcap new file mode 100644 index 0000000000000000000000000000000000000000..a42d6102e8a27868cf17b3da7a31af47d3140f5f GIT binary patch literal 1400 zcmca|c+)~A1{MYw`2U}Qff2~*h}-PQdxM3+3djNB|6stt-Ng9EiG#tFfl+6L83V&F zLGf;oPLL#n3xhMGM5H_;BO6e}Ru&|V0l@k(M2D+aba9{-kBM@^jI5W5~nkX4F zp@k$!4x|Qb?63?;CPo%eO0oh5BRhvRkmT_*29kUNW-K6&!-5nNuqY%bl;^x;#g|^q z!RfUNqz#c?=kJB4S2+~pV4PtY%FIaV6_lnRfeTBuppd-wiWOgab;Fik@85=|S9nN* a%!UOdG}XhoL!AN1`K-87DkL4_Nv{BdC3Zjn literal 0 HcmV?d00001 diff --git a/packetbeat/tests/system/test_0066_dhcp.py b/packetbeat/tests/system/test_0066_dhcp.py new file mode 100644 index 000000000000..ff797a01669a --- /dev/null +++ b/packetbeat/tests/system/test_0066_dhcp.py @@ -0,0 +1,32 @@ +from packetbeat import BaseTest + +""" +Tests for the DHCP protocol. +""" + + +class Test(BaseTest): + + def test_dhcp(self): + self.render_config_template( + dhcp_ports=[67], + ) + self.run_packetbeat(pcap="dhcp.pcap") + + objs = self.read_output() + assert len(objs) == 3 + assert objs[0]['dhcp.client_ip'] == '' + assert objs[0]['dhcp.server_ip'] == '' + assert objs[0]['dhcp.op_code'] == 1 + assert objs[0]['dhcp.hops'] == 0 + assert objs[0]['dhcp.gateway_ip'] == '' + assert objs[0]['dhcp.client_hwaddr'] == '00:0b:82:01:fc:42' + assert objs[0]['dhcp.message_type'] == 'DHCPDISCOVER' + assert objs[0]['dhcp.transaction_id'] == '00003d1d' + assert objs[0]['dhcp.server_name'] == '' + assert objs[0]['dhcp.hardware_type'] == 'ethernet' + assert objs[0]['dhcp.assigned_ip'] == '' + assert objs[1]['dhcp.server_ip'] == '192.168.0.1' + assert objs[1]['dhcp.assigned_ip'] == '192.168.0.10' + assert objs[1]['dhcp.server_identifier'] == '192.168.0.1' + assert objs[0]['dhcp.message_type'] == 'DHCPOFFER' From bf01234d6864ebec8802adb230ab4d4ca9839f9a Mon Sep 17 00:00:00 2001 From: brian Date: Tue, 19 Jun 2018 20:18:28 -0700 Subject: [PATCH 06/10] push updated list.go --- packetbeat/include/list.go | 1 + 1 file changed, 1 insertion(+) diff --git a/packetbeat/include/list.go b/packetbeat/include/list.go index 6ab8eb8d3b42..29dd271204ed 100644 --- a/packetbeat/include/list.go +++ b/packetbeat/include/list.go @@ -10,6 +10,7 @@ import ( _ "github.com/elastic/beats/packetbeat/protos/amqp" _ "github.com/elastic/beats/packetbeat/protos/applayer" _ "github.com/elastic/beats/packetbeat/protos/cassandra" + _ "github.com/elastic/beats/packetbeat/protos/dhcp" _ "github.com/elastic/beats/packetbeat/protos/dns" _ "github.com/elastic/beats/packetbeat/protos/http" _ "github.com/elastic/beats/packetbeat/protos/icmp" From 7616f1779f911ea1241b43a28506bfc892f15f98 Mon Sep 17 00:00:00 2001 From: brian Date: Tue, 19 Jun 2018 21:05:30 -0700 Subject: [PATCH 07/10] regenerate fields.go --- packetbeat/docs/fields.asciidoc | 125 ++++++++++++++++++++++++++++++++ packetbeat/include/fields.go | 2 +- 2 files changed, 126 insertions(+), 1 deletion(-) diff --git a/packetbeat/docs/fields.asciidoc b/packetbeat/docs/fields.asciidoc index f5c109086ce4..616e256babfc 100644 --- a/packetbeat/docs/fields.asciidoc +++ b/packetbeat/docs/fields.asciidoc @@ -17,6 +17,7 @@ grouped in the following categories: * <> * <> * <> +* <> * <> * <> * <> @@ -1507,6 +1508,130 @@ The name of the process that initiated the transaction. The software release of the service serving the transaction. This can be the commit id or a semantic version. +-- + +[[exported-fields-dhcp]] +== DHCP fields + +DHCP-specific event fields + + + +*`dhcp.transaction_id`*:: ++ +-- +type: string + +Generated by the client, allows the client to correctly match requests and responses. + +-- + +*`dhcp.client_ip`*:: ++ +-- +type: string + +The current IP address of the client. + +-- + +*`dhcp.assigned_ip`*:: ++ +-- +type: string + +The IP address that the DHCP server is assigning to the client. + +-- + +*`dhcp.server_ip`*:: ++ +-- +type: string + +The IP address of the DHCP server that the client should use for the next step in the bootstrap process. + +-- + +*`dhcp.gateway_ip`*:: ++ +-- +type: string + +The gateway IP address used by the client to contact the server. + +-- + +*`dhcp.client_hwaddr`*:: ++ +-- +type: string + +The client's hardware (layer two) address. + +-- + +*`dhcp.server_name`*:: ++ +-- +type: string + +Optional, for DHCPOFFER or DHCPACK messages, the name of the server sending the message. + +-- + +*`dhcp.op_code`*:: ++ +-- +type: int + +The general type of DHCP message. + +-- + +*`dhcp.hops`*:: ++ +-- +type: int + +The number of hops the DHCP message went through. + +-- + +*`dhcp.hardware_type`*:: ++ +-- +type: string + +The type of hardware used for the local network (Ethernet, LocalTalk, etc) + +-- + +*`dhcp.message_type`*:: ++ +-- +type: string + +The specific type of DHCP message being sent (DHCPOFFER, DCHPREQUEST, etc) + +-- + +*`dhcp.server_identifier`*:: ++ +-- +type: string + +IP address of the individual DHCP server which handled this message. + +-- + +*`dhcp.subnet_mask`*:: ++ +-- +type: string + +The subnet mask that the client should use on the currnet network. + -- [[exported-fields-dns]] diff --git a/packetbeat/include/fields.go b/packetbeat/include/fields.go index b938cbb9645f..9cce486995fc 100644 --- a/packetbeat/include/fields.go +++ b/packetbeat/include/fields.go @@ -14,5 +14,5 @@ func init() { // Asset returns asset data func Asset() string { - return "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" + return "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" } From d4172e7177edc181a4a437038ef6c3ee7a7f3a08 Mon Sep 17 00:00:00 2001 From: brian Date: Wed, 20 Jun 2018 19:03:19 -0700 Subject: [PATCH 08/10] fix test --- packetbeat/tests/system/test_0066_dhcp.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packetbeat/tests/system/test_0066_dhcp.py b/packetbeat/tests/system/test_0066_dhcp.py index ff797a01669a..3752c0902c21 100644 --- a/packetbeat/tests/system/test_0066_dhcp.py +++ b/packetbeat/tests/system/test_0066_dhcp.py @@ -13,8 +13,8 @@ def test_dhcp(self): ) self.run_packetbeat(pcap="dhcp.pcap") - objs = self.read_output() - assert len(objs) == 3 + objs = self.read_output(types=['dhcp']) + assert len(objs) == 4 assert objs[0]['dhcp.client_ip'] == '' assert objs[0]['dhcp.server_ip'] == '' assert objs[0]['dhcp.op_code'] == 1 @@ -29,4 +29,4 @@ def test_dhcp(self): assert objs[1]['dhcp.server_ip'] == '192.168.0.1' assert objs[1]['dhcp.assigned_ip'] == '192.168.0.10' assert objs[1]['dhcp.server_identifier'] == '192.168.0.1' - assert objs[0]['dhcp.message_type'] == 'DHCPOFFER' + assert objs[1]['dhcp.message_type'] == 'DHCPOFFER' From d9f14adcdfff4f98145c1a2071de015ab5db85f1 Mon Sep 17 00:00:00 2001 From: brian Date: Wed, 20 Jun 2018 19:18:24 -0700 Subject: [PATCH 09/10] updated config --- packetbeat/tests/system/config/packetbeat.yml.j2 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packetbeat/tests/system/config/packetbeat.yml.j2 b/packetbeat/tests/system/config/packetbeat.yml.j2 index 95b02acc16c7..8f699481b348 100644 --- a/packetbeat/tests/system/config/packetbeat.yml.j2 +++ b/packetbeat/tests/system/config/packetbeat.yml.j2 @@ -132,6 +132,8 @@ packetbeat.protocols: {% if mongodb_max_docs is not none %} max_docs: {{mongodb_max_docs}}{% endif %} {% if mongodb_max_doc_length is not none %} max_doc_length: {{mongodb_max_doc_length}}{% endif %} +- type: dhcp + ports: [{{ dhcp_ports|default([67])|join(", ") }}] {% if procs_enabled %} #=========================== Monitored processes ============================== From 6dc1256804fb1a47bdea43a52b0ba0338ad6e6a0 Mon Sep 17 00:00:00 2001 From: brian Date: Wed, 20 Jun 2018 19:34:12 -0700 Subject: [PATCH 10/10] add status field --- packetbeat/protos/dhcp/dhcp.go | 1 + 1 file changed, 1 insertion(+) diff --git a/packetbeat/protos/dhcp/dhcp.go b/packetbeat/protos/dhcp/dhcp.go index a528eb0a77a9..a8557d54b110 100644 --- a/packetbeat/protos/dhcp/dhcp.go +++ b/packetbeat/protos/dhcp/dhcp.go @@ -164,6 +164,7 @@ func (dhcp *dhcpPlugin) parsePacket(pkt *protos.Packet) beat.Event { "client_port": pkt.Tuple.SrcPort, "type": "dhcp", "dhcp": dhcpFields, + "status": "OK", }, } return event