diff --git a/gtests/net/packetdrill/checksum.c b/gtests/net/packetdrill/checksum.c
index da19714f0da387577c877a830fb91946d814f0e1..b37dc00b95c1f6b754ff4cb4847055388da0b8b1 100644
--- a/gtests/net/packetdrill/checksum.c
+++ b/gtests/net/packetdrill/checksum.c
@@ -32,11 +32,8 @@
  */
 static u64 ip_checksum_partial(const void *p, size_t len, u64 sum)
 {
-	/* Main loop: 32 bits at a time.
-	 * We take advantage of intel's ability to do unaligned memory
-	 * accesses with minimal additional cost. Other architectures
-	 * probably want to be more careful here.
-	 */
+	assert(((uintptr_t)p & 0x03) == 0);
+	/* Main loop: 32 bits at a time. */
 	const u32 *p32 = (const u32 *)(p);
 	for (; len >= sizeof(*p32); len -= sizeof(*p32))
 		sum += *p32++;
diff --git a/gtests/net/packetdrill/checksum_test.c b/gtests/net/packetdrill/checksum_test.c
index e080163caf4bc658219996a0aeac28b5b2f81c06..55ac51e29d5398e491a358e57ef7ab627f16406a 100644
--- a/gtests/net/packetdrill/checksum_test.c
+++ b/gtests/net/packetdrill/checksum_test.c
@@ -33,7 +33,7 @@
 
 static void test_tcp_udp_v4_checksum(void)
 {
-	u8 data[] = {
+	u8 data[] __aligned(4) = {
 		0x45, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00,
 		0xff, 0x06, 0xf9, 0x10, 0x01, 0x01, 0x01, 0x01,
 		0xc0, 0xa8, 0x00, 0x01, 0x04, 0xd2, 0xeb, 0x35,
@@ -64,7 +64,7 @@ static void test_tcp_udp_v4_checksum(void)
 
 static void test_tcp_udp_v6_checksum(void)
 {
-	u8 data[] = {
+	u8 data[] __aligned(4) = {
 		0x60, 0x00, 0x00, 0x00, 0x00, 0x20, 0x06, 0xff,
 		0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00,
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
@@ -97,7 +97,7 @@ static void test_tcp_udp_v6_checksum(void)
 
 static void test_ipv4_checksum(void)
 {
-	u8 data[] = {
+	u8 data[] __aligned(4) = {
 		0x45, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00,
 		0xff, 0x06, 0xf9, 0x10, 0x01, 0x01, 0x01, 0x01,
 		0xc0, 0xa8, 0x00, 0x01,
@@ -115,7 +115,7 @@ static void test_ipv4_checksum(void)
 
 static void test_sctp_crc32c(void)
 {
-	u8 data[] = {
+	u8 data[] __aligned(4) = {
 		0x07, 0xd0, 0xd6, 0x61, 0x11, 0x0c, 0xc5, 0x6c,
 		0xda, 0xd7, 0x37, 0x74, 0x06, 0x00, 0x00, 0x0f,
 		0x00, 0x0c, 0x00, 0x0b, 0x47, 0x6f, 0x6f, 0x64,
diff --git a/gtests/net/packetdrill/netdev.c b/gtests/net/packetdrill/netdev.c
index aeca2da0e642694fb35bda441603298eb6526d20..c6e36fcb1f5a82f7dccc2108d77114b1979e0301 100644
--- a/gtests/net/packetdrill/netdev.c
+++ b/gtests/net/packetdrill/netdev.c
@@ -399,20 +399,20 @@ static int local_netdev_receive(struct netdev *a_netdev,
 
 	DEBUGP("local_netdev_receive\n");
 
-	status = netdev_receive_loop(netdev->psock, PACKET_LAYER_3_IP,
-				     DIRECTION_OUTBOUND, packet, &num_packets,
-				     error);
+	status = netdev_receive_loop(netdev->psock, DIRECTION_OUTBOUND, packet,
+				     &num_packets, error);
 	local_netdev_read_queue(netdev, num_packets);
 	return status;
 }
 
 int netdev_receive_loop(struct packet_socket *psock,
-			enum packet_layer_t layer,
 			enum direction_t direction,
 			struct packet **packet,
 			int *num_packets,
 			char **error)
 {
+	u16 ether_type;
+
 	assert(*packet == NULL);	/* should be no packet yet */
 
 	*num_packets = 0;
@@ -423,11 +423,12 @@ int netdev_receive_loop(struct packet_socket *psock,
 		*packet = packet_new(PACKET_READ_BYTES);
 
 		/* Sniff the next outbound packet from the kernel under test. */
-		if (packet_socket_receive(psock, direction, *packet, &in_bytes))
+		if (packet_socket_receive(psock, direction, &ether_type,
+					  *packet, &in_bytes))
 			continue;
 
 		++*num_packets;
-		result = parse_packet(*packet, in_bytes, layer, error);
+		result = parse_packet(*packet, in_bytes, ether_type, error);
 
 		if (result == PACKET_OK)
 			return STATUS_OK;
diff --git a/gtests/net/packetdrill/netdev.h b/gtests/net/packetdrill/netdev.h
index c69c1384e82d0a19a6570ef8e0c7737552ef41a7..115c3453edff6e002323ea824fd4ed891bcbad5b 100644
--- a/gtests/net/packetdrill/netdev.h
+++ b/gtests/net/packetdrill/netdev.h
@@ -87,7 +87,6 @@ static inline int netdev_receive(struct netdev *netdev,
  * packet. Caller must free the packet with packet_free().
  */
 extern int netdev_receive_loop(struct packet_socket *psock,
-			       enum packet_layer_t layer,
 			       enum direction_t direction,
 			       struct packet **packet,
 			       int *num_packets,
diff --git a/gtests/net/packetdrill/packet.c b/gtests/net/packetdrill/packet.c
index b1810ff1a9b5f3c290977800cde316b6e457689a..c52bb14392420bb92cce00bf91595676ab23fe6d 100644
--- a/gtests/net/packetdrill/packet.c
+++ b/gtests/net/packetdrill/packet.c
@@ -102,7 +102,6 @@ struct header *packet_append_header(struct packet *packet,
 {
 	struct header *header = NULL;
 	int num_headers = packet_header_count(packet);
-	int packet_bytes;
 
 	assert(num_headers <= PACKET_MAX_HEADERS);
 	if (num_headers == PACKET_MAX_HEADERS)
@@ -112,8 +111,7 @@ struct header *packet_append_header(struct packet *packet,
 
 	if (packet->ip_bytes + header_bytes > packet->buffer_bytes)
 		return NULL;
-	packet_bytes = packet->l2_header_bytes + packet->ip_bytes;
-	header->h.ptr = packet->buffer + packet_bytes;
+	header->h.ptr = packet->buffer + packet->ip_bytes;
 	packet->ip_bytes += header_bytes;
 
 	header->type = header_type;
diff --git a/gtests/net/packetdrill/packet.h b/gtests/net/packetdrill/packet.h
index 83869bcfae03f205ec5876f41bf208768f8ff642..fd4a50ceb9ec1c166e72fb8bf19baaf59ab4f6ad 100644
--- a/gtests/net/packetdrill/packet.h
+++ b/gtests/net/packetdrill/packet.h
@@ -69,7 +69,6 @@ static const int PACKET_READ_BYTES = 64 * 1024;
 struct packet {
 	u8 *buffer;		/* data buffer: full contents of packet */
 	u32 buffer_bytes;	/* bytes of space in data buffer */
-	u32 l2_header_bytes;	/* bytes in outer hardware/layer-2 header */
 	u32 ip_bytes;		/* bytes in outermost IP hdrs/payload */
 	enum direction_t direction;	/* direction packet is traveling */
 
diff --git a/gtests/net/packetdrill/packet_parser.c b/gtests/net/packetdrill/packet_parser.c
index 0c95a70284e219ecf9e1f4056e19705377d29f5f..b1acd3feddc66ecf9766bbf50c7c42762fb1f37b 100644
--- a/gtests/net/packetdrill/packet_parser.c
+++ b/gtests/net/packetdrill/packet_parser.c
@@ -57,29 +57,6 @@ static int parse_layer4(struct packet *packet, u8 *header_start,
 			int layer4_protocol, int layer4_bytes,
 			u8 *packet_end, bool *is_inner, char **error);
 
-static int parse_layer2_packet(struct packet *packet,
-			       u8 *header_start, u8 *packet_end,
-			       char **error)
-{
-	u8 *p = header_start;
-	struct ether_header *ether = NULL;
-
-	/* Find Ethernet header */
-	if (p + sizeof(*ether) > packet_end) {
-		asprintf(error, "Ethernet header overflows packet");
-		goto error_out;
-	}
-	ether = (struct ether_header *)p;
-	p += sizeof(*ether);
-	packet->l2_header_bytes = sizeof(*ether);
-
-	return parse_layer3_packet_by_proto(packet, ntohs(ether->ether_type),
-					    p, packet_end, error);
-
-error_out:
-	return PACKET_BAD;
-}
-
 static int parse_layer3_packet_by_proto(struct packet *packet,
 					u16 proto, u8 *header_start,
 					u8 *packet_end, char **error)
@@ -163,7 +140,7 @@ static int parse_layer3_packet(struct packet *packet,
 }
 
 int parse_packet(struct packet *packet, int in_bytes,
-			 enum packet_layer_t layer, char **error)
+		 u16 ether_type, char **error)
 {
 	assert(in_bytes <= packet->buffer_bytes);
 	char *message = NULL;		/* human-readable error summary */
@@ -173,14 +150,8 @@ int parse_packet(struct packet *packet, int in_bytes,
 	/* packet_end points to the byte beyond the end of packet. */
 	u8 *packet_end = packet->buffer + in_bytes;
 
-	if (layer == PACKET_LAYER_2_ETHERNET)
-		result = parse_layer2_packet(packet, header_start, packet_end,
-					     error);
-	else if (layer == PACKET_LAYER_3_IP)
-		result = parse_layer3_packet(packet, header_start, packet_end,
-					     error);
-	else
-		assert(!"bad layer");
+	result = parse_layer3_packet_by_proto(packet, ether_type,
+					      header_start, packet_end, error);
 
 	if (result != PACKET_BAD)
 		return result;
diff --git a/gtests/net/packetdrill/packet_parser.h b/gtests/net/packetdrill/packet_parser.h
index 8bd651265e70d4b3c1422ba658fbe7dbc6ca3365..160be514094ecc2e3bfafe1ad0fb5272fb6df9e8 100644
--- a/gtests/net/packetdrill/packet_parser.h
+++ b/gtests/net/packetdrill/packet_parser.h
@@ -27,12 +27,6 @@
 
 #include "packet.h"
 
-/* What layer of headers is at the head of the packet? */
-enum packet_layer_t {
-	PACKET_LAYER_3_IP = 0,		/* no layer 2 headers */
-	PACKET_LAYER_2_ETHERNET,	/* layer 2 is Ethernet */
-};
-
 enum packet_parse_result_t {
 	PACKET_OK,		/* no errors detected */
 	PACKET_BAD,		/* illegal header */
@@ -48,6 +42,6 @@ enum packet_parse_result_t {
  * error message.
  */
 int parse_packet(struct packet *packet, int in_bytes,
-		 enum packet_layer_t layer, char **error);
+		 u16 ether_type, char **error);
 
 #endif /* __PACKET_PARSER_H__ */
diff --git a/gtests/net/packetdrill/packet_parser_test.c b/gtests/net/packetdrill/packet_parser_test.c
index 3aae4e3df0d598346839ef9279e4bd5bdad01a14..c2545e7d62726b76eae3a0148660503042ea2153 100644
--- a/gtests/net/packetdrill/packet_parser_test.c
+++ b/gtests/net/packetdrill/packet_parser_test.c
@@ -22,6 +22,7 @@
  * Test for parsing IP packets.
  */
 
+#include "ethernet.h"
 #include "packet_parser.h"
 
 #include <assert.h>
@@ -52,7 +53,7 @@ static void test_parse_tcp_ipv4_packet(void)
 	memcpy(packet->buffer, data, sizeof(data));
 	char *error = NULL;
 	enum packet_parse_result_t result =
-		parse_packet(packet, sizeof(data), PACKET_LAYER_3_IP,
+		parse_packet(packet, sizeof(data), ETHERTYPE_IP,
 				     &error);
 	assert(result == PACKET_OK);
 	assert(error == NULL);
@@ -99,7 +100,7 @@ static void test_parse_tcp_ipv6_packet(void)
 	memcpy(packet->buffer, data, sizeof(data));
 	char *error = NULL;
 	enum packet_parse_result_t result =
-		parse_packet(packet, sizeof(data), PACKET_LAYER_3_IP,
+		parse_packet(packet, sizeof(data), ETHERTYPE_IPV6,
 				     &error);
 	assert(result == PACKET_OK);
 	assert(error == NULL);
@@ -139,7 +140,7 @@ static void test_parse_udp_ipv4_packet(void)
 	memcpy(packet->buffer, data, sizeof(data));
 	char *error = NULL;
 	enum packet_parse_result_t result =
-		parse_packet(packet, sizeof(data), PACKET_LAYER_3_IP,
+		parse_packet(packet, sizeof(data), ETHERTYPE_IP,
 				     &error);
 	assert(result == PACKET_OK);
 	assert(error == NULL);
@@ -183,7 +184,7 @@ static void test_parse_udp_ipv6_packet(void)
 	memcpy(packet->buffer, data, sizeof(data));
 	char *error = NULL;
 	enum packet_parse_result_t result =
-		parse_packet(packet, sizeof(data), PACKET_LAYER_3_IP,
+		parse_packet(packet, sizeof(data), ETHERTYPE_IPV6,
 				     &error);
 	assert(result == PACKET_OK);
 	assert(error == NULL);
@@ -233,7 +234,7 @@ static void test_parse_ipv4_gre_ipv4_tcp_packet(void)
 	memcpy(packet->buffer, data, sizeof(data));
 	char *error = NULL;
 	enum packet_parse_result_t result =
-		parse_packet(packet, sizeof(data), PACKET_LAYER_3_IP,
+		parse_packet(packet, sizeof(data), ETHERTYPE_IP,
 				     &error);
 	assert(result == PACKET_OK);
 	assert(error == NULL);
@@ -324,7 +325,7 @@ static void test_parse_ipv4_gre_mpls_ipv4_tcp_packet(void)
 	memcpy(packet->buffer, data, sizeof(data));
 	char *error = NULL;
 	enum packet_parse_result_t result =
-		parse_packet(packet, sizeof(data), PACKET_LAYER_3_IP,
+		parse_packet(packet, sizeof(data), ETHERTYPE_IP,
 				     &error);
 	assert(result == PACKET_OK);
 	assert(error == NULL);
@@ -401,7 +402,7 @@ static void test_parse_icmpv4_packet(void)
 	memcpy(packet->buffer, data, sizeof(data));
 	char *error = NULL;
 	enum packet_parse_result_t result =
-		parse_packet(packet, sizeof(data), PACKET_LAYER_3_IP,
+		parse_packet(packet, sizeof(data), ETHERTYPE_IP,
 				     &error);
 	assert(result == PACKET_OK);
 	assert(error == NULL);
@@ -454,7 +455,7 @@ static void test_parse_icmpv6_packet(void)
 	memcpy(packet->buffer, data, sizeof(data));
 	char *error = NULL;
 	enum packet_parse_result_t result =
-		parse_packet(packet, sizeof(data), PACKET_LAYER_3_IP,
+		parse_packet(packet, sizeof(data), ETHERTYPE_IPV6,
 				     &error);
 	assert(result == PACKET_OK);
 	assert(error == NULL);
diff --git a/gtests/net/packetdrill/packet_socket.h b/gtests/net/packetdrill/packet_socket.h
index a2defd39f74052be7dc801a084744d23a8f519d9..769378c5d62ebbae1d1d4eb35f64dca3125312e7 100644
--- a/gtests/net/packetdrill/packet_socket.h
+++ b/gtests/net/packetdrill/packet_socket.h
@@ -63,7 +63,7 @@ extern int packet_socket_writev(struct packet_socket *psock,
  * retry).
  */
 extern int packet_socket_receive(struct packet_socket *psock,
-				 enum direction_t direction,
+				 enum direction_t direction, u16 *ether_type,
 				 struct packet *packet, int *in_bytes);
 
 #endif /* __PACKET_SOCKET_H__ */
diff --git a/gtests/net/packetdrill/packet_socket_linux.c b/gtests/net/packetdrill/packet_socket_linux.c
index 4e889972d5a67846d9f9ceafd924458257af5f4b..95e852bdf23158cf0bf8a74fdb3cced05e735f72 100644
--- a/gtests/net/packetdrill/packet_socket_linux.c
+++ b/gtests/net/packetdrill/packet_socket_linux.c
@@ -48,6 +48,7 @@ struct packet_socket {
 	int packet_fd;	/* socket for sending, sniffing timestamped packets */
 	char *name;	/* malloc-allocated copy of interface name */
 	int index;	/* interface index from if_nametoindex */
+	bool trim_ethernet_header;
 };
 
 /* Set the receive buffer for a socket to the given size in bytes. */
@@ -178,6 +179,8 @@ void packet_socket_set_filter(struct packet_socket *psock,
 		       &bpfcode, sizeof(bpfcode)) < 0) {
 		die_perror("setsockopt SOL_SOCKET, SO_ATTACH_FILTER");
 	}
+
+	psock->trim_ethernet_header = true;
 }
 
 struct packet_socket *packet_socket_new(const char *device_name)
@@ -186,6 +189,7 @@ struct packet_socket *packet_socket_new(const char *device_name)
 
 	psock->name = strdup(device_name);
 	psock->packet_fd = -1;
+	psock->trim_ethernet_header = false;
 
 	packet_socket_setup(psock);
 
@@ -215,18 +219,39 @@ int packet_socket_writev(struct packet_socket *psock,
 }
 
 int packet_socket_receive(struct packet_socket *psock,
-			  enum direction_t direction,
+			  enum direction_t direction, u16 *ether_type,
 			  struct packet *packet, int *in_bytes)
 {
 	struct sockaddr_ll from;
-	memset(&from, 0, sizeof(from));
-	socklen_t from_len = sizeof(from);
+	struct ether_header ether;
+	struct iovec iov[2];
+	struct msghdr msg;
 
 	/* Read the packet out of our kernel packet socket buffer. */
-	*in_bytes = recvfrom(psock->packet_fd,
-			     packet->buffer, packet->buffer_bytes, 0,
-			     (struct sockaddr *)&from, &from_len);
-	assert(*in_bytes <= packet->buffer_bytes);
+	memset(&from, 0, sizeof(from));
+	if (psock->trim_ethernet_header) {
+		iov[0].iov_base = &ether;
+		iov[0].iov_len = sizeof(struct ether_header);
+		iov[1].iov_base = packet->buffer;
+		iov[1].iov_len = packet->buffer_bytes;
+	} else {
+		iov[0].iov_base = packet->buffer;
+		iov[0].iov_len = packet->buffer_bytes;
+	}
+	msg.msg_name = &from;
+	msg.msg_namelen = (socklen_t)sizeof(struct sockaddr_ll);
+	msg.msg_iov = iov;
+	msg.msg_iovlen = (psock->trim_ethernet_header == 1) ? 2 : 1;
+	msg.msg_control = NULL;
+	msg.msg_controllen = 0;
+	msg.msg_flags = 0;
+	*in_bytes = recvmsg(psock->packet_fd, &msg, 0);
+
+	if (psock->trim_ethernet_header)
+		assert(*in_bytes <=
+		       packet->buffer_bytes + sizeof(struct ether_header));
+	else
+		assert(*in_bytes <= packet->buffer_bytes);
 	if (*in_bytes < 0) {
 		if (errno == EINTR) {
 			DEBUGP("EINTR\n");
@@ -267,6 +292,19 @@ int packet_socket_receive(struct packet_socket *psock,
 	       (u32)tv.tv_sec, (u32)tv.tv_usec,
 	       packet->time_usecs);
 
+	DEBUGP("reported sll_protocol = 0x%04x\n", ntohs(from.sll_protocol));
+	if (psock->trim_ethernet_header) {
+		if (*in_bytes < sizeof(struct ether_header)) {
+			DEBUGP("packet does not contain ethernet header\n");
+			return STATUS_ERR;
+		} else {
+			*ether_type = ntohs(ether.ether_type);
+			*in_bytes -= sizeof(struct ether_header);
+		}
+	} else {
+		*ether_type = ntohs(from.sll_protocol);
+	}
+	DEBUGP("ether_type is 0x%04x\n", *ether_type);
 	return STATUS_OK;
 }
 
diff --git a/gtests/net/packetdrill/packet_socket_pcap.c b/gtests/net/packetdrill/packet_socket_pcap.c
index 04e31063260237fbc4c1d0eab63453ca742ec6b7..27d51f7301e4f6d067ad3f6eb7f8012918baabe8 100644
--- a/gtests/net/packetdrill/packet_socket_pcap.c
+++ b/gtests/net/packetdrill/packet_socket_pcap.c
@@ -52,6 +52,7 @@ struct packet_socket {
 				/* also used for sending packets */
 	char pcap_error[PCAP_ERRBUF_SIZE];	/* for libpcap errors */
 	int pcap_offset;  /* offset of packet data in pcap buffer */
+	int data_link;
 };
 
 #if defined(__OpenBSD__)
@@ -73,7 +74,7 @@ extern void die_pcap_perror(pcap_t *pcap, char *message)
 
 static void packet_socket_setup(struct packet_socket *psock)
 {
-	int data_link = -1, bpf_fd = -1, val = -1;
+	int bpf_fd = -1, val = -1;
 
 	DEBUGP("calling pcap_create() with %s\n", psock->name);
 	psock->pcap_in = pcap_create(psock->name, psock->pcap_error);
@@ -130,26 +131,22 @@ static void packet_socket_setup(struct packet_socket *psock)
 		die_perror("ioctl BIOCIMMEDIATE on bpf fd");
 
 	/* Find data link type. */
-	data_link = pcap_datalink(psock->pcap_in);
-	DEBUGP("data_link: %d\n", data_link);
+	psock->data_link = pcap_datalink(psock->pcap_in);
+	DEBUGP("data_link: %d\n", psock->data_link);
 
 	/* Based on the data_link type, calculate the offset of the
 	 * packet data in the buffer.
 	 */
-	switch (data_link) {
+	switch (psock->data_link) {
 	case DLT_EN10MB:
-		psock->pcap_offset = 0;
+		psock->pcap_offset = sizeof(struct ether_header);
 		break;
 	case DLT_LOOP:
 	case DLT_NULL:
-		psock->pcap_offset = 4;
-		break;
-	case DLT_SLIP:
-	case DLT_RAW:
-		psock->pcap_offset = 0;
+		psock->pcap_offset = sizeof(u32);
 		break;
 	default:
-		die("Unknown data_link type %d\n", data_link);
+		die("Unknown data_link type %d\n", psock->data_link);
 		break;
 	}
 }
@@ -248,13 +245,15 @@ int packet_socket_writev(struct packet_socket *psock,
 }
 
 int packet_socket_receive(struct packet_socket *psock,
-			  enum direction_t direction,
+			  enum direction_t direction, u16 *ether_type,
 			  struct packet *packet, int *in_bytes)
 {
 	int status = 0;
 	struct pcap_pkthdr *pkt_header = NULL;
 	const u8 *pkt_data = NULL;
 	pcap_t *pcap;
+	struct ether_header *ether;
+	u32 address_family;
 
 	DEBUGP("calling pcap_next_ex() for direction %s\n",
 	       direction == DIRECTION_INBOUND ? "inbound" : "outbound");
@@ -320,9 +319,37 @@ int packet_socket_receive(struct packet_socket *psock,
 	assert(pkt_header->len <= packet->buffer_bytes);
 
 	assert(pkt_header->len > psock->pcap_offset);
+	switch (psock->data_link) {
+	case DLT_EN10MB:
+		ether = (struct ether_header *)pkt_data;
+		*ether_type = ntohs(ether->ether_type);
+		break;
+	case DLT_LOOP:
+	case DLT_NULL:
+#if defined(__OpenBSD__)
+		address_family = ntohl(*(u32 *)pkt_data);
+#else
+		address_family = *(u32 *)pkt_data;
+#endif
+		switch (address_family) {
+		case AF_INET:
+			*ether_type = ETHERTYPE_IP;
+			break;
+		case AF_INET6:
+			*ether_type = ETHERTYPE_IPV6;
+			break;
+		default:
+			DEBUGP("Unknown address family %d.\n", address_family);
+			return STATUS_ERR;
+		}
+		break;
+	default:
+		assert(!"not reached");
+		break;
+	}
+	DEBUGP("ether_type is 0x%04x\n", *ether_type);
 	*in_bytes = pkt_header->len - psock->pcap_offset;
 	memcpy(packet->buffer, pkt_data + psock->pcap_offset, *in_bytes);
-
 	return STATUS_OK;
 }
 
diff --git a/gtests/net/packetdrill/packet_to_string_test.c b/gtests/net/packetdrill/packet_to_string_test.c
index fc3b21c71259d45fb6e7b798a9d5c30a8f78f155..4d33971027e9e990bed42b70e472a1f7b6e5ec7c 100644
--- a/gtests/net/packetdrill/packet_to_string_test.c
+++ b/gtests/net/packetdrill/packet_to_string_test.c
@@ -27,6 +27,7 @@
 #include <assert.h>
 #include <stdlib.h>
 #include <string.h>
+#include "ethernet.h"
 #include "packet_parser.h"
 
 static void test_tcp_ipv4_packet_to_string(void)
@@ -56,8 +57,7 @@ static void test_tcp_ipv4_packet_to_string(void)
 	memcpy(packet->buffer, data, sizeof(data));
 	char *error = NULL;
 	enum packet_parse_result_t result =
-		parse_packet(packet, sizeof(data), PACKET_LAYER_3_IP,
-				     &error);
+		parse_packet(packet, sizeof(data), ETHERTYPE_IP, &error);
 	assert(result == PACKET_OK);
 	assert(error == NULL);
 
@@ -142,8 +142,7 @@ static void test_tcp_ipv6_packet_to_string(void)
 	memcpy(packet->buffer, data, sizeof(data));
 	char *error = NULL;
 	enum packet_parse_result_t result =
-		parse_packet(packet, sizeof(data), PACKET_LAYER_3_IP,
-				     &error);
+		parse_packet(packet, sizeof(data), ETHERTYPE_IPV6, &error);
 	assert(result == PACKET_OK);
 	assert(error == NULL);
 
@@ -224,8 +223,7 @@ static void test_gre_mpls_tcp_ipv4_packet_to_string(void)
 	memcpy(packet->buffer, data, sizeof(data));
 	char *error = NULL;
 	enum packet_parse_result_t result =
-		parse_packet(packet, sizeof(data), PACKET_LAYER_3_IP,
-				     &error);
+		parse_packet(packet, sizeof(data), ETHERTYPE_IP, &error);
 	assert(result == PACKET_OK);
 	assert(error == NULL);
 
diff --git a/gtests/net/packetdrill/types.h b/gtests/net/packetdrill/types.h
index 50d7edf2fd08637a5b38f889f0dafdb8250ee44f..ffb24e001d4f384188acac1d36f71ea823be7f4c 100644
--- a/gtests/net/packetdrill/types.h
+++ b/gtests/net/packetdrill/types.h
@@ -49,6 +49,9 @@
 #ifndef __packed
 #define __packed __attribute__ ((packed))
 #endif
+#ifndef __aligned
+#define __aligned(x) __attribute__ ((aligned(x)))
+#endif
 
 /* We use kernel-style names for standard integer types. */
 typedef unsigned char u8;
diff --git a/gtests/net/packetdrill/wire_server_netdev.c b/gtests/net/packetdrill/wire_server_netdev.c
index cee64e7a655d53d83a701dbfae4fcee852b8eec2..8ef26f3a7ce3eeec04b45fde6a91fa74c37a514d 100644
--- a/gtests/net/packetdrill/wire_server_netdev.c
+++ b/gtests/net/packetdrill/wire_server_netdev.c
@@ -192,9 +192,8 @@ static int wire_server_netdev_receive(struct netdev *a_netdev,
 
 	DEBUGP("wire_server_netdev_receive\n");
 
-	return netdev_receive_loop(netdev->psock, PACKET_LAYER_2_ETHERNET,
-				   DIRECTION_INBOUND, packet, &num_packets,
-				   error);
+	return netdev_receive_loop(netdev->psock, DIRECTION_INBOUND, packet,
+				   &num_packets, error);
 }
 
 struct netdev_ops wire_server_netdev_ops = {