From owner-svn-soc-all@freebsd.org Wed Jun 27 15:52:51 2018 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 5974F102A680 for ; Wed, 27 Jun 2018 15:52:51 +0000 (UTC) (envelope-from sduo@FreeBSD.org) Received: from mxrelay.ysv.freebsd.org (mxrelay.ysv.freebsd.org [IPv6:2001:1900:2254:206a::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.ysv.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id D557183A3A for ; Wed, 27 Jun 2018 15:52:50 +0000 (UTC) (envelope-from sduo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.ysv.freebsd.org (Postfix) with ESMTPS id 1E4C0CC41 for ; Wed, 27 Jun 2018 15:52:50 +0000 (UTC) (envelope-from sduo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id w5RFqnsG019634 for ; Wed, 27 Jun 2018 15:52:49 GMT (envelope-from sduo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id w5RFqnK2019628 for svn-soc-all@FreeBSD.org; Wed, 27 Jun 2018 15:52:49 GMT (envelope-from sduo@FreeBSD.org) Date: Wed, 27 Jun 2018 15:52:49 GMT Message-Id: <201806271552.w5RFqnK2019628@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to sduo@FreeBSD.org using -f From: sduo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r337264 - soc2018/sduo/head/sys/dev/vale_vlan MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 27 Jun 2018 15:52:51 -0000 Author: sduo Date: Wed Jun 27 15:52:47 2018 New Revision: 337264 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=337264 Log: Updated sys/dev/vale_vlan/vv_os_interface.h commends Modified: soc2018/sduo/head/sys/dev/vale_vlan/vv_os_interface.h Modified: soc2018/sduo/head/sys/dev/vale_vlan/vv_os_interface.h ============================================================================== --- soc2018/sduo/head/sys/dev/vale_vlan/vv_os_interface.h Mon Jun 18 19:47:46 2018 (r337263) +++ soc2018/sduo/head/sys/dev/vale_vlan/vv_os_interface.h Wed Jun 27 15:52:47 2018 (r337264) @@ -17,10 +17,10 @@ void vv_module_put(void); /* DOUBLY LINKED LIST TEMPLATE - * #define vv_list_declare(head_struct_t, elem_struct_t) + * #define vv_list_declare(head_struct_t, entry_struct_t) * #define vv_list_head_init(head_p) - * #define vv_list_elem_init(elem_p) - * #define vv_list_entry(elem_struct_t) + * #define vv_list_elem_init(elem_p, entry_name) + * #define vv_list_entry(entry_struct_t) * #define vv_list_insert_head(head_p, elem_p, entry_name) * #define vv_list_remove(elem_p, entry_name) * #define vv_list_foreach(cursor_p, head_p, entry_name) @@ -28,14 +28,14 @@ */ #if defined(__linux__) -#define vv_list_declare(head_struct_t, elem_struct_t) struct list_head +#define vv_list_declare(head_struct_t, entry_struct_t) struct list_head #define vv_list_head_init(head_p) INIT_LIST_HEAD(head_p) #define vv_list_elem_init(elem_p, entry_name) \ INIT_LIST_HEAD(&(elem_p)->entry_name) -#define vv_list_entry(elem_struct_t) struct list_head +#define vv_list_entry(entry_struct_t) struct list_head #define vv_list_insert_head(head_p, elem_p, entry_name) \ list_add(&(elem_p)->entry_name, head_p) @@ -49,14 +49,14 @@ list_for_each_entry_safe(cursor_p, temp_p, head_p, entry_name) #elif defined(__FreeBSD__) -#define vv_list_declare(head_struct_t, elem_struct_t) \ - LIST_HEAD(head_struct_t, elem_struct_t) +#define vv_list_declare(head_struct_t, entry_struct_t) \ + LIST_HEAD(head_struct_t, entry_struct_t) #define vv_list_head_init(head_p) LIST_INIT(head_p) #define vv_list_elem_init(elem_p, entry_name) (void)(elem_p) -#define vv_list_entry(elem_struct_t) LIST_ENTRY(elem_struct_t) +#define vv_list_entry(entry_struct_t) LIST_ENTRY(entry_struct_t) #define vv_list_insert_head(head_p, elem_p, entry_name) \ LIST_INSERT_HEAD(head_p, elem_p, entry_name) From owner-svn-soc-all@freebsd.org Wed Jun 27 16:17:27 2018 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id CCA98102B417 for ; Wed, 27 Jun 2018 16:17:26 +0000 (UTC) (envelope-from sduo@FreeBSD.org) Received: from mxrelay.ysv.freebsd.org (mxrelay.ysv.freebsd.org [IPv6:2001:1900:2254:206a::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.ysv.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 1D2F384576 for ; Wed, 27 Jun 2018 16:17:26 +0000 (UTC) (envelope-from sduo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.ysv.freebsd.org (Postfix) with ESMTPS id 5798ECF1C for ; Wed, 27 Jun 2018 16:17:25 +0000 (UTC) (envelope-from sduo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id w5RGHPar083855 for ; Wed, 27 Jun 2018 16:17:25 GMT (envelope-from sduo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id w5RGHMEx083846 for svn-soc-all@FreeBSD.org; Wed, 27 Jun 2018 16:17:22 GMT (envelope-from sduo@FreeBSD.org) Date: Wed, 27 Jun 2018 16:17:22 GMT Message-Id: <201806271617.w5RGHMEx083846@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to sduo@FreeBSD.org using -f From: sduo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r337265 - soc2018/sduo/netmap_utils MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 27 Jun 2018 16:17:27 -0000 Author: sduo Date: Wed Jun 27 16:17:21 2018 New Revision: 337265 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=337265 Log: functional.c can request netmap interface file descriptors from fd_server. Added: soc2018/sduo/netmap_utils/functional.c Modified: soc2018/sduo/netmap_utils/fd_server.c soc2018/sduo/netmap_utils/fd_server.h Modified: soc2018/sduo/netmap_utils/fd_server.c ============================================================================== --- soc2018/sduo/netmap_utils/fd_server.c Wed Jun 27 15:52:47 2018 (r337264) +++ soc2018/sduo/netmap_utils/fd_server.c Wed Jun 27 16:17:21 2018 (r337265) @@ -1,5 +1,7 @@ #include #include +#include +#include #include #include #include @@ -10,17 +12,22 @@ #include #include #include -#include + +#include +#define NETMAP_WITH_LIBS +#include #include "fd_server.h" struct nmd_entry { + char if_name[NETMAP_REQ_IFNAMSIZ]; struct nm_desc *nmd; uint8_t is_in_use; uint8_t is_open; }; -#define SOCKET_NAME "/tmp/my_unix_socket" +#define printf(format, ...) syslog(LOG_NOTICE, format, ##__VA_ARGS__) + #define MAX_OPEN_IF 128 struct nmd_entry entries[MAX_OPEN_IF]; int num_entries = 0; @@ -29,13 +36,13 @@ print_request(struct fd_request *req) { - syslog(LOG_NOTICE, "d action: %s, if_name: %s\n", + printf("action: %s, if_name: '%s'\n", req->action == FD_GET - ? "FD_GET" - : req->action == FD_RELEASE - ? "FD_RELEASE" - : req->action == FD_CLOSE ? "FD_CLOSE" - : "FD_STOP", + ? "FD_GET" + : req->action == FD_RELEASE + ? "FD_RELEASE" + : req->action == FD_CLOSE ? "FD_CLOSE" + : "FD_STOP", req->if_name); } @@ -44,32 +51,34 @@ { int i; + // printf("searching %s\n", if_name); for (i = 0; i < num_entries; ++i) { struct nmd_entry *entry = &entries[i]; - struct nm_desc *nmd = entry->nmd; + + // printf("i=%d, is_open=%d, is_in_use=%d, if_name=%s\n", + // i, entry->is_open, entry->is_in_use, entry->if_name); if (entry->is_open == 0) { continue; } - if (strcmp(nmd->req.nr_name, if_name) == 0) { + if (strncmp(entry->if_name, if_name, IFNAMSIZ) == 0) { + // printf("finished searching with a match\n"); return entry; } } + // printf("finished searching without a match\n"); return NULL; } struct nmd_entry * -get_free_des(int *ret) +get_free_des(void) { - if (num_entries == MAX_OPEN_IF) { - *ret = -1; return NULL; } - *ret = 0; return &entries[num_entries++]; } @@ -77,12 +86,11 @@ get_fd(const char *if_name, struct fd_response *res) { struct nmd_entry *entry; - int ret; entry = search_des(if_name); if (entry != NULL) { if (entry->is_in_use == 1) { - syslog(LOG_NOTICE, "if_name %s is in use\n", if_name); + printf("if_name %s is in use\n", if_name); res->result = EBUSY; return -1; } @@ -90,20 +98,21 @@ return entry->nmd->fd; } - entry = get_free_des(&ret); - if (ret == -1) { - syslog(LOG_NOTICE, "Out of memory\n"); + entry = get_free_des(); + if (entry == NULL) { + printf("Out of memory\n"); res->result = ENOMEM; return -1; } entry->nmd = nm_open(if_name, NULL, 0, NULL); if (entry->nmd == NULL) { - syslog(LOG_NOTICE, "Failed to nm_open(%s) with error %d\n", - if_name, errno); + printf("Failed to nm_open(%s) with error %d\n", if_name, errno); res->result = errno; return -1; } + strncpy(entry->if_name, if_name, sizeof(entry->if_name)); + entry->if_name[sizeof(entry->if_name) - 1] = '\0'; memcpy(&res->req, &entry->nmd->req, sizeof(entry->nmd->req)); entry->is_in_use = 1; @@ -118,7 +127,7 @@ entry = search_des(if_name); if (entry == NULL) { - syslog(LOG_NOTICE, "if_name %s isn't open\n", if_name); + printf("if_name %s isn't open\n", if_name); res->result = ENOENT; return; } @@ -132,7 +141,7 @@ struct nmd_entry *entry; int ret; - if (if_name == NULL || strnlen(if_name, IFNAMSIZ) == 0) { + if (if_name == NULL || strnlen(if_name, NETMAP_REQ_IFNAMSIZ) == 0) { res->result = EINVAL; return; } @@ -140,14 +149,14 @@ entry = search_des(if_name); if (entry == NULL) { res->result = ENOENT; - syslog(LOG_NOTICE, "if_name %s hasn't been opened\n", if_name); + printf("if_name %s hasn't been opened\n", if_name); return; } - ret = nm_close(entry->nmd); + ret = nm_close(entry->nmd); res->result = ret; if (ret != 0) { - syslog(LOG_NOTICE, "error while close interface %s\n", if_name); + printf("error while close interface %s\n", if_name); return; } entry->is_in_use = 0; @@ -164,10 +173,10 @@ struct cmsghdr *cmsg; struct iovec iov[1]; struct msghdr msg; + int ret; iov[0].iov_base = buf; iov[0].iov_len = buf_size; - memset(&msg, 0, sizeof(struct msghdr)); msg.msg_iov = iov; msg.msg_iovlen = 1; @@ -176,17 +185,18 @@ /* We need the ancillary data only when we're sending a file * descriptor, and a file descriptor cannot be negative. */ - msg.msg_control = ancillary.buf; - msg.msg_controllen = sizeof(ancillary.buf); - - cmsg = CMSG_FIRSTHDR(&msg); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; - cmsg->cmsg_len = CMSG_LEN(sizeof(int)); + printf("sending a file descriptor\n"); + msg.msg_control = ancillary.buf; + msg.msg_controllen = sizeof(ancillary.buf); + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + cmsg->cmsg_len = CMSG_LEN(sizeof(int)); *(int *)CMSG_DATA(cmsg) = fd; } - return sendmsg(socket, &msg, 0); + ret = sendmsg(socket, &msg, 0); + return ret; } int @@ -194,15 +204,14 @@ { struct fd_response res; struct fd_request req; - int amount; int fd = -1; + int amount; + int ret; - memset(&res, 0, sizeof(res)); memset(&req, 0, sizeof(req)); - amount = recv(socket, &req, sizeof(struct fd_request), 0); if (amount == -1) { - syslog(LOG_NOTICE, "error during recv()"); + printf("error while receiving the request\n"); return -1; } @@ -219,14 +228,18 @@ close_fd(req.if_name, &res); return 0; case FD_STOP: - syslog(LOG_NOTICE, "shutting down"); + printf("shutting down\n"); exit(EXIT_SUCCESS); break; default: res.result = EOPNOTSUPP; } - return send_fd(socket, fd, &res, sizeof(struct fd_response)); + ret = send_fd(socket, fd, &res, sizeof(struct fd_response)); + if (ret == -1) { + printf("error while sending the reponse\n"); + } + return ret; } void @@ -236,42 +249,48 @@ int socket_fd; int ret; + printf("starting up.\n"); + if (unlink(SOCKET_NAME) == -1 && errno != ENOENT) { + printf("error %d during unlink()", errno); + exit(EXIT_FAILURE); + } socket_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0); if (socket_fd == -1) { - syslog(LOG_NOTICE, "error during socket()"); + printf("error during socket()\n"); exit(EXIT_FAILURE); } - unlink(SOCKET_NAME); memset(&name, 0, sizeof(struct sockaddr_un)); name.sun_family = AF_UNIX; strncpy(name.sun_path, SOCKET_NAME, sizeof(name.sun_path) - 1); ret = bind(socket_fd, (const struct sockaddr *)&name, - sizeof(struct sockaddr_un)); + sizeof(struct sockaddr_un)); if (ret == -1) { - syslog(LOG_NOTICE, "error during bind()"); + printf("error during bind()\n"); exit(EXIT_FAILURE); } ret = listen(socket_fd, 2); if (ret == -1) { - syslog(LOG_NOTICE, "error during listen()"); + printf("error during listen()"); exit(EXIT_FAILURE); } + printf("listening\n"); for (;;) { int conn_fd; int ret; conn_fd = accept(socket_fd, NULL, NULL); if (conn_fd == -1) { - syslog(LOG_NOTICE, - "error during accept(), shutting down"); + printf("error during accept(), shutting down\n"); exit(EXIT_FAILURE); } - syslog(LOG_NOTICE, "handling a request"); ret = handle_request(conn_fd); + if (ret == -1) { + printf("error while handling a request\n"); + } (void)ret; close(conn_fd); } @@ -291,7 +310,7 @@ exit(EXIT_SUCCESS); } - if (setsid() < 0) { + if (setsid() == -1) { exit(EXIT_FAILURE); } @@ -307,10 +326,11 @@ } umask(0); + if (chdir("/") == -1) { - perror("chdir()"); exit(EXIT_FAILURE); } + for (i = sysconf(_SC_OPEN_MAX); i >= 0; i--) { close(i); } @@ -321,7 +341,6 @@ int main() { - daemonize(); main_loop(); return 0; Modified: soc2018/sduo/netmap_utils/fd_server.h ============================================================================== --- soc2018/sduo/netmap_utils/fd_server.h Wed Jun 27 15:52:47 2018 (r337264) +++ soc2018/sduo/netmap_utils/fd_server.h Wed Jun 27 16:17:21 2018 (r337265) @@ -1,14 +1,7 @@ #ifndef FD_LIB_H #define FD_LIB_H -#include -#include -#include -#include - -#include -#define NETMAP_WITH_LIBS -#include +#define SOCKET_NAME "/tmp/my_unix_socket" struct fd_request { #define FD_GET 1 @@ -16,7 +9,7 @@ #define FD_CLOSE 3 #define FD_STOP 4 uint8_t action; - char if_name[IFNAMSIZ]; + char if_name[NETMAP_REQ_IFNAMSIZ]; }; struct fd_response { Added: soc2018/sduo/netmap_utils/functional.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2018/sduo/netmap_utils/functional.c Wed Jun 27 16:17:21 2018 (r337265) @@ -0,0 +1,1245 @@ +/* + * A tool for functional testing netmap transmission and reception. + * + * Copyright (C) 2018 Vincenzo Maffione. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define NETMAP_WITH_LIBS +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "fd_server.h" + +#define ETH_ADDR_LEN 6 + +struct Event { + unsigned evtype; +#define EVENT_TYPE_RX 0x1 +#define EVENT_TYPE_TX 0x2 +#define EVENT_TYPE_PAUSE 0x3 + unsigned num; /* > 1 if repeated event */ + + /* Tx and Rx event. */ + unsigned pkt_len; + char filler; + + /* Pause event. */ + unsigned long long usecs; +}; + +struct Global { + struct nm_desc nmd; + const char *ifname; + unsigned wait_link_secs; /* wait for link */ + unsigned timeout_secs; /* transmit/receive timeout */ + int ignore_if_not_matching; /* ignore certain received packets */ + int success_if_no_receive; /* exit status 0 if we receive no packets */ + int + sequential_fill; /* increment fill char for multi-packets + operations */ + int request_from_fd_server; + int verbose; + +#define MAX_PKT_SIZE 65536 + char pktm[MAX_PKT_SIZE]; /* packet model */ + unsigned pktm_len; /* packet model length */ + char pktr[MAX_PKT_SIZE]; /* packet received */ + unsigned pktr_len; /* length of received packet */ + unsigned max_frag_size; /* max bytes per netmap TX slot */ + + char src_mac[ETH_ADDR_LEN]; + char dst_mac[ETH_ADDR_LEN]; + uint32_t src_ip; + uint32_t dst_ip; + uint16_t src_port; + uint16_t dst_port; + char filler; + +#define MAX_EVENTS 64 + unsigned num_events; + struct Event events[MAX_EVENTS]; + unsigned num_loops; +}; + +void release_if_fd(struct Global *, const char *); + +void +clean_exit(struct Global *g) +{ + + release_if_fd(g, g->ifname); + exit(EXIT_FAILURE); +} + +static void +fill_packet_field(struct Global *g, unsigned offset, const char *content, + unsigned content_len) +{ + if (offset + content_len > sizeof(g->pktm)) { + printf("Packet layout overflow: %u + %u > %lu\n", offset, + content_len, sizeof(g->pktm)); + clean_exit(g); + } + + memcpy(g->pktm + offset, content, content_len); +} + +static void +fill_packet_8bit(struct Global *g, unsigned offset, uint8_t val) +{ + fill_packet_field(g, offset, (const char *)&val, sizeof(val)); +} + +static void +fill_packet_16bit(struct Global *g, unsigned offset, uint16_t val) +{ + val = htons(val); + fill_packet_field(g, offset, (const char *)&val, sizeof(val)); +} + +static void +fill_packet_32bit(struct Global *g, unsigned offset, uint32_t val) +{ + val = htonl(val); + fill_packet_field(g, offset, (const char *)&val, sizeof(val)); +} + +/* Compute the checksum of the given ip header. */ +static uint32_t +checksum(const void *data, uint16_t len, uint32_t sum /* host endianness */) +{ + const uint8_t *addr = data; + uint32_t i; + + /* Checksum all the pairs of bytes first... */ + for (i = 0; i < (len & ~1U); i += 2) { + sum += (u_int16_t)ntohs(*((u_int16_t *)(addr + i))); + if (sum > 0xFFFF) { + sum -= 0xFFFF; + } + } + /* + * If there's a single byte left over, checksum it, too. + * Network byte order is big-endian, so the remaining byte is + * the high byte. + */ + if (i < len) { + sum += addr[i] << 8; + if (sum > 0xFFFF) { + sum -= 0xFFFF; + } + } + return sum; +} + +static uint16_t +wrapsum(uint32_t sum /* host endianness */) +{ + sum = ~sum & 0xFFFF; + return sum; /* host endianness */ +} + +static void +build_packet(struct Global *g) +{ + unsigned ofs = 0; + unsigned ethofs; + unsigned ipofs; + unsigned udpofs; + unsigned pldofs; + + memset(g->pktm, 0, sizeof(g->pktm)); + if (g->verbose) { + printf("%s: starting at ofs %u\n", __func__, ofs); + } + + ethofs = ofs; + (void)ethofs; + /* Ethernet destination and source MAC address plus ethertype. */ + fill_packet_field(g, ofs, g->dst_mac, ETH_ADDR_LEN); + ofs += ETH_ADDR_LEN; + fill_packet_field(g, ofs, g->src_mac, ETH_ADDR_LEN); + ofs += ETH_ADDR_LEN; + fill_packet_16bit(g, ofs, ETHERTYPE_IP); + ofs += 2; + if (g->verbose) { + printf("%s: eth done, ofs %u\n", __func__, ofs); + } + + ipofs = ofs; + /* First byte of IP header. */ + fill_packet_8bit(g, ofs, + (IPVERSION << 4) | ((sizeof(struct iphdr)) >> 2)); + ofs += 1; + /* Skip QoS byte. */ + ofs += 1; + /* Total length. */ + fill_packet_16bit(g, ofs, g->pktm_len - ipofs); + ofs += 2; + /* Skip identification field. */ + ofs += 2; + /* Offset (and flags) field. */ + fill_packet_16bit(g, ofs, IP_DF); + ofs += 2; + /* TTL. */ + fill_packet_8bit(g, ofs, IPDEFTTL); + ofs += 1; + /* Protocol. */ + fill_packet_8bit(g, ofs, IPPROTO_UDP); + ofs += 1; + /* Skip checksum for now. */ + ofs += 2; + /* Source IP address. */ + fill_packet_32bit(g, ofs, g->src_ip); + ofs += 4; + /* Dst IP address. */ + fill_packet_32bit(g, ofs, g->dst_ip); + ofs += 4; + /* Now put the checksum. */ + fill_packet_16bit( + g, ipofs + 10, + wrapsum(checksum(g->pktm + ipofs, sizeof(struct iphdr), 0))); + if (g->verbose) { + printf("%s: ip done, ofs %u\n", __func__, ofs); + } + + udpofs = ofs; + /* UDP source port. */ + fill_packet_16bit(g, ofs, g->src_port); + ofs += 2; + /* UDP source port. */ + fill_packet_16bit(g, ofs, g->dst_port); + ofs += 2; + /* UDP length (UDP header + data). */ + fill_packet_16bit(g, ofs, g->pktm_len - udpofs); + ofs += 2; + /* Skip the UDP checksum for now. */ + ofs += 2; + if (g->verbose) { + printf("%s: udp done, ofs %u\n", __func__, ofs); + } + + /* Fill UDP payload. */ + pldofs = ofs; + for (; ofs < g->pktm_len; ofs++) { + fill_packet_8bit(g, ofs, g->filler); + } + if (g->verbose) { + printf("%s: payload done, ofs %u\n", __func__, ofs); + } + + /* Put the UDP checksum now. + * Magic: taken from sbin/dhclient/packet.c */ + fill_packet_16bit( + g, udpofs + 6, + wrapsum(checksum( + /* udp header */ g->pktm + udpofs, + sizeof(struct udphdr), + checksum(/* udp payload */ g->pktm + pldofs, + g->pktm_len - pldofs, + checksum(/* pseudo header */ g->pktm + ipofs + + 12, + 2 * sizeof(g->src_ip), + IPPROTO_UDP + (uint32_t)(g->pktm_len - + udpofs)))))); +} + +// static unsigned +// tx_bytes_avail(struct netmap_ring *ring, unsigned max_frag_size) +// { +// unsigned avail_per_slot = ring->nr_buf_size; + +// if (max_frag_size < avail_per_slot) { +// avail_per_slot = max_frag_size; +// } + +// return nm_ring_space(ring) * avail_per_slot; +// } + +static int +tx_flush(struct Global *g) +{ + struct nm_desc *nmd = &g->nmd; + unsigned elapsed_ms = 0; + unsigned wait_ms = 100; + int i; + + for (;;) { + int pending = 0; + for (i = nmd->first_tx_ring; i <= nmd->last_tx_ring; i++) { + struct netmap_ring *ring = NETMAP_TXRING(nmd->nifp, i); + + pending += nm_tx_pending(ring); + } + + if (!pending) { + return 0; + } + + if (elapsed_ms > g->timeout_secs * 1000) { + printf("%s: Timeout\n", __func__); + return -1; + } + + usleep(wait_ms * 1000); + elapsed_ms += wait_ms; + + ioctl(nmd->fd, NIOCTXSYNC, NULL); + } +} + +uint64_t +ring_avail_packets(struct netmap_ring *ring, unsigned pkt_len) +{ + uint64_t slot_per_packet; + + slot_per_packet = ceil((double)pkt_len / (double)ring->nr_buf_size); + return nm_ring_space(ring) / slot_per_packet; +} + +uint64_t +adapter_avail_sends(struct nm_desc *nmd, unsigned pkt_len) +{ + uint64_t sends_available = 0; + unsigned int i; + + for (i = nmd->first_tx_ring; i <= nmd->last_tx_ring; i++) { + struct netmap_ring *ring = NETMAP_TXRING(nmd->nifp, i); + + sends_available += ring_avail_packets(ring, pkt_len); + } + + return sends_available; +} + +void +put_one_packet(struct Global *g, struct netmap_ring *ring) +{ + unsigned head = ring->head; + unsigned frags = 0; + unsigned ofs = 0; + + for (;;) { + struct netmap_slot *slot = &ring->slot[head]; + char *buf = NETMAP_BUF(ring, slot->buf_idx); + unsigned copysize = g->pktm_len - ofs; + + if (copysize > ring->nr_buf_size) { + copysize = ring->nr_buf_size; + } + if (copysize > g->max_frag_size) { + copysize = g->max_frag_size; + } + + memcpy(buf, g->pktm + ofs, copysize); + ofs += copysize; + slot->len = copysize; + slot->flags = NS_MOREFRAG; + head = nm_ring_next(ring, head); + frags++; + if (ofs >= g->pktm_len) { + /* Last fragment. */ + assert(ofs == g->pktm_len); + slot->flags = NS_REPORT; + break; + } + } + + ring->head = ring->cur = head; + printf("packet (%u bytes, %u frags) placed to TX\n", g->pktm_len, + frags); +} + +char +next_fill(char cur_fill) +{ + if (cur_fill == 'z') + return 'a'; + if (cur_fill == 'Z') + return 'A'; + return ++cur_fill; +} + +/* Transmit packets_num packets using any combination of TX rings. */ +static int +tx(struct Global *g, unsigned packets_num) +{ + struct nm_desc *nmd = &g->nmd; + unsigned elapsed_ms = 0; + unsigned wait_ms = 100; + unsigned int i; + + /* We cycle here until either we timeout or we find enough space. */ + for (;;) { + if (adapter_avail_sends(nmd, g->pktm_len) >= packets_num) { + break; + } + + if (elapsed_ms > g->timeout_secs * 1000) { + printf("%s: Timeout\n", __func__); + return -1; + } + + /* Retry after a short while. */ + usleep(wait_ms * 1000); + elapsed_ms += wait_ms; + ioctl(nmd->fd, NIOCTXSYNC, NULL); + } + + /* Once we have enough space, we start filling slots. We might use + * multiple rings. + */ + for (i = nmd->first_tx_ring; i <= nmd->last_tx_ring; i++) { + struct netmap_ring *ring = NETMAP_TXRING(nmd->nifp, i); + uint64_t ring_sends_num; + + for (ring_sends_num = ring_avail_packets(ring, g->pktm_len); + ring_sends_num > 0 && packets_num > 0; + --ring_sends_num, --packets_num) { + put_one_packet(g, ring); + + if (g->sequential_fill == 1) { + g->filler = next_fill(g->filler); + build_packet(g); + } + } + + if (packets_num == 0) { + break; + } + } + + assert(packets_num == 0); + /* Once we're done we sync, sending all packets at once. */ + ioctl(nmd->fd, NIOCTXSYNC, NULL); + return 0; +} + +/* If -I option is specified, we want to ignore frames that don't match + * our expected ethernet header. + * This function currently assumes that Ethernet header starts from + * the beginning of the packet buffers. */ +static int +ignore_received_frame(struct Global *g) +{ + if (!g->ignore_if_not_matching) { + return 0; /* don't ignore */ + } + + if (g->pktr_len < 14 || memcmp(g->pktm, g->pktr, 14) != 0) { + return 1; /* ignore */ + } + + return 0; /* don't ignore */ +} + +uint64_t +adapter_avail_receives(struct nm_desc *nmd, unsigned pkt_len) +{ + uint64_t receives_available = 0; + unsigned int i; + + for (i = nmd->first_rx_ring; i <= nmd->last_rx_ring; i++) { + struct netmap_ring *ring = NETMAP_RXRING(nmd->nifp, i); + + receives_available += ring_avail_packets(ring, pkt_len); + } + + return receives_available; +} + +static int +rx_check(struct Global *g) +{ + unsigned i; + + if (g->pktr_len != g->pktm_len) { + printf("Received packet length (%u) different from " + "expected (%u bytes)\n", + g->pktr_len, g->pktm_len); + return -1; + } + + for (i = 0; i < g->pktr_len; i++) { + if (g->pktr[i] != g->pktm[i]) { + printf("Received packet differs from model at " + "offset %u (0x%02x!=0x%02x)\n", + i, g->pktr[i], (uint8_t)g->pktm[i]); + return -1; + } + } + + return 0; +} + +int +read_one_packet(struct Global *g, struct netmap_ring *ring) +{ + unsigned head = ring->head; + int frags = 0; + + g->pktr_len = 0; + for (;;) { + struct netmap_slot *slot = &ring->slot[head]; + char *buf = NETMAP_BUF(ring, slot->buf_idx); + + if (g->pktr_len + slot->len > sizeof(g->pktr)) { + /* Sanity check. */ + printf("Error: received packet too " + "large " + "(>= %u bytes) ", + g->pktr_len + slot->len); + clean_exit(g); + } + + memcpy(g->pktr + g->pktr_len, buf, slot->len); + g->pktr_len += slot->len; + head = nm_ring_next(ring, head); + frags++; + if (!(slot->flags & NS_MOREFRAG)) { + break; + } + + if (head == ring->tail) { + printf("warning: truncated packet " + "(len=%u)\n", + g->pktr_len); + frags = -1; + break; + } + } + + ring->head = ring->cur = head; + printf("packet (%u bytes, %d frags) received " + "from RX\n", + g->pktr_len, frags); + return frags; +} + +/* Receive packets_num packets from any combination of RX rings. */ +static int +rx(struct Global *g, unsigned packets_num) +{ + struct nm_desc *nmd = &g->nmd; + unsigned elapsed_ms = 0; + unsigned wait_ms = 100; + unsigned int i; + + /* We cycle here until either we timeout or we find enough space. */ + for (;;) { + again: + if (adapter_avail_receives(nmd, g->pktm_len) >= packets_num) { + break; + } + + if (elapsed_ms > g->timeout_secs * 1000) { + printf("%s: Timeout\n", __func__); + /* -n flag */ + return g->success_if_no_receive == 1 ? 0 : -1; + } + + /* Retry after a short while. */ + usleep(wait_ms * 1000); + elapsed_ms += wait_ms; + ioctl(nmd->fd, NIOCRXSYNC, NULL); + } + + /* Once we have enough space, we start reading packets. We might use + * multiple rings. + */ + for (i = nmd->first_rx_ring; i <= nmd->last_rx_ring; i++) { + struct netmap_ring *ring = NETMAP_RXRING(nmd->nifp, i); + uint64_t ring_receives_num; + + for (ring_receives_num = ring_avail_packets(ring, g->pktm_len); + ring_receives_num > 0 && packets_num > 0; + --ring_receives_num, --packets_num) { + int frags = 0; + + frags = read_one_packet(g, ring); + if (frags == -1) { + break; /* Truncated packet, skip this ring. */ + } + + if (ignore_received_frame(g)) { + if (g->verbose) { + printf("(ignoring packet with %u bytes " + "and " + "%d frags received from RX ring " + "#%d)\n", + g->pktr_len, frags, i); + } + elapsed_ms = 0; + /* We can go back there, because we're + * decrementing packets_num each time, therefore + * the we will wait only for the remaining + * packets. + */ + goto again; + } + + /* As soon as we find a packet wich doesn't match our + * packet model we exit with status EXIT_FAILURE. + */ + if (rx_check(g)) { + clean_exit(g); + } + + if (g->sequential_fill == 1) { + g->filler = next_fill(g->filler); *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** From owner-svn-soc-all@freebsd.org Fri Jun 29 19:39:06 2018 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 9C78EF76CA5 for ; Fri, 29 Jun 2018 19:39:06 +0000 (UTC) (envelope-from aniketp@FreeBSD.org) Received: from mxrelay.ysv.freebsd.org (mxrelay.ysv.freebsd.org [IPv6:2001:1900:2254:206a::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.ysv.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 102857867E for ; Fri, 29 Jun 2018 19:39:06 +0000 (UTC) (envelope-from aniketp@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.ysv.freebsd.org (Postfix) with ESMTPS id 642E727B24 for ; Fri, 29 Jun 2018 19:39:05 +0000 (UTC) (envelope-from aniketp@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id w5TJd5iw010267 for ; Fri, 29 Jun 2018 19:39:05 GMT (envelope-from aniketp@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id w5TJd27x010161 for svn-soc-all@FreeBSD.org; Fri, 29 Jun 2018 19:39:02 GMT (envelope-from aniketp@FreeBSD.org) Date: Fri, 29 Jun 2018 19:39:02 GMT Message-Id: <201806291939.w5TJd27x010161@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to aniketp@FreeBSD.org using -f From: aniketp@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r337266 - soc2018/aniketp/head/tests/sys/audit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 29 Jun 2018 19:39:07 -0000 Author: aniketp Date: Fri Jun 29 19:38:59 2018 New Revision: 337266 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=337266 Log: Proposed work complete: 375 tests for 175 system calls Expected failures to be added Modified: soc2018/aniketp/head/tests/sys/audit/Makefile soc2018/aniketp/head/tests/sys/audit/administrative.c soc2018/aniketp/head/tests/sys/audit/file-attribute-access.c soc2018/aniketp/head/tests/sys/audit/file-attribute-modify.c soc2018/aniketp/head/tests/sys/audit/inter-process.c soc2018/aniketp/head/tests/sys/audit/ioctl.c soc2018/aniketp/head/tests/sys/audit/network.c soc2018/aniketp/head/tests/sys/audit/open.c soc2018/aniketp/head/tests/sys/audit/process-control.c Modified: soc2018/aniketp/head/tests/sys/audit/Makefile ============================================================================== --- soc2018/aniketp/head/tests/sys/audit/Makefile Wed Jun 27 16:17:21 2018 (r337265) +++ soc2018/aniketp/head/tests/sys/audit/Makefile Fri Jun 29 19:38:59 2018 (r337266) @@ -3,15 +3,23 @@ TESTSDIR= ${TESTSBASE}/sys/audit ATF_TESTS_C= file-attribute-access +ATF_TESTS_C+= file-attribute-modify ATF_TESTS_C+= file-create ATF_TESTS_C+= file-delete ATF_TESTS_C+= file-close ATF_TESTS_C+= file-write ATF_TESTS_C+= file-read ATF_TESTS_C+= open +ATF_TESTS_C+= ioctl +ATF_TESTS_C+= network +ATF_TESTS_C+= inter-process +ATF_TESTS_C+= administrative +ATF_TESTS_C+= process-control SRCS.file-attribute-access+= file-attribute-access.c SRCS.file-attribute-access+= utils.c +SRCS.file-attribute-modify+= file-attribute-modify.c +SRCS.file-attribute-modify+= utils.c SRCS.file-create+= file-create.c SRCS.file-create+= utils.c SRCS.file-delete+= file-delete.c @@ -24,6 +32,16 @@ SRCS.file-read+= utils.c SRCS.open+= open.c SRCS.open+= utils.c +SRCS.ioctl+= ioctl.c +SRCS.ioctl+= utils.c +SRCS.network+= network.c +SRCS.network+= utils.c +SRCS.inter-process+= inter-process.c +SRCS.inter-process+= utils.c +SRCS.administrative+= administrative.c +SRCS.administrative+= utils.c +SRCS.process-control+= process-control.c +SRCS.process-control+= utils.c TEST_METADATA+= timeout="30" TEST_METADATA+= required_user="root" Modified: soc2018/aniketp/head/tests/sys/audit/administrative.c ============================================================================== --- soc2018/aniketp/head/tests/sys/audit/administrative.c Wed Jun 27 16:17:21 2018 (r337265) +++ soc2018/aniketp/head/tests/sys/audit/administrative.c Fri Jun 29 19:38:59 2018 (r337266) @@ -1,6 +1,5 @@ /*- - * Copyright 2018 Aniket Pandey - * All rights reserved. + * Copyright (c) 2018 Aniket Pandey * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -30,8 +29,13 @@ #include #include #include +#include #include +#include #include + +#include +#include #include #include @@ -39,15 +43,17 @@ #include #include #include -#include #include "utils.h" static pid_t pid; +static int filedesc; static mode_t mode = 0777; static struct pollfd fds[1]; -static char adregex[60]; +static char adregex[80]; +static const char *auclass = "ad"; static const char *path = "fileforaudit"; +static const char *successreg = "fileforaudit.*return,success"; ATF_TC_WITH_CLEANUP(settimeofday_success); @@ -60,13 +66,13 @@ ATF_TC_BODY(settimeofday_success, tc) { pid = getpid(); - snprintf(adregex, 60, "settimeofday.*%d.*return,success", pid); + snprintf(adregex, sizeof(adregex), "settimeofday.*%d.*success", pid); struct timeval tp; struct timezone tzp; ATF_REQUIRE_EQ(0, gettimeofday(&tp, &tzp)); - FILE *pipefd = setup(fds, "ad"); + FILE *pipefd = setup(fds, auclass); /* Setting the same time as obtained by gettimeofday(2) */ ATF_REQUIRE_EQ(0, settimeofday(&tp, &tzp)); check_audit(fds, adregex, pipefd); @@ -88,15 +94,15 @@ ATF_TC_BODY(settimeofday_failure, tc) { pid = getpid(); - snprintf(adregex, 60, "settimeofday.*%d.*return,failure", pid); + snprintf(adregex, sizeof(adregex), "settimeofday.*%d.*failure", pid); struct timeval tp; struct timezone tzp; ATF_REQUIRE_EQ(0, gettimeofday(&tp, &tzp)); - FILE *pipefd = setup(fds, "ad"); - /* Invalid value for tp.tv_sec; */ + FILE *pipefd = setup(fds, auclass); tp.tv_sec = -1; + /* Failure reason: Invalid value for tp.tv_sec; */ ATF_REQUIRE_EQ(-1, settimeofday(&tp, &tzp)); check_audit(fds, adregex, pipefd); } @@ -107,6 +113,60 @@ } +ATF_TC_WITH_CLEANUP(clock_settime_success); +ATF_TC_HEAD(clock_settime_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " + "clock_settime(2) call"); +} + +ATF_TC_BODY(clock_settime_success, tc) +{ + pid = getpid(); + snprintf(adregex, sizeof(adregex), "clock_settime.*%d.*success", pid); + + struct timespec tp; + ATF_REQUIRE_EQ(0, clock_gettime(CLOCK_REALTIME, &tp)); + + FILE *pipefd = setup(fds, auclass); + /* Setting the same time as obtained by clock_gettime(2) */ + ATF_REQUIRE_EQ(0, clock_settime(CLOCK_REALTIME, &tp)); + check_audit(fds, adregex, pipefd); +} + +ATF_TC_CLEANUP(clock_settime_success, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(clock_settime_failure); +ATF_TC_HEAD(clock_settime_failure, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " + "clock_settime(2) call"); +} + +ATF_TC_BODY(clock_settime_failure, tc) +{ + pid = getpid(); + snprintf(adregex, sizeof(adregex), "clock_settime.*%d.*failure", pid); + + struct timespec tp; + ATF_REQUIRE_EQ(0, clock_gettime(CLOCK_MONOTONIC, &tp)); + + FILE *pipefd = setup(fds, auclass); + /* Failure reason: cannot use CLOCK_MONOTONIC to set the system time */ + ATF_REQUIRE_EQ(-1, clock_settime(CLOCK_MONOTONIC, &tp)); + check_audit(fds, adregex, pipefd); +} + +ATF_TC_CLEANUP(clock_settime_failure, tc) +{ + cleanup(); +} + + ATF_TC_WITH_CLEANUP(adjtime_success); ATF_TC_HEAD(adjtime_success, tc) { @@ -117,11 +177,11 @@ ATF_TC_BODY(adjtime_success, tc) { pid = getpid(); - snprintf(adregex, 60, "adjtime.*%d.*return,success", pid); + snprintf(adregex, sizeof(adregex), "adjtime.*%d.*return,success", pid); - FILE *pipefd = setup(fds, "ad"); + FILE *pipefd = setup(fds, auclass); /* We don't want to change the system time, hence NULL */ - ATF_REQUIRE_EQ(0, adjtime(NULL,NULL)); + ATF_REQUIRE_EQ(0, adjtime(NULL, NULL)); check_audit(fds, adregex, pipefd); } @@ -141,9 +201,9 @@ ATF_TC_BODY(adjtime_failure, tc) { pid = getpid(); - snprintf(adregex, 60, "adjtime.*%d.*return,failure", pid); + snprintf(adregex, sizeof(adregex), "adjtime.*%d.*return,failure", pid); - FILE *pipefd = setup(fds, "ad"); + FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(-1, adjtime((struct timeval *)(-1), NULL)); check_audit(fds, adregex, pipefd); } @@ -154,6 +214,54 @@ } +ATF_TC_WITH_CLEANUP(ntp_adjtime_success); +ATF_TC_HEAD(ntp_adjtime_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " + "ntp_adjtime(2) call"); +} + +ATF_TC_BODY(ntp_adjtime_success, tc) +{ + struct timex timebuff; + bzero(&timebuff, sizeof(timebuff)); + + pid = getpid(); + snprintf(adregex, sizeof(adregex), "ntp_adjtime.*%d.*success", pid); + + FILE *pipefd = setup(fds, auclass); + ATF_REQUIRE(ntp_adjtime(&timebuff) != -1); + check_audit(fds, adregex, pipefd); +} + +ATF_TC_CLEANUP(ntp_adjtime_success, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(ntp_adjtime_failure); +ATF_TC_HEAD(ntp_adjtime_failure, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " + "ntp_adjtime(2) call"); +} + +ATF_TC_BODY(ntp_adjtime_failure, tc) +{ + pid = getpid(); + snprintf(adregex, sizeof(adregex), "ntp_adjtime.*%d.*failure", pid); + + FILE *pipefd = setup(fds, auclass); + ATF_REQUIRE_EQ(-1, ntp_adjtime(NULL)); + check_audit(fds, adregex, pipefd); +} + +ATF_TC_CLEANUP(ntp_adjtime_failure, tc) +{ + cleanup(); +} + ATF_TC_WITH_CLEANUP(nfs_getfh_success); ATF_TC_HEAD(nfs_getfh_success, tc) @@ -166,13 +274,14 @@ { fhandle_t fhp; pid = getpid(); - snprintf(adregex, 60, "nfs_getfh.*%d.*return,success", pid); + snprintf(adregex, sizeof(adregex), "nfs_getfh.*%d.*ret.*success", pid); /* File needs to exist to call getfh(2) */ - ATF_REQUIRE(open(path, O_CREAT, mode) != -1); - FILE *pipefd = setup(fds, "ad"); + ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1); + FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, getfh(path, &fhp)); check_audit(fds, adregex, pipefd); + close(filedesc); } ATF_TC_CLEANUP(nfs_getfh_success, tc) @@ -191,9 +300,9 @@ ATF_TC_BODY(nfs_getfh_failure, tc) { pid = getpid(); - snprintf(adregex, 60, "nfs_getfh.*%d.*return,failure", pid); + snprintf(adregex, sizeof(adregex), "nfs_getfh.*%d.*ret.*failure", pid); - FILE *pipefd = setup(fds, "ad"); + FILE *pipefd = setup(fds, auclass); /* Failure reason: file does not exist */ ATF_REQUIRE_EQ(-1, getfh(path, NULL)); check_audit(fds, adregex, pipefd); @@ -205,6 +314,188 @@ } +ATF_TC_WITH_CLEANUP(auditctl_success); +ATF_TC_HEAD(auditctl_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " + "auditctl(2) call"); +} + +ATF_TC_BODY(auditctl_success, tc) +{ + /* File needs to exist in order to call auditctl(2) */ + ATF_REQUIRE((filedesc = open(path, O_CREAT | O_WRONLY, mode)) != -1); + FILE *pipefd = setup(fds, auclass); + ATF_REQUIRE_EQ(0, auditctl(path)); + check_audit(fds, successreg, pipefd); + close(filedesc); +} + +ATF_TC_CLEANUP(auditctl_success, tc) +{ + /* + * auditctl(2) disables audit log at /var/audit and initiates auditing + * at the configured path. To reset this, we need to stop and start the + * auditd(8) again. Here, we check if auditd(8) was running already + * before the test started. If so, we stop and start it again. + */ + system("service auditd onestop > /dev/null 2>&1"); + if (!atf_utils_file_exists("started_auditd")) + system("service auditd onestart > /dev/null 2>&1"); +} + + +ATF_TC_WITH_CLEANUP(auditctl_failure); +ATF_TC_HEAD(auditctl_failure, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " + "auditctl(2) call"); +} + +ATF_TC_BODY(auditctl_failure, tc) +{ + pid = getpid(); + snprintf(adregex, sizeof(adregex), "auditctl.*%d.*return,failure", pid); + + FILE *pipefd = setup(fds, auclass); + /* Failure reason: file does not exist */ + ATF_REQUIRE_EQ(-1, auditctl(NULL)); + check_audit(fds, adregex, pipefd); +} + +ATF_TC_CLEANUP(auditctl_failure, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(auditon_success); +ATF_TC_HEAD(auditon_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " + "auditon(2) call"); +} + +ATF_TC_BODY(auditon_success, tc) +{ + pid = getpid(); + au_evclass_map_t evclass; + snprintf(adregex, sizeof(adregex), "auditon.*%d.*return,success", pid); + + /* Initialize evclass to get the event-class mapping for auditon(2) */ + evclass.ec_number = AUE_AUDITON; + evclass.ec_class = 0; + FILE *pipefd = setup(fds, auclass); + ATF_REQUIRE_EQ(0, auditon(A_GETCLASS, &evclass, sizeof(&evclass))); + check_audit(fds, adregex, pipefd); +} + +ATF_TC_CLEANUP(auditon_success, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(auditon_failure); +ATF_TC_HEAD(auditon_failure, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " + "auditon(2) call"); +} + +ATF_TC_BODY(auditon_failure, tc) +{ + pid = getpid(); + snprintf(adregex, sizeof(adregex), "auditon.*%d.*return,failure", pid); + + FILE *pipefd = setup(fds, auclass); + /* Failure reason: Invalid au_evclass_map_t structure */ + ATF_REQUIRE_EQ(-1, auditon(A_GETCLASS, NULL, 0)); + check_audit(fds, adregex, pipefd); +} + +ATF_TC_CLEANUP(auditon_failure, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(acct_success); +ATF_TC_HEAD(acct_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " + "acct(2) call"); +} + +ATF_TC_BODY(acct_success, tc) +{ + int acctinfo, filedesc2; + size_t len = sizeof(acctinfo); + const char *acctname = "kern.acct_configured"; + ATF_REQUIRE_EQ(0, sysctlbyname(acctname, &acctinfo, &len, NULL, 0)); + + /* File needs to exist to start system accounting */ + ATF_REQUIRE((filedesc = open(path, O_CREAT | O_RDWR, mode)) != -1); + + /* + * acctinfo = 0: System accounting was disabled + * acctinfo = 1: System accounting was enabled + */ + if (acctinfo) { + ATF_REQUIRE((filedesc2 = open("acct_ok", O_CREAT, mode)) != -1); + close(filedesc2); + } + + pid = getpid(); + snprintf(adregex, sizeof(adregex), + "acct.*%s.*%d.*return,success", path, pid); + + /* + * We temporarily switch the accounting record to a file at + * our own configured path in order to confirm acct(2)'s successful + * auditing. Then we set everything back to its original state. + */ + FILE *pipefd = setup(fds, auclass); + ATF_REQUIRE_EQ(0, acct(path)); + check_audit(fds, adregex, pipefd); + close(filedesc); +} + +ATF_TC_CLEANUP(acct_success, tc) +{ + /* Reset accounting configured path */ + ATF_REQUIRE_EQ(0, system("service accounting onestop")); + if (atf_utils_file_exists("acct_ok")) { + ATF_REQUIRE_EQ(0, system("service accounting onestart")); + } + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(acct_failure); +ATF_TC_HEAD(acct_failure, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " + "acct(2) call"); +} + +ATF_TC_BODY(acct_failure, tc) +{ + pid = getpid(); + snprintf(adregex, sizeof(adregex), "acct.*%d.*return,failure", pid); + + FILE *pipefd = setup(fds, auclass); + /* Failure reason: File does not exist */ + ATF_REQUIRE_EQ(-1, acct(path)); + check_audit(fds, adregex, pipefd); +} + +ATF_TC_CLEANUP(acct_failure, tc) +{ + cleanup(); +} + + ATF_TC_WITH_CLEANUP(getauid_success); ATF_TC_HEAD(getauid_success, tc) { @@ -216,9 +507,9 @@ { au_id_t auid; pid = getpid(); - snprintf(adregex, 60, "getauid.*%d.*return,success", pid); + snprintf(adregex, sizeof(adregex), "getauid.*%d.*return,success", pid); - FILE *pipefd = setup(fds, "ad"); + FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, getauid(&auid)); check_audit(fds, adregex, pipefd); } @@ -239,9 +530,10 @@ ATF_TC_BODY(getauid_failure, tc) { pid = getpid(); - snprintf(adregex, 60, "getauid.*%d.*return,failure", pid); + snprintf(adregex, sizeof(adregex), "getauid.*%d.*return,failure", pid); - FILE *pipefd = setup(fds, "ad"); + FILE *pipefd = setup(fds, auclass); + /* Failure reason: Bad address */ ATF_REQUIRE_EQ(-1, getauid(NULL)); check_audit(fds, adregex, pipefd); } @@ -263,10 +555,10 @@ { au_id_t auid; pid = getpid(); - snprintf(adregex, 60, "setauid.*%d.*return,success", pid); + snprintf(adregex, sizeof(adregex), "setauid.*%d.*return,success", pid); ATF_REQUIRE_EQ(0, getauid(&auid)); - FILE *pipefd = setup(fds, "ad"); + FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, setauid(&auid)); check_audit(fds, adregex, pipefd); } @@ -287,9 +579,10 @@ ATF_TC_BODY(setauid_failure, tc) { pid = getpid(); - snprintf(adregex, 60, "setauid.*%d.*return,failure", pid); + snprintf(adregex, sizeof(adregex), "setauid.*%d.*return,failure", pid); - FILE *pipefd = setup(fds, "ad"); + FILE *pipefd = setup(fds, auclass); + /* Failure reason: Bad address */ ATF_REQUIRE_EQ(-1, setauid(NULL)); check_audit(fds, adregex, pipefd); } @@ -309,11 +602,11 @@ ATF_TC_BODY(getaudit_success, tc) { - auditinfo_t auditinfo; pid = getpid(); - snprintf(adregex, 60, "getaudit.*%d.*return,success", pid); + auditinfo_t auditinfo; + snprintf(adregex, sizeof(adregex), "getaudit.*%d.*return,success", pid); - FILE *pipefd = setup(fds, "ad"); + FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, getaudit(&auditinfo)); check_audit(fds, adregex, pipefd); } @@ -334,9 +627,10 @@ ATF_TC_BODY(getaudit_failure, tc) { pid = getpid(); - snprintf(adregex, 60, "getaudit.*%d.*return,failure", pid); + snprintf(adregex, sizeof(adregex), "getaudit.*%d.*return,failure", pid); - FILE *pipefd = setup(fds, "ad"); + FILE *pipefd = setup(fds, auclass); + /* Failure reason: Bad address */ ATF_REQUIRE_EQ(-1, getaudit(NULL)); check_audit(fds, adregex, pipefd); } @@ -356,12 +650,12 @@ ATF_TC_BODY(setaudit_success, tc) { - auditinfo_t auditinfo; pid = getpid(); - snprintf(adregex, 60, "setaudit.*%d.*return,success", pid); + auditinfo_t auditinfo; + snprintf(adregex, sizeof(adregex), "setaudit.*%d.*return,success", pid); ATF_REQUIRE_EQ(0, getaudit(&auditinfo)); - FILE *pipefd = setup(fds, "ad"); + FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(0, setaudit(&auditinfo)); check_audit(fds, adregex, pipefd); } @@ -382,9 +676,10 @@ ATF_TC_BODY(setaudit_failure, tc) { pid = getpid(); - snprintf(adregex, 60, "setaudit.*%d.*return,failure", pid); + snprintf(adregex, sizeof(adregex), "setaudit.*%d.*return,failure", pid); - FILE *pipefd = setup(fds, "ad"); + FILE *pipefd = setup(fds, auclass); + /* Failure reason: Bad address */ ATF_REQUIRE_EQ(-1, setaudit(NULL)); check_audit(fds, adregex, pipefd); } @@ -404,13 +699,13 @@ ATF_TC_BODY(getaudit_addr_success, tc) { - auditinfo_addr_t auditinfo; - u_int *length = (u_int *)malloc(sizeof(u_int)); pid = getpid(); - snprintf(adregex, 60, "getaudit_addr.*%d.*return,success", pid); + auditinfo_addr_t auditinfo; + snprintf(adregex, sizeof(adregex), + "getaudit_addr.*%d.*return,success", pid); - FILE *pipefd = setup(fds, "ad"); - ATF_REQUIRE_EQ(0, getaudit_addr(&auditinfo, *length)); + FILE *pipefd = setup(fds, auclass); + ATF_REQUIRE_EQ(0, getaudit_addr(&auditinfo, sizeof(auditinfo))); check_audit(fds, adregex, pipefd); } @@ -430,9 +725,11 @@ ATF_TC_BODY(getaudit_addr_failure, tc) { pid = getpid(); - snprintf(adregex, 60, "getaudit_addr.*%d.*return,failure", pid); + snprintf(adregex, sizeof(adregex), + "getaudit_addr.*%d.*return,failure", pid); - FILE *pipefd = setup(fds, "ad"); + FILE *pipefd = setup(fds, auclass); + /* Failure reason: Bad address */ ATF_REQUIRE_EQ(-1, getaudit_addr(NULL, 0)); check_audit(fds, adregex, pipefd); } @@ -452,14 +749,14 @@ ATF_TC_BODY(setaudit_addr_success, tc) { - auditinfo_addr_t auditinfo; - u_int *length = (u_int *)malloc(sizeof(u_int)); pid = getpid(); - snprintf(adregex, 60, "setaudit_addr.*%d.*return,success", pid); - ATF_REQUIRE_EQ(0, getaudit_addr(&auditinfo, *length)); + auditinfo_addr_t auditinfo; + snprintf(adregex, sizeof(adregex), + "setaudit_addr.*%d.*return,success", pid); - FILE *pipefd = setup(fds, "ad"); - ATF_REQUIRE_EQ(0, setaudit_addr(&auditinfo, *length)); + ATF_REQUIRE_EQ(0, getaudit_addr(&auditinfo, sizeof(auditinfo))); + FILE *pipefd = setup(fds, auclass); + ATF_REQUIRE_EQ(0, setaudit_addr(&auditinfo, sizeof(auditinfo))); check_audit(fds, adregex, pipefd); } @@ -479,9 +776,11 @@ ATF_TC_BODY(setaudit_addr_failure, tc) { pid = getpid(); - snprintf(adregex, 60, "setaudit_addr.*%d.*return,failure", pid); + snprintf(adregex, sizeof(adregex), + "setaudit_addr.*%d.*return,failure", pid); - FILE *pipefd = setup(fds, "ad"); + FILE *pipefd = setup(fds, auclass); + /* Failure reason: Bad address */ ATF_REQUIRE_EQ(-1, setaudit_addr(NULL, 0)); check_audit(fds, adregex, pipefd); } @@ -508,9 +807,9 @@ ATF_TC_BODY(reboot_failure, tc) { pid = getpid(); - snprintf(adregex, 60, "reboot.*%d.*return,failure", pid); + snprintf(adregex, sizeof(adregex), "reboot.*%d.*return,failure", pid); - FILE *pipefd = setup(fds, "ad"); + FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(-1, reboot(-1)); check_audit(fds, adregex, pipefd); } @@ -522,35 +821,6 @@ /* - * Audit of acct(2) cannot be tested in normal conditions as we don't want - * to enable/disable the collection of system accounting records - */ - - -ATF_TC_WITH_CLEANUP(acct_failure); -ATF_TC_HEAD(acct_failure, tc) -{ - atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " - "acct(2) call"); -} - -ATF_TC_BODY(acct_failure, tc) -{ - pid = getpid(); - snprintf(adregex, 60, "acct.*%d.*return,failure", pid); - - FILE *pipefd = setup(fds, "ad"); - ATF_REQUIRE_EQ(-1, acct(path)); - check_audit(fds, adregex, pipefd); -} - -ATF_TC_CLEANUP(acct_failure, tc) -{ - cleanup(); -} - - -/* * Audit of quotactl(2) cannot be tested in normal conditions as we don't want * to tamper with filesystem quotas */ @@ -566,9 +836,9 @@ ATF_TC_BODY(quotactl_failure, tc) { pid = getpid(); - snprintf(adregex, 60, "quotactl.*%d.*return,failure", pid); + snprintf(adregex, sizeof(adregex), "quotactl.*%d.*return,failure", pid); - FILE *pipefd = setup(fds, "ad"); + FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(-1, quotactl(NULL, 0, 0, NULL)); check_audit(fds, adregex, pipefd); } @@ -579,12 +849,6 @@ } -/* - * Audit of mount(2) and nmount(2) cannot be tested in normal - * conditions as we are not allowed to mount a filesystem. - */ - - ATF_TC_WITH_CLEANUP(mount_failure); ATF_TC_HEAD(mount_failure, tc) { @@ -595,9 +859,9 @@ ATF_TC_BODY(mount_failure, tc) { pid = getpid(); - snprintf(adregex, 60, "mount.*%d.*return,failure", pid); + snprintf(adregex, sizeof(adregex), "mount.*%d.*return,failure", pid); - FILE *pipefd = setup(fds, "ad"); + FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(-1, mount(NULL, NULL, 0, NULL)); check_audit(fds, adregex, pipefd); } @@ -618,9 +882,9 @@ ATF_TC_BODY(nmount_failure, tc) { pid = getpid(); - snprintf(adregex, 60, "nmount.*%d.*return,failure", pid); + snprintf(adregex, sizeof(adregex), "nmount.*%d.*return,failure", pid); - FILE *pipefd = setup(fds, "ad"); + FILE *pipefd = setup(fds, auclass); ATF_REQUIRE_EQ(-1, nmount(NULL, 0, 0)); check_audit(fds, adregex, pipefd); } @@ -631,62 +895,74 @@ } -ATF_TC_WITH_CLEANUP(ntp_adjtime_failure); -ATF_TC_HEAD(ntp_adjtime_failure, tc) +ATF_TC_WITH_CLEANUP(swapon_failure); +ATF_TC_HEAD(swapon_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " - "ntp_adjtime(2) call"); + "swapon(2) call"); } -ATF_TC_BODY(ntp_adjtime_failure, tc) +ATF_TC_BODY(swapon_failure, tc) { pid = getpid(); - snprintf(adregex, 60, "ntp_adjtime.*%d.*return,failure", pid); + snprintf(adregex, sizeof(adregex), "swapon.*%d.*return,failure", pid); - FILE *pipefd = setup(fds, "ad"); - ATF_REQUIRE_EQ(-1, ntp_adjtime(NULL)); + FILE *pipefd = setup(fds, auclass); + /* Failure reason: Block device required */ + ATF_REQUIRE_EQ(-1, swapon(path)); check_audit(fds, adregex, pipefd); } -ATF_TC_CLEANUP(ntp_adjtime_failure, tc) +ATF_TC_CLEANUP(swapon_failure, tc) { cleanup(); } -ATF_TC_WITH_CLEANUP(auditctl_failure); -ATF_TC_HEAD(auditctl_failure, tc) +ATF_TC_WITH_CLEANUP(swapoff_failure); +ATF_TC_HEAD(swapoff_failure, tc) { atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " - "auditctl(2) call"); + "swapoff(2) call"); } -ATF_TC_BODY(auditctl_failure, tc) +ATF_TC_BODY(swapoff_failure, tc) { pid = getpid(); - snprintf(adregex, 60, "auditctl.*%d.*return,failure", pid); + snprintf(adregex, sizeof(adregex), "swapoff.*%d.*return,failure", pid); - FILE *pipefd = setup(fds, "ad"); - ATF_REQUIRE_EQ(-1, auditctl(NULL)); + FILE *pipefd = setup(fds, auclass); + /* Failure reason: Block device required */ + ATF_REQUIRE_EQ(-1, swapoff(path)); check_audit(fds, adregex, pipefd); } -ATF_TC_CLEANUP(auditctl_failure, tc) +ATF_TC_CLEANUP(swapoff_failure, tc) { cleanup(); } - ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, settimeofday_success); ATF_TP_ADD_TC(tp, settimeofday_failure); + ATF_TP_ADD_TC(tp, clock_settime_success); + ATF_TP_ADD_TC(tp, clock_settime_failure); ATF_TP_ADD_TC(tp, adjtime_success); ATF_TP_ADD_TC(tp, adjtime_failure); + ATF_TP_ADD_TC(tp, ntp_adjtime_success); + ATF_TP_ADD_TC(tp, ntp_adjtime_failure); ATF_TP_ADD_TC(tp, nfs_getfh_success); ATF_TP_ADD_TC(tp, nfs_getfh_failure); + ATF_TP_ADD_TC(tp, acct_success); + ATF_TP_ADD_TC(tp, acct_failure); + + ATF_TP_ADD_TC(tp, auditctl_success); + ATF_TP_ADD_TC(tp, auditctl_failure); + ATF_TP_ADD_TC(tp, auditon_success); + ATF_TP_ADD_TC(tp, auditon_failure); ATF_TP_ADD_TC(tp, getauid_success); ATF_TP_ADD_TC(tp, getauid_failure); @@ -704,13 +980,11 @@ ATF_TP_ADD_TC(tp, setaudit_addr_failure); ATF_TP_ADD_TC(tp, reboot_failure); - ATF_TP_ADD_TC(tp, acct_failure); ATF_TP_ADD_TC(tp, quotactl_failure); ATF_TP_ADD_TC(tp, mount_failure); ATF_TP_ADD_TC(tp, nmount_failure); - ATF_TP_ADD_TC(tp, ntp_adjtime_failure); - ATF_TP_ADD_TC(tp, auditctl_failure); + ATF_TP_ADD_TC(tp, swapon_failure); + ATF_TP_ADD_TC(tp, swapoff_failure); return (atf_no_error()); } - Modified: soc2018/aniketp/head/tests/sys/audit/file-attribute-access.c ============================================================================== --- soc2018/aniketp/head/tests/sys/audit/file-attribute-access.c Wed Jun 27 16:17:21 2018 (r337265) +++ soc2018/aniketp/head/tests/sys/audit/file-attribute-access.c Fri Jun 29 19:38:59 2018 (r337266) @@ -26,6 +26,7 @@ */ #include +#include #include #include #include @@ -40,11 +41,14 @@ static struct pollfd fds[1]; static mode_t mode = 0777; static pid_t pid; -static int filedesc; +static fhandle_t fht; +static int filedesc, fhdesc; static char extregex[80]; +static char buff[] = "ezio"; static struct stat statbuff; static struct statfs statfsbuff; static const char *auclass = "fa"; +static const char *name = "authorname"; static const char *path = "fileforaudit"; static const char *errpath = "dirdoesnotexist/fileforaudit"; static const char *successreg = "fileforaudit.*return,success"; @@ -370,6 +374,768 @@ } +ATF_TC_WITH_CLEANUP(fhopen_success); +ATF_TC_HEAD(fhopen_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " + "fhopen(2) call"); +} + +ATF_TC_BODY(fhopen_success, tc) +{ + pid = getpid(); + snprintf(extregex, sizeof(extregex), "fhopen.*%d.*return,success", pid); + + /* File needs to exist to get a file-handle */ + ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1); + /* Get the file handle to be passed to fhopen(2) */ + ATF_REQUIRE_EQ(0, getfh(path, &fht)); + + FILE *pipefd = setup(fds, auclass); + ATF_REQUIRE((fhdesc = fhopen(&fht, O_RDWR)) != -1); + check_audit(fds, extregex, pipefd); + + close(fhdesc); + close(filedesc); +} + +ATF_TC_CLEANUP(fhopen_success, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(fhopen_failure); +ATF_TC_HEAD(fhopen_failure, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " + "fhopen(2) call"); +} + +ATF_TC_BODY(fhopen_failure, tc) +{ + const char *regex = "fhopen.*return,failure : Invalid argument"; + FILE *pipefd = setup(fds, auclass); + /* + * Failure reason: NULL does not represent any file handle + * and O_CREAT is not allowed as the flag for fhopen(2) + */ + ATF_REQUIRE_EQ(-1, fhopen(NULL, O_CREAT)); + check_audit(fds, regex, pipefd); +} + +ATF_TC_CLEANUP(fhopen_failure, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(fhstat_success); +ATF_TC_HEAD(fhstat_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " + "fstat(2) call"); +} + +ATF_TC_BODY(fhstat_success, tc) +{ + pid = getpid(); + snprintf(extregex, sizeof(extregex), "fhstat.*%d.*return,success", pid); + + /* File needs to exist to get a file-handle */ + ATF_REQUIRE((filedesc = open(path, O_CREAT, mode)) != -1); + /* Get the file handle to be passed to fhstat(2) */ + ATF_REQUIRE_EQ(0, getfh(path, &fht)); + + FILE *pipefd = setup(fds, auclass); + ATF_REQUIRE_EQ(0, fhstat(&fht, &statbuff)); + check_audit(fds, extregex, pipefd); + close(filedesc); +} + +ATF_TC_CLEANUP(fhstat_success, tc) +{ + cleanup(); +} + + +ATF_TC_WITH_CLEANUP(fhstat_failure); +ATF_TC_HEAD(fhstat_failure, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " + "fhstat(2) call"); +} + +ATF_TC_BODY(fhstat_failure, tc) +{ + const char *regex = "fhstat.*return,failure : Bad address"; + FILE *pipefd = setup(fds, auclass); + /* Failure reason: NULL does not represent any file handle */ + ATF_REQUIRE_EQ(-1, fhstat(NULL, NULL)); + check_audit(fds, regex, pipefd); +} + +ATF_TC_CLEANUP(fhstat_failure, tc) +{ + cleanup(); +} *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***