google / gvisor

Application Kernel for Containers
https://gvisor.dev
Apache License 2.0
15.63k stars 1.29k forks source link

tcpdump support #173

Closed amscanne closed 3 years ago

kevinGC commented 4 years ago

Fixed by #731.

fvoznika commented 4 years ago

There are TODOs still referencing this bug.

ianlewis commented 4 years ago

related: #1409

hbhasker commented 4 years ago

Just documenting something i identified trying to get tcpdump working. Our RAW/AF_PACKET sockets are not populating the sockaddr_ll structure correctly, eg Protocol is missing and we don't seem to set the ha_type field correctly as well as Packet Type is always set to PACKET_HOST this needs to be different when we loop outbound packets etc to raw sockets. Today raw/af_packet sockets only see inbound packets and none of the outbound ones (that's another missing feature)

Address types The sockaddr_ll structure is a device-independent physical-layer address.

       struct sockaddr_ll {
           unsigned short sll_family;   /* Always AF_PACKET */
           unsigned short sll_protocol; /* Physical-layer protocol */
           int            sll_ifindex;  /* Interface number */
           unsigned short sll_hatype;   /* ARP hardware type */
           unsigned char  sll_pkttype;  /* Packet type */
           unsigned char  sll_halen;    /* Length of address */
           unsigned char  sll_addr[8];  /* Physical-layer address */
       };

   The fields of this structure are as follows:

   *  sll_protocol is the standard ethernet protocol type in network
      byte order as defined in the <linux/if_ether.h> include file.  It
      defaults to the socket's protocol.

   *  sll_ifindex is the interface index of the interface (see
      netdevice(7)); 0 matches any interface (only permitted for bind‐
      ing).  sll_hatype is an ARP type as defined in the
      <linux/if_arp.h> include file.

   *  sll_pkttype contains the packet type.  Valid types are PACKET_HOST
      for a packet addressed to the local host, PACKET_BROADCAST for a
      physical-layer broadcast packet, PACKET_MULTICAST for a packet
      sent to a physical-layer multicast address, PACKET_OTHERHOST for a
      packet to some other host that has been caught by a device driver
      in promiscuous mode, and PACKET_OUTGOING for a packet originating
      from the local host that is looped back to a packet socket.  These
      types make sense only for receiving.

   *  sll_addr and sll_halen contain the physical-layer (e.g., IEEE
      802.3) address and its length.  The exact interpretation depends
      on the device.
hbhasker commented 4 years ago

Here's the relevant ARP HA type values

https://github.com/torvalds/linux/blob/master/include/uapi/linux/if_arp.h#L30

hbhasker commented 4 years ago

In most cases what we want probably is https://github.com/torvalds/linux/blob/master/include/uapi/linux/if_arp.h#L30 to indicate ethernet.

hbhasker commented 4 years ago

Also missing is the Protocol field which seems rather complicated to get to because the endpoint.Read() returns a raw buffer.View and the only way to pass protocol back to be populated in sockaddr_ll will require changing Read() to either return a SockAddrLink in addition or change the signature to return something like PacketBuffer which will be significantly more complicated.

hbhasker commented 4 years ago

tcpdump now works in gVisor.

The following should work

tcpdump -i any & tcpdump -i -p

Promiscuous mode is not yet supported due to some missing features in our AF_PACKET implementation.

I am going to close this bug and open a new to add support for promiscuous mode. But that is a lot lower priority.

github-actions[bot] commented 4 years ago

There are TODOs still referencing this issue:

  1. pkg/tcpip/transport/packet/endpoint.go:196: Implement.
  2. pkg/tcpip/transport/packet/endpoint.go:237: Add Bind support.
  3. pkg/tcpip/transport/packet/endpoint.go:435: Return network protocol.
  4. pkg/sentry/socket/netstack/netstack.go:426: Return protocol too.
  5. pkg/sentry/socket/netstack/netstack.go:2438: Return protocol too.
  6. test/syscalls/linux/packet_socket.cc:58: gVisor support.
  7. test/syscalls/linux/packet_socket.cc:191: Verify protocol once we return it.
  8. test/syscalls/linux/packet_socket.cc:237: Remove once we support packet socket writing.
  9. test/syscalls/linux/packet_socket_raw.cc:61: gVisor support.
  10. test/syscalls/linux/packet_socket_raw.cc:198: Verify protocol once we return it.
  11. test/syscalls/linux/packet_socket_raw.cc:243: Remove once we support packet socket writing.

Search TODO