/usr/lib/python2.7/dist-packages/scapy/contrib/carp.py is in python-scapy 2.3.3-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | # scapy.contrib.description = CARP
# scapy.contrib.status = loads
import struct, hmac, hashlib
from scapy.packet import *
from scapy.layers.inet import IP
from scapy.fields import BitField, ByteField, XShortField, IntField, XIntField
from scapy.utils import checksum, inet_aton
class CARP(Packet):
name = "CARP"
fields_desc = [ BitField("version", 4, 4),
BitField("type", 4, 4),
ByteField("vhid", 1),
ByteField("advskew", 0),
ByteField("authlen", 0),
ByteField("demotion", 0),
ByteField("advbase", 0),
XShortField("chksum", 0),
XIntField("counter1", 0),
XIntField("counter2", 0),
XIntField("hmac1", 0),
XIntField("hmac2", 0),
XIntField("hmac3", 0),
XIntField("hmac4", 0),
XIntField("hmac5", 0)
]
def post_build(self, pkt, pay):
if self.chksum == None:
pkt = pkt[:6] + struct.pack("!H", checksum(pkt)) + pkt[8:]
return pkt
def build_hmac_sha1(pkt, pw = '\0' * 20, ip4l=None, ip6l=None):
if ip4l is None:
ip4l = []
if ip6l is None:
ip6l = []
if not pkt.haslayer(CARP):
return None
p = pkt[CARP]
h = hmac.new(pw, digestmod = hashlib.sha1)
# XXX: this is a dirty hack. it needs to pack version and type into a single 8bit field
h.update('\x21')
# XXX: mac addy if different from special link layer. comes before vhid
h.update(struct.pack('!B', p.vhid))
sl = []
for i in ip4l:
# sort ips from smallest to largest
sl.append(inet_aton(i))
sl.sort()
for i in sl:
h.update(i)
# XXX: do ip6l sorting
return h.digest()
"""
XXX: Usually CARP is multicast to 224.0.0.18 but because of virtual setup, it'll
be unicast between nodes. Uncomment the following line for normal use
bind_layers(IP, CARP, proto=112, dst='224.0.0.18')
"""
bind_layers(IP, CARP, proto=112)
|