123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- """Dynamic Host Configuration Protocol."""
- from pypacker import pypacker, triggerlist
- from pypacker.layer12 import arp
- import logging
- logger = logging.getLogger("pypacker")
- DHCP_OP_REQUEST = 1
- DHCP_OP_REPLY = 2
- DHCP_MAGIC = 0x63825363
- # DHCP option codes
- DHCP_OPT_NETMASK = 1 # I: subnet mask
- DHCP_OPT_TIMEOFFSET = 2
- DHCP_OPT_ROUTER = 3 # s: list of router ips
- DHCP_OPT_TIMESERVER = 4
- DHCP_OPT_NAMESERVER = 5
- DHCP_OPT_DNS_SVRS = 6 # s: list of DNS servers
- DHCP_OPT_LOGSERV = 7
- DHCP_OPT_COOKIESERV = 8
- DHCP_OPT_LPRSERV = 9
- DHCP_OPT_IMPSERV = 10
- DHCP_OPT_RESSERV = 11
- DHCP_OPT_HOSTNAME = 12 # s: client hostname
- DHCP_OPT_BOOTFILESIZE = 13
- DHCP_OPT_DUMPFILE = 14
- DHCP_OPT_DOMAIN = 15 # s: domain name
- DHCP_OPT_SWAPSERV = 16
- DHCP_OPT_ROOTPATH = 17
- DHCP_OPT_EXTENPATH = 18
- DHCP_OPT_IPFORWARD = 19
- DHCP_OPT_SRCROUTE = 20
- DHCP_OPT_POLICYFILTER = 21
- DHCP_OPT_MAXASMSIZE = 22
- DHCP_OPT_IPTTL = 23
- DHCP_OPT_MTUTIMEOUT = 24
- DHCP_OPT_MTUTABLE = 25
- DHCP_OPT_MTUSIZE = 26
- DHCP_OPT_LOCALSUBNETS = 27
- DHCP_OPT_BROADCASTADDR = 28
- DHCP_OPT_DOMASKDISCOV = 29
- DHCP_OPT_MASKSUPPLY = 30
- DHCP_OPT_DOROUTEDISC = 31
- DHCP_OPT_ROUTERSOLICIT = 32
- DHCP_OPT_STATICROUTE = 33
- DHCP_OPT_TRAILERENCAP = 34
- DHCP_OPT_ARPTIMEOUT = 35
- DHCP_OPT_ETHERENCAP = 36
- DHCP_OPT_TCPTTL = 37
- DHCP_OPT_TCPKEEPALIVE = 38
- DHCP_OPT_TCPALIVEGARBAGE = 39
- DHCP_OPT_NISDOMAIN = 40
- DHCP_OPT_NISSERVERS = 41
- DHCP_OPT_NISTIMESERV = 42
- DHCP_OPT_VENDSPECIFIC = 43
- DHCP_OPT_NBNS = 44
- DHCP_OPT_NBDD = 45
- DHCP_OPT_NBTCPIP = 46
- DHCP_OPT_NBTCPSCOPE = 47
- DHCP_OPT_XFONT = 48
- DHCP_OPT_XDISPLAYMGR = 49
- DHCP_OPT_REQ_IP = 50 # I: IP address
- DHCP_OPT_LEASE_SEC = 51 # I: lease seconds
- DHCP_OPT_OPTIONOVERLOAD = 52
- DHCP_OPT_MSGTYPE = 53 # B: message type
- DHCP_OPT_SERVER_ID = 54 # I: server IP address
- DHCP_OPT_PARAM_REQ = 55 # s: list of option codes
- DHCP_OPT_MESSAGE = 56
- DHCP_OPT_MAXMSGSIZE = 57
- DHCP_OPT_RENEWTIME = 58
- DHCP_OPT_REBINDTIME = 59
- DHCP_OPT_VENDOR_ID = 60 # s: vendor class id
- DHCP_OPT_CLIENT_ID = 61 # Bs: idtype, id (idtype 0: FQDN, idtype 1: M
- DHCP_OPT_NISPLUSDOMAIN = 64
- DHCP_OPT_NISPLUSSERVERS = 65
- DHCP_OPT_MOBILEIPAGENT = 68
- DHCP_OPT_SMTPSERVER = 69
- DHCP_OPT_POP3SERVER = 70
- DHCP_OPT_NNTPSERVER = 71
- DHCP_OPT_WWWSERVER = 72
- DHCP_OPT_FINGERSERVER = 73
- DHCP_OPT_IRCSERVER = 74
- DHCP_OPT_STSERVER = 75
- DHCP_OPT_STDASERVER = 76
- # DHCP message type values
- DHCPDISCOVER = 1
- DHCPOFFER = 2
- DHCPREQUEST = 3
- DHCPDECLINE = 4
- DHCPACK = 5
- DHCPNAK = 6
- DHCPRELEASE = 7
- DHCPINFORM = 8
- class DHCP(pypacker.Packet):
- __hdr__ = (
- ("op", "B", DHCP_OP_REQUEST),
- ("hrd", "B", arp.ARP_HRD_ETH), # just like ARP.hrd
- ("hln", "B", 6), # and ARP.hln
- ("hops", "B", 0),
- ("xid", "I", 0xdeadbeef),
- ("secs", "H", 0),
- ("flags", "H", 0),
- ("ciaddr", "I", 0),
- ("yiaddr", "I", 0),
- ("siaddr", "I", 0),
- ("giaddr", "I", 0),
- # MAC + padding
- ("chaddr", "16s", b"\x00" * 6 + b"\x00" * 10),
- ("sname", "64s", b"\x00" * 64),
- ("file", "128s", b"\x00" * 128),
- ("magic", "I", DHCP_MAGIC),
- ("opts", None, triggerlist.TriggerList)
- )
- """
- opts = (
- (DHCP_OPT_MSGTYPE, chr(DHCPDISCOVER)),
- (DHCP_OPT_PARAM_REQ, "".join(map(chr, (DHCP_OPT_REQ_IP,
- DHCP_OPT_ROUTER,
- DHCP_OPT_NETMASK,
- DHCP_OPT_DNS_SVRS))))
- ) # list of (type, data) tuples
- """
- def _dissect(self, buf):
- # logger.debug("DHCP: parsing options, buflen: %d" % len(buf))
- self._init_triggerlist("opts", buf[28 + 16 + 64 + 128 + 4:], self.__get_opts)
- # logger.debug(buf[28+16+64+128+4:])
- # logger.debug("amount of options after parsing: %d" % len(self.opts))
- return len(buf)
- def __get_opts(self, buf):
- # logger.debug("DHCP: parsing options from: %s" % buf)
- opts = []
- i = 0
- while i < len(buf):
- t = buf[i]
- p = None
- # logger.debug("DHCP: adding option type %d" % t)
- # last option
- if t in [0, 0xff]:
- p = DHCPOptSingle(type=t)
- i += 1
- else:
- dlen = buf[i + 1]
- p = DHCPOptMulti(type=t, len=dlen, body_bytes=buf[i + 2: i + 2 + dlen])
- i += 2 + dlen
- # logger.debug("new option: %s" % p)
- opts.append(p)
- if t == 0xff:
- if i < len(buf):
- # padding is part of the options
- opts.append(Padding(buf[i:]))
- break
- return opts
- class DHCPOptSingle(pypacker.Packet):
- __hdr__ = (
- ("type", "B", 0),
- )
- class DHCPOptMulti(pypacker.Packet):
- __hdr__ = (
- ("type", "B", 0),
- ("len", "B", 0),
- )
- class Padding(pypacker.Packet):
- pass
|