blob: 4844862eded15c4e691141db7f0b63ca26ae3ac8 [file] [log] [blame]
# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import dpkt
import socket
from lansim import tools
class SimpleHost(object):
"""A simple host supporting IPv4.
This class is useful as a base clase to implement other hosts. It supports
a single IPv4 address.
"""
def __init__(self, sim, hw_addr, ip_addr):
"""Creates the host and associates it with the given NetworkBridge.
@param sim: The Simulator interface where this host lives.
@param hw_addr: Hex or binary representation of the Ethernet address.
@param ip_addr: The IPv4 address. For example: "10.0.0.1".
"""
self._sim = sim
self._hw_addr = hw_addr
self._ip_addr = ip_addr
self._bin_hw_addr = tools.inet_hwton(hw_addr)
self._bin_ip_addr = socket.inet_aton(ip_addr)
# Reply to broadcast ARP requests.
rule = {
"dst": "\xff" * 6, # Broadcast HW addr.
"arp.pln": 4, # Protocol Addres Length is 4 (IP v4).
"arp.op": dpkt.arp.ARP_OP_REQUEST,
"arp.tpa": self._bin_ip_addr}
sim.add_match(rule, self.arp_request)
# Reply to unicast ARP requests.
rule["dst"] = self._bin_hw_addr
sim.add_match(rule, self.arp_request)
def arp_request(self, pkt):
"""Sends the ARP_REPLY matching the request.
@param pkt: a dpkt.Packet with the ARP_REQUEST.
"""
arp_resp = dpkt.arp.ARP(
op = dpkt.arp.ARP_OP_REPLY,
pln = 4,
tpa = pkt.arp.spa, # Target Protocol Address.
tha = pkt.arp.sha, # Target Hardware Address.
spa = self._bin_ip_addr, # Source Protocol Address.
sha = self._bin_hw_addr) # Source Hardware Address.
eth_resp = dpkt.ethernet.Ethernet(
dst = pkt.arp.sha,
src = self._bin_hw_addr,
type = dpkt.ethernet.ETH_TYPE_ARP,
data = arp_resp)
self._sim.write(eth_resp)