From 3219b8a63def6d648b7a5a53ed714cb481a041d9 Mon Sep 17 00:00:00 2001 From: Guillaume Valadon Date: Tue, 25 Jun 2019 18:41:48 +0200 Subject: [PATCH] Remove duplicated code --- scapy/layers/dhcp6.py | 47 ++++++++++++++----------------- scapy/layers/ppp.py | 58 ++++++++++---------------------------- scapy/layers/sctp.py | 65 ++++++++----------------------------------- 3 files changed, 46 insertions(+), 124 deletions(-) diff --git a/scapy/layers/dhcp6.py b/scapy/layers/dhcp6.py index e02545d46a4..136ca4ff529 100644 --- a/scapy/layers/dhcp6.py +++ b/scapy/layers/dhcp6.py @@ -1699,6 +1699,25 @@ def make_reply(self, req): msgtype = p.msgtype trid = p.trid + def _include_options(query, answer): + """ + Include options from the DHCPv6 query + """ + + # See which options should be included + reqopts = [] + if query.haslayer(DHCP6OptOptReq): # add only asked ones + reqopts = query[DHCP6OptOptReq].reqopts + for o, opt in six.iteritems(self.dhcpv6_options): + if o in reqopts: + answer /= opt + else: + # advertise everything we have available + # Should not happen has clients MUST include + # and ORO in requests (sec 18.1.1) -- arno + for o, opt in six.iteritems(self.dhcpv6_options): + answer /= opt + if msgtype == 1: # SOLICIT (See Sect 17.1 and 17.2 of RFC 3315) # XXX We don't support address or prefix assignment @@ -1741,16 +1760,7 @@ def make_reply(self, req): resp /= DHCP6OptClientId(duid=client_duid) resp /= DHCP6OptReconfAccept() - # See which options should be included - reqopts = [] - if p.haslayer(DHCP6OptOptReq): # add only asked ones - reqopts = p[DHCP6OptOptReq].reqopts - for o, opt in six.iteritems(self.dhcpv6_options): - if o in reqopts: - resp /= opt - else: # advertise everything we have available - for o, opt in six.iteritems(self.dhcpv6_options): - resp /= opt + _include_options(p, resp) return resp @@ -1762,19 +1772,7 @@ def make_reply(self, req): resp /= DHCP6OptServerId(duid=self.duid) resp /= DHCP6OptClientId(duid=client_duid) - # See which options should be included - reqopts = [] - if p.haslayer(DHCP6OptOptReq): # add only asked ones - reqopts = p[DHCP6OptOptReq].reqopts - for o, opt in six.iteritems(self.dhcpv6_options): - if o in reqopts: - resp /= opt - else: - # advertise everything we have available. - # Should not happen has clients MUST include - # and ORO in requests (sec 18.1.1) -- arno - for o, opt in six.iteritems(self.dhcpv6_options): - resp /= opt + _include_options(p, resp) return resp @@ -1859,9 +1857,6 @@ def make_reply(self, req): resp /= DHCP6OptClientId(duid=client_duid) # Stack requested options if available - reqopts = [] - if p.haslayer(DHCP6OptOptReq): - reqopts = p[DHCP6OptOptReq].reqopts for o, opt in six.iteritems(self.dhcpv6_options): resp /= opt diff --git a/scapy/layers/ppp.py b/scapy/layers/ppp.py index 269b9c5136c..b9180f572b6 100644 --- a/scapy/layers/ppp.py +++ b/scapy/layers/ppp.py @@ -353,48 +353,24 @@ class PPP_IPCP_Option_IPAddress(PPP_IPCP_Option): ] -class PPP_IPCP_Option_DNS1(PPP_IPCP_Option): +class PPP_IPCP_Option_DNS1(PPP_IPCP_Option_IPAddress): name = "PPP IPCP Option: DNS1 Address" - fields_desc = [ - ByteEnumField("type", 129, _PPP_ipcpopttypes), - FieldLenField("len", None, length_of="data", fmt="B", - adjust=lambda _, val: val + 2), - IPField("data", "0.0.0.0"), - StrLenField("garbage", "", length_from=lambda pkt: pkt.len - 6), - ] + type = 129 -class PPP_IPCP_Option_DNS2(PPP_IPCP_Option): +class PPP_IPCP_Option_DNS2(PPP_IPCP_Option_IPAddress): name = "PPP IPCP Option: DNS2 Address" - fields_desc = [ - ByteEnumField("type", 131, _PPP_ipcpopttypes), - FieldLenField("len", None, length_of="data", fmt="B", - adjust=lambda _, val: val + 2), - IPField("data", "0.0.0.0"), - StrLenField("garbage", "", length_from=lambda pkt: pkt.len - 6), - ] + type = 131 -class PPP_IPCP_Option_NBNS1(PPP_IPCP_Option): +class PPP_IPCP_Option_NBNS1(PPP_IPCP_Option_IPAddress): name = "PPP IPCP Option: NBNS1 Address" - fields_desc = [ - ByteEnumField("type", 130, _PPP_ipcpopttypes), - FieldLenField("len", None, length_of="data", fmt="B", - adjust=lambda _, val: val + 2), - IPField("data", "0.0.0.0"), - StrLenField("garbage", "", length_from=lambda pkt: pkt.len - 6), - ] + type = 130 -class PPP_IPCP_Option_NBNS2(PPP_IPCP_Option): +class PPP_IPCP_Option_NBNS2(PPP_IPCP_Option_IPAddress): name = "PPP IPCP Option: NBNS2 Address" - fields_desc = [ - ByteEnumField("type", 132, _PPP_ipcpopttypes), - FieldLenField("len", None, length_of="data", fmt="B", - adjust=lambda _, val: val + 2), - IPField("data", "0.0.0.0"), - StrLenField("garbage", "", length_from=lambda pkt: pkt.len - 6), - ] + type = 132 class PPP_IPCP(Packet): @@ -691,9 +667,9 @@ class PPP_LCP_Protocol_Reject(PPP_LCP): ] -class PPP_LCP_Echo(PPP_LCP): +class PPP_LCP_Discard_Request(PPP_LCP): fields_desc = [ - ByteEnumField("code", 9, _PPP_lcptypes), + ByteEnumField("code", 11, _PPP_lcptypes), XByteField("id", 0), FieldLenField("len", None, fmt="H", length_of="data", adjust=lambda _, val: val + 8), @@ -701,6 +677,10 @@ class PPP_LCP_Echo(PPP_LCP): StrLenField("data", "", length_from=lambda pkt: pkt.len - 8), ] + +class PPP_LCP_Echo(PPP_LCP_Discard_Request): + code = 9 + def answers(self, other): return ( isinstance(other, PPP_LCP_Echo) and self.code == 10 and @@ -708,16 +688,6 @@ def answers(self, other): ) -class PPP_LCP_Discard_Request(PPP_LCP): - fields_desc = [ - ByteEnumField("code", 11, _PPP_lcptypes), - XByteField("id", 0), - FieldLenField("len", None, fmt="H", length_of="data", - adjust=lambda _, val: val + 8), - IntField("magic_number", None), - StrLenField("data", "", length_from=lambda pkt: pkt.len - 8), - ] - # Password authentication protocol (RFC 1334) diff --git a/scapy/layers/sctp.py b/scapy/layers/sctp.py index 9646e00e56f..e6634b90c12 100644 --- a/scapy/layers/sctp.py +++ b/scapy/layers/sctp.py @@ -404,20 +404,8 @@ class SCTPChunkParamAddIPAddr(_SCTPChunkParam, Packet): lambda p: p.addr_type == 6), ] -class SCTPChunkParamDelIPAddr(_SCTPChunkParam, Packet): - fields_desc = [ShortEnumField("type", 0xc002, sctpchunkparamtypes), - FieldLenField("len", None, length_of="addr", - adjust=lambda pkt, x:x + 12), - XIntField("correlation_id", None), - ShortEnumField("addr_type", 5, sctpchunkparamtypes), - FieldLenField("addr_len", None, length_of="addr", - adjust=lambda pkt, x:x + 4), - ConditionalField( - IPField("addr", "127.0.0.1"), - lambda p: p.addr_type == 5), - ConditionalField( - IP6Field("addr", "::1"), - lambda p: p.addr_type == 6), ] +class SCTPChunkParamDelIPAddr(SCTPChunkParamAddIPAddr): + type = 0xc002 class SCTPChunkParamErrorIndication(_SCTPChunkParam, Packet): @@ -430,20 +418,8 @@ class SCTPChunkParamErrorIndication(_SCTPChunkParam, Packet): 4, padwith=b"\x00"), ] -class SCTPChunkParamSetPrimaryAddr(_SCTPChunkParam, Packet): - fields_desc = [ShortEnumField("type", 0xc004, sctpchunkparamtypes), - FieldLenField("len", None, length_of="addr", - adjust=lambda pkt, x:x + 12), - XIntField("correlation_id", None), - ShortEnumField("addr_type", 5, sctpchunkparamtypes), - FieldLenField("addr_len", None, length_of="addr", - adjust=lambda pkt, x:x + 4), - ConditionalField( - IPField("addr", "127.0.0.1"), - lambda p: p.addr_type == 5), - ConditionalField( - IP6Field("addr", "::1"), - lambda p: p.addr_type == 6), ] +class SCTPChunkParamSetPrimaryAddr(SCTPChunkParamAddIPAddr): + type = 0xc004 class SCTPChunkParamSuccessIndication(_SCTPChunkParam, Packet): @@ -554,17 +530,8 @@ class SCTPChunkInit(_SCTPChunkGuessPayload, Packet): ] -class SCTPChunkInitAck(_SCTPChunkGuessPayload, Packet): - fields_desc = [ByteEnumField("type", 2, sctpchunktypes), - XByteField("flags", None), - FieldLenField("len", None, length_of="params", adjust=lambda pkt, x:x + 20), # noqa: E501 - XIntField("init_tag", None), - IntField("a_rwnd", None), - ShortField("n_out_streams", None), - ShortField("n_in_streams", None), - XIntField("init_tsn", None), - ChunkParamField("params", None, length_from=lambda pkt:pkt.len - 20), # noqa: E501 - ] +class SCTPChunkInitAck(SCTPChunkInit): + type = 2 class GapAckField(Field): @@ -613,12 +580,8 @@ class SCTPChunkHeartbeatReq(_SCTPChunkGuessPayload, Packet): ] -class SCTPChunkHeartbeatAck(_SCTPChunkGuessPayload, Packet): - fields_desc = [ByteEnumField("type", 5, sctpchunktypes), - XByteField("flags", None), - FieldLenField("len", None, length_of="params", adjust=lambda pkt, x:x + 4), # noqa: E501 - ChunkParamField("params", None, length_from=lambda pkt:pkt.len - 4), # noqa: E501 - ] +class SCTPChunkHeartbeatAck(SCTPChunkHeartbeatReq): + type = 5 class SCTPChunkAbort(_SCTPChunkGuessPayload, Packet): @@ -655,7 +618,7 @@ class SCTPChunkError(_SCTPChunkGuessPayload, Packet): ] -class SCTPChunkCookieEcho(_SCTPChunkGuessPayload, Packet): +class SCTPChunkCookieEcho(SCTPChunkError): fields_desc = [ByteEnumField("type", 10, sctpchunktypes), XByteField("flags", None), FieldLenField("len", None, length_of="cookie", adjust=lambda pkt, x:x + 4), # noqa: E501 @@ -701,14 +664,8 @@ class SCTPChunkAddressConf(_SCTPChunkGuessPayload, Packet): ] -class SCTPChunkAddressConfAck(_SCTPChunkGuessPayload, Packet): - fields_desc = [ByteEnumField("type", 0x80, sctpchunktypes), - XByteField("flags", None), - FieldLenField("len", None, length_of="params", - adjust=lambda pkt, x:x + 8), - IntField("seq", 0), - ChunkParamField("params", None, length_from=lambda pkt:pkt.len - 8), # noqa: E501 - ] +class SCTPChunkAddressConfAck(SCTPChunkAddressConf): + type = 0x80 bind_layers(IP, SCTP, proto=IPPROTO_SCTP)