accf_data_attach.c revision 147300
1132649Srwatson/*- 2132649Srwatson * Copyright (c) 2004 Robert N. M. Watson 3132649Srwatson * All rights reserved. 4132649Srwatson * 5132649Srwatson * Redistribution and use in source and binary forms, with or without 6132649Srwatson * modification, are permitted provided that the following conditions 7132649Srwatson * are met: 8132649Srwatson * 1. Redistributions of source code must retain the above copyright 9132649Srwatson * notice, this list of conditions and the following disclaimer. 10132649Srwatson * 2. Redistributions in binary form must reproduce the above copyright 11132649Srwatson * notice, this list of conditions and the following disclaimer in the 12132649Srwatson * documentation and/or other materials provided with the distribution. 13132649Srwatson * 14132649Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15132649Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16132649Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17132649Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18132649Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19132649Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20132649Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21132649Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22132649Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23132649Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24132649Srwatson * SUCH DAMAGE. 25132649Srwatson * 26132649Srwatson * $FreeBSD: head/tools/regression/sockets/accf_data_attach/accf_data_attach.c 147300 2005-06-11 11:59:48Z maxim $ 27132649Srwatson */ 28132649Srwatson 29132649Srwatson#include <sys/types.h> 30132649Srwatson#include <sys/socket.h> 31132649Srwatson 32132649Srwatson#include <netinet/in.h> 33132649Srwatson 34132649Srwatson#include <err.h> 35132649Srwatson#include <errno.h> 36132649Srwatson#include <stdio.h> 37132649Srwatson#include <stdlib.h> 38132649Srwatson#include <string.h> 39132649Srwatson#include <unistd.h> 40132649Srwatson 41132649Srwatson#define ACCF_NAME "dataready" 42132649Srwatson 43132649Srwatson/* 44132649Srwatson * A number of small tests to confirm that attaching ACCF_DATA accept filters 45132649Srwatson * to inet4 ports works as expected. We test: 46132649Srwatson * 47132649Srwatson * - That no accept filter is attached on a newly created socket. 48132649Srwatson * - That bind() has no affect on the accept filter state. 49132649Srwatson * - That we can't attach an accept filter to a socket that isn't in the 50132649Srwatson * listen state. 51132649Srwatson * - That after we fail to attach the filter, querying the kernel shows no 52132649Srwatson * filter attached. 53132649Srwatson * - That we can attach an accept filter to a socket that is in the listen 54132649Srwatson * state. 55132649Srwatson * - That once an accept filter is attached, we can query to make sure it is 56132649Srwatson * attached. 57147300Smaxim * - That once an accept filter is attached, we can remove it and query to 58147300Smaxim * make sure it is removed. 59132649Srwatson */ 60132649Srwatsonint 61132649Srwatsonmain(int argc, char *argv[]) 62132649Srwatson{ 63132649Srwatson struct accept_filter_arg afa; 64132649Srwatson struct sockaddr_in sin; 65132649Srwatson socklen_t len; 66132649Srwatson int lso, ret; 67132649Srwatson 68147300Smaxim printf("1..11\n"); 69137587Snik 70132649Srwatson /* 71132649Srwatson * Step 0. Open socket(). 72132649Srwatson */ 73132649Srwatson lso = socket(PF_INET, SOCK_STREAM, 0); 74132649Srwatson if (lso == -1) 75137587Snik errx(-1, "not ok 1 - socket: %s", strerror(errno)); 76137587Snik printf("ok 1 - socket\n"); 77132649Srwatson 78132649Srwatson /* 79132649Srwatson * Step 1. After socket(). Should return EINVAL, since no accept 80132649Srwatson * filter should be attached. 81132649Srwatson */ 82132649Srwatson bzero(&afa, sizeof(afa)); 83132649Srwatson len = sizeof(afa); 84132649Srwatson ret = getsockopt(lso, SOL_SOCKET, SO_ACCEPTFILTER, &afa, &len); 85136844Srwatson if (ret != -1) 86137587Snik errx(-1, "not ok 2 - getsockopt() after socket() succeeded"); 87136844Srwatson if (errno != EINVAL) 88137587Snik errx(-1, "not ok 2 - getsockopt() after socket() failed with " 89136844Srwatson "%d (%s)", errno, strerror(errno)); 90137587Snik printf("ok 2 - getsockopt\n"); 91132649Srwatson 92132649Srwatson /* 93132649Srwatson * Step 2. Bind(). Ideally this will succeed. 94132649Srwatson */ 95132649Srwatson bzero(&sin, sizeof(sin)); 96132649Srwatson sin.sin_len = sizeof(sin); 97132649Srwatson sin.sin_family = AF_INET; 98132649Srwatson sin.sin_port = htons(8080); 99132649Srwatson sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 100132649Srwatson if (bind(lso, (struct sockaddr *)&sin, sizeof(sin)) < 0) 101137587Snik errx(-1, "not ok 3 - bind %s", strerror(errno)); 102137587Snik printf("ok 3 - bind\n"); 103132649Srwatson 104132649Srwatson /* 105132649Srwatson * Step 3: After bind(). getsockopt() should return EINVAL, since no 106132649Srwatson * accept filter should be attached. 107132649Srwatson */ 108132649Srwatson len = sizeof(afa); 109132649Srwatson ret = getsockopt(lso, SOL_SOCKET, SO_ACCEPTFILTER, &afa, &len); 110136844Srwatson if (ret != -1) 111137587Snik errx(-1, "not ok 4 - getsockopt() after bind() succeeded"); 112136844Srwatson if (errno != EINVAL) 113137587Snik errx(-1, "not ok 4 - getsockopt() after bind() failed with %d (%s)", 114136844Srwatson errno, strerror(errno)); 115137587Snik printf("ok 4 - getsockopt\n"); 116132649Srwatson 117132649Srwatson /* 118132649Srwatson * Step 4: Setsockopt() before listen(). Should fail, since it's not 119132649Srwatson * yet a listen() socket. 120132649Srwatson */ 121132649Srwatson bzero(&afa, sizeof(afa)); 122132649Srwatson strcpy(afa.af_name, ACCF_NAME); 123132649Srwatson ret = setsockopt(lso, SOL_SOCKET, SO_ACCEPTFILTER, &afa, sizeof(afa)); 124136844Srwatson if (ret == 0) 125137587Snik errx(-1, "not ok 5 - setsockopt() before listen() succeeded"); 126137587Snik printf("ok 5 - setsockopt\n"); 127132649Srwatson 128132649Srwatson /* 129132649Srwatson * Step 5: Getsockopt() after pre-listen() setsockopt(). Should 130132649Srwatson * fail with EINVAL, since setsockopt() should have failed. 131132649Srwatson */ 132132649Srwatson len = sizeof(afa); 133132649Srwatson ret = getsockopt(lso, SOL_SOCKET, SO_ACCEPTFILTER, &afa, &len); 134136844Srwatson if (ret == 0) 135137587Snik errx(-1, "not ok 6 - getsockopt() after pre-listen() setsockopt() " 136136844Srwatson "succeeded"); 137136844Srwatson if (errno != EINVAL) 138137587Snik errx(-1, "not ok 6 - pre-listen() getsockopt() failed with %d (%s)", 139136844Srwatson errno, strerror(errno)); 140137587Snik printf("ok 6 - getsockopt\n"); 141132649Srwatson 142132649Srwatson /* 143132649Srwatson * Step 6: listen(). 144132649Srwatson */ 145132649Srwatson if (listen(lso, -1) < 0) 146137587Snik errx(-1, "not ok 7 - listen: %s", strerror(errno)); 147137587Snik printf("ok 7 - listen\n"); 148132649Srwatson 149132649Srwatson /* 150147300Smaxim * Step 7: Getsockopt() after listen(). Should fail with EINVAL, 151147300Smaxim * since we have not installed accept filter yet. 152132649Srwatson */ 153147300Smaxim len = sizeof(afa); 154147300Smaxim ret = getsockopt(lso, SOL_SOCKET, SO_ACCEPTFILTER, &afa, &len); 155147300Smaxim if (ret == 0) 156147300Smaxim errx(-1, "not ok 8 - getsockopt() after listen() but before " 157147300Smaxim "setsockopt() succeeded"); 158147300Smaxim if (errno != EINVAL) 159147300Smaxim errx(-1, "not ok 8 - getsockopt() after listen() but before " 160147300Smaxim "setsockopt() failed with %d (%s)", errno, strerror(errno)); 161147300Smaxim printf("ok 8 - getsockopt\n"); 162147300Smaxim 163147300Smaxim /* 164147300Smaxim * Step 8: After listen(). This call to setsockopt() should succeed. 165147300Smaxim */ 166132649Srwatson bzero(&afa, sizeof(afa)); 167132649Srwatson strcpy(afa.af_name, ACCF_NAME); 168132649Srwatson ret = setsockopt(lso, SOL_SOCKET, SO_ACCEPTFILTER, &afa, sizeof(afa)); 169136844Srwatson if (ret != 0) 170147300Smaxim errx(-1, "not ok 9 - setsockopt() after listen() failed with %d " 171136844Srwatson "(%s)", errno, strerror(errno)); 172136844Srwatson if (len != sizeof(afa)) 173147300Smaxim errx(-1, "not ok 9 - setsockopt() after listen() returned wrong " 174136844Srwatson "size (%d vs expected %d)", len, sizeof(afa)); 175147300Smaxim printf("ok 9 - setsockopt\n"); 176132649Srwatson 177132649Srwatson /* 178147300Smaxim * Step 9: After setsockopt(). Should succeed and identify 179132649Srwatson * ACCF_NAME. 180132649Srwatson */ 181132649Srwatson bzero(&afa, sizeof(afa)); 182132649Srwatson len = sizeof(afa); 183132649Srwatson ret = getsockopt(lso, SOL_SOCKET, SO_ACCEPTFILTER, &afa, &len); 184136844Srwatson if (ret != 0) 185147300Smaxim errx(-1, "not ok 10 - getsockopt() after listen() setsockopt() " 186136844Srwatson "failed with %d (%s)", errno, strerror(errno)); 187136844Srwatson if (len != sizeof(afa)) 188147300Smaxim errx(-1, "not ok 10 - getsockopt() after setsockopet() after " 189136844Srwatson "listen() returned wrong size (got %d expected %d)", len, 190136844Srwatson sizeof(afa)); 191136844Srwatson if (strcmp(afa.af_name, ACCF_NAME) != 0) 192147300Smaxim errx(-1, "not ok 10 - getsockopt() after setsockopt() after " 193136844Srwatson "listen() mismatch (got %s expected %s)", afa.af_name, 194136844Srwatson ACCF_NAME); 195147300Smaxim printf("ok 10 - getsockopt\n"); 196132649Srwatson 197147300Smaxim /* 198147300Smaxim * Step 10: Remove accept filter. After removing the accept filter 199147300Smaxim * getsockopt() should fail with EINVAL. 200147300Smaxim */ 201147300Smaxim ret = setsockopt(lso, SOL_SOCKET, SO_ACCEPTFILTER, NULL, 0); 202147300Smaxim if (ret != 0) 203147300Smaxim errx(-1, "not ok 11 - setsockopt() after listen() " 204147300Smaxim "failed with %d (%s)", errno, strerror(errno)); 205147300Smaxim bzero(&afa, sizeof(afa)); 206147300Smaxim len = sizeof(afa); 207147300Smaxim ret = getsockopt(lso, SOL_SOCKET, SO_ACCEPTFILTER, &afa, &len); 208147300Smaxim if (ret == 0) 209147300Smaxim errx(-1, "not ok 11 - getsockopt() after removing " 210147300Smaxim "the accept filter returns valid accept filter %s", 211147300Smaxim afa.af_name); 212147300Smaxim if (errno != EINVAL) 213147300Smaxim errx(-1, "not ok 11 - getsockopt() after removing the accept" 214147300Smaxim "filter failed with %d (%s)", errno, strerror(errno)); 215147300Smaxim printf("ok 11 - setsockopt\n"); 216147300Smaxim 217132649Srwatson close(lso); 218132649Srwatson return (0); 219132649Srwatson} 220