diff --git a/lib/ethif.ml b/lib/ethif.ml index 8bfd43bbd..59c822356 100644 --- a/lib/ethif.ml +++ b/lib/ethif.ml @@ -21,7 +21,6 @@ module Make(Netif : V1_LWT.NETWORK) = struct type 'a io = 'a Lwt.t type buffer = Cstruct.t - type ipv4addr = Ipaddr.V4.t type macaddr = Macaddr.t type netif = Netif.t @@ -40,25 +39,19 @@ module Make(Netif : V1_LWT.NETWORK) = struct let input ~arpv4 ~ipv4 ~ipv6 t frame = MProf.Trace.label "ethif.input"; - let frame_mac = Macaddr.of_bytes (Wire_structs.copy_ethernet_dst frame) in - match frame_mac with - | None -> Lwt.return_unit - | Some frame_mac -> - if Macaddr.compare frame_mac (mac t) = 0 - || not (Macaddr.is_unicast frame_mac) - then match Wire_structs.get_ethernet_ethertype frame with - | 0x0806 -> arpv4 frame (* ARP *) - | 0x0800 -> (* IPv4 *) - let payload = Cstruct.shift frame Wire_structs.sizeof_ethernet in - ipv4 payload - | 0x86dd -> - let payload = Cstruct.shift frame Wire_structs.sizeof_ethernet in - ipv6 payload - | _etype -> - let _payload = Cstruct.shift frame Wire_structs.sizeof_ethernet in - (* TODO default etype payload *) - Lwt.return_unit - else Lwt.return_unit + let of_interest dest = + Macaddr.compare dest (mac t) = 0 || not (Macaddr.is_unicast dest) + in + match Wire_structs.parse_ethernet_frame frame with + | Some (typ, destination, payload) when of_interest destination -> + begin + match typ with + | Some Wire_structs.ARP -> arpv4 frame + | Some Wire_structs.IPv4 -> ipv4 payload + | Some Wire_structs.IPv6 -> ipv6 payload + | None -> Lwt.return_unit (* TODO: default ethertype payload handler *) + end + | _ -> Lwt.return_unit let write t frame = MProf.Trace.label "ethif.write"; diff --git a/lib/wire_structs.ml b/lib/wire_structs.ml index f594e2164..0223e8911 100644 --- a/lib/wire_structs.ml +++ b/lib/wire_structs.ml @@ -4,6 +4,24 @@ cstruct ethernet { uint16_t ethertype } as big_endian +cenum ethertype { + ARP = 0x0806; + IPv4 = 0x0800; + IPv6 = 0x86dd; + } as uint16_t + +let parse_ethernet_frame frame = + if Cstruct.len frame >= 14 then + (* source + destination + type = 14 *) + let payload = Cstruct.shift frame sizeof_ethernet + and typ = get_ethernet_ethertype frame + and dst = Macaddr.of_bytes_exn (copy_ethernet_dst frame) + in + Some (int_to_ethertype typ, dst, payload) + else + None + + cstruct udp { uint16_t source_port; uint16_t dest_port;