diff --git a/gtests/net/packetdrill/netdev.c b/gtests/net/packetdrill/netdev.c index 98a3f006e147147d78442e27aa48fca5cb4c5030..64ac611ebdf2e86d545d2b41281cf5c755d38cd4 100644 --- a/gtests/net/packetdrill/netdev.c +++ b/gtests/net/packetdrill/netdev.c @@ -370,21 +370,28 @@ static int local_netdev_receive(struct netdev *a_netdev, DEBUGP("local_netdev_receive\n"); + return netdev_receive_loop(netdev->psock, PACKET_LAYER_3_IP, + packet, error); +} + +int netdev_receive_loop(struct packet_socket *psock, + enum packet_layer_t layer, + struct packet **packet, + char **error) +{ assert(*packet == NULL); /* should be no packet yet */ *packet = packet_new(PACKET_READ_BYTES); while (1) { int in_bytes = 0; + enum packet_parse_result_t result; /* Sniff the next outbound packet from the kernel under test. */ - if (packet_socket_receive(netdev->psock, - DIRECTION_OUTBOUND, + if (packet_socket_receive(psock, DIRECTION_OUTBOUND, *packet, &in_bytes)) continue; - enum packet_parse_result_t result = - parse_packet(*packet, in_bytes, - PACKET_LAYER_3_IP, error); + result = parse_packet(*packet, in_bytes, layer, error); if (result == PACKET_OK) { return STATUS_OK; } else if (result == PACKET_BAD) { @@ -392,7 +399,8 @@ static int local_netdev_receive(struct netdev *a_netdev, *packet = NULL; return STATUS_ERR; } else { - DEBUGP("error parsing packet: %s\n", *error); + DEBUGP("parse_result:%d; error parsing packet: %s\n", + result, *error); } } diff --git a/gtests/net/packetdrill/netdev.h b/gtests/net/packetdrill/netdev.h index 1eba6d0b97fd51ec72623111398df4bb346eeef9..84e87a0af5771ef6e3fbf6ce885986bad66812f1 100644 --- a/gtests/net/packetdrill/netdev.h +++ b/gtests/net/packetdrill/netdev.h @@ -30,6 +30,8 @@ #include "config.h" #include "packet.h" +#include "packet_parser.h" +#include "packet_socket.h" struct netdev_ops; @@ -79,6 +81,16 @@ static inline int netdev_receive(struct netdev *netdev, return netdev->ops->receive(netdev, packet, error); } + +/* Keep sniffing packets leaving the kernel until we see one we know + * about and can parse. Return a pointer to the newly-allocated + * packet. Caller must free the packet with packet_free(). + */ +extern int netdev_receive_loop(struct packet_socket *psock, + enum packet_layer_t layer, + struct packet **packet, + char **error); + /* Allocate and return a new netdev for purely local tests. */ extern struct netdev *local_netdev_new(struct config *config); diff --git a/gtests/net/packetdrill/wire_server_netdev.c b/gtests/net/packetdrill/wire_server_netdev.c index fe57ce4663ad59fca9536df7910e1e93eaddce39..066566f251d5e87674357a904986bfec5cb3d59c 100644 --- a/gtests/net/packetdrill/wire_server_netdev.c +++ b/gtests/net/packetdrill/wire_server_netdev.c @@ -191,36 +191,8 @@ static int wire_server_netdev_receive(struct netdev *a_netdev, DEBUGP("wire_server_netdev_receive\n"); - assert(*packet == NULL); /* should be no packet yet */ - *packet = packet_new(PACKET_READ_BYTES); - - while (1) { - int in_bytes = 0; - enum packet_parse_result_t result; - - /* Sniff the next inbound packet from the kernel under test. */ - if (packet_socket_receive(netdev->psock, - DIRECTION_INBOUND, - *packet, &in_bytes)) - continue; - - result = parse_packet(*packet, in_bytes, - PACKET_LAYER_2_ETHERNET, - error); - if (result == PACKET_OK) { - return STATUS_OK; - } else if (result == PACKET_BAD) { - packet_free(*packet); - *packet = NULL; - return STATUS_ERR; - } else { - /* TODO: print these packets in verbose mode? */ - DEBUGP("parse_result:%d; error parsing packet: %s\n", - result, *error); - } - } - - return STATUS_ERR; + return netdev_receive_loop(netdev->psock, PACKET_LAYER_2_ETHERNET, + packet, error); } struct netdev_ops wire_server_netdev_ops = {