Mini Shell
import json
import select
import sys
from pyroute2.dhcp import (
BOOTREQUEST,
DHCPACK,
DHCPDISCOVER,
DHCPOFFER,
DHCPREQUEST,
)
from pyroute2.dhcp.dhcp4msg import dhcp4msg
from pyroute2.dhcp.dhcp4socket import DHCP4Socket
def req(s, poll, msg, expect):
do_req = True
xid = None
while True:
# get transaction id
if do_req:
xid = s.put(msg)['xid']
# wait for response
events = poll.poll(2)
for fd, event in events:
response = s.get()
if response['xid'] != xid:
do_req = False
continue
if response['options']['message_type'] != expect:
raise Exception("DHCP protocol error")
return response
do_req = True
def action(ifname):
s = DHCP4Socket(ifname)
poll = select.poll()
poll.register(s, select.POLLIN | select.POLLPRI)
# DISCOVER
discover = dhcp4msg(
{
'op': BOOTREQUEST,
'chaddr': s.l2addr,
'options': {
'message_type': DHCPDISCOVER,
'parameter_list': [1, 3, 6, 12, 15, 28],
},
}
)
reply = req(s, poll, discover, expect=DHCPOFFER)
# REQUEST
request = dhcp4msg(
{
'op': BOOTREQUEST,
'chaddr': s.l2addr,
'options': {
'message_type': DHCPREQUEST,
'requested_ip': reply['yiaddr'],
'server_id': reply['options']['server_id'],
'parameter_list': [1, 3, 6, 12, 15, 28],
},
}
)
reply = req(s, poll, request, expect=DHCPACK)
s.close()
return reply
def run():
if len(sys.argv) > 1:
ifname = sys.argv[1]
else:
ifname = 'eth0'
print(json.dumps(action(ifname), indent=4))
if __name__ == '__main__':
run()
Zerion Mini Shell 1.0