diff --git a/gtests/net/packetdrill/gre.h b/gtests/net/packetdrill/gre.h new file mode 100644 index 0000000000000000000000000000000000000000..35a280aaa4c9f8c65cfe999080f8fbb3fdf4fb4f --- /dev/null +++ b/gtests/net/packetdrill/gre.h @@ -0,0 +1,82 @@ +/* + * Copyright 2013 Google Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ +/* + * Author: ncardwell@google.com (Neal Cardwell) + * + * Our own GRE header declarations, so we have something that's + * portable and somewhat more readable than a typical system header + * file. + * + * We cannot include the kernel's GRE .h files because this tool tries + * to compile and work for basically any Linux/BSD kernel version. So + * we declare our own version of various GRE-related definitions here. + */ + +#ifndef __GRE_HEADERS_H__ +#define __GRE_HEADERS_H__ + +#include "types.h" + +/* GRE header. See RFC 1701. */ +struct gre { +#if __BYTE_ORDER == __LITTLE_ENDIAN + __u16 recursion_control:3, + strict_route:1, + has_seq:1, + has_key:1, + has_routing:1, + has_checksum:1, + version:3, + reserved:4, + ack:1; +#elif __BYTE_ORDER == __BIG_ENDIAN + __u16 has_checksum:1, + has_routing:1, + has_key:1, + has_seq:1, + strict_route:1, + ack:1, + reserved:4, + version:3; +#else +# error "Please fix endianness defines" +#endif + __be16 protocol; + /* bytes 4+ (optional) not defined here... */ +}; + +/* Return the length in bytes of a GRE header. */ +static inline int gre_len(const struct gre *gre) +{ + int bytes = sizeof(*gre); + + assert(gre->version == 0); /* we only support v0 */ + assert(!gre->has_routing); /* routing info is variable-length! */ + + if (gre->has_checksum || gre->has_routing) + bytes += 4; + if (gre->has_key) + bytes += 4; + if (gre->has_seq) + bytes += 4; + + return bytes; +} + +#endif /* __GRE_HEADERS_H__ */ diff --git a/gtests/net/packetdrill/gre_packet.c b/gtests/net/packetdrill/gre_packet.c new file mode 100644 index 0000000000000000000000000000000000000000..54c6011014842409c9b43f8f6f800a5756ce9e48 --- /dev/null +++ b/gtests/net/packetdrill/gre_packet.c @@ -0,0 +1,54 @@ +/* + * Copyright 2013 Google Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ +/* + * Author: ncardwell@google.com (Neal Cardwell) + * + * Implementation for module for formatting GRE packets. + */ + +#include "gre_packet.h" + +#include "ip_packet.h" +#include "gre.h" + +int gre_header_append(struct packet *packet, char **error) +{ + struct header *header; + + header = packet_append_header(packet, HEADER_GRE, sizeof(struct gre)); + if (header == NULL) { + asprintf(error, "too many headers"); + return STATUS_ERR; + } + + return STATUS_OK; +} + +int gre_header_finish(struct packet *packet, + struct header *header, struct header *next_inner) +{ + struct gre *gre = header->h.gre; + int gre_bytes = sizeof(struct gre) + next_inner->total_bytes; + + gre->protocol = htons(header_type_info(next_inner->type)->eth_proto); + + header->total_bytes = gre_bytes; + + return STATUS_OK; +} diff --git a/gtests/net/packetdrill/gre_packet.h b/gtests/net/packetdrill/gre_packet.h new file mode 100644 index 0000000000000000000000000000000000000000..cefe9d74fa17393f62f1b90836b08122bfad040b --- /dev/null +++ b/gtests/net/packetdrill/gre_packet.h @@ -0,0 +1,44 @@ +/* + * Copyright 2013 Google Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ +/* + * Author: ncardwell@google.com (Neal Cardwell) + * + * Interface for module for formatting GRE packets. + */ + +#ifndef __GRE_PACKET_H__ +#define __GRE_PACKET_H__ + +#include "types.h" + +#include "packet.h" + +/* Append a GRE header to the end of the given packet. On success, + * return STATUS_OK; on error return STATUS_ERR and fill in a + * malloc-allocated error message in *error. + */ +extern int gre_header_append(struct packet *packet, char **error); + +/* Finalize the GRE header by filling in all necessary fields that + * were not filled in at parse time. + */ +extern int gre_header_finish(struct packet *packet, + struct header *header, struct header *next_inner); + +#endif /* __GRE_PACKET_H__ */