1168925Smtm/*- 2168925Smtm * Copyright (c) 2007 Michael Telahun Makonnen 3168925Smtm * All rights reserved. 4168925Smtm * 5168925Smtm * Redistribution and use in source and binary forms, with or without 6168925Smtm * modification, are permitted provided that the following conditions 7168925Smtm * are met: 8168925Smtm * 1. Redistributions of source code must retain the above copyright 9168925Smtm * notice, this list of conditions and the following disclaimer. 10168925Smtm * 2. Redistributions in binary form must reproduce the above copyright 11168925Smtm * notice, this list of conditions and the following disclaimer in the 12168925Smtm * documentation and/or other materials provided with the distribution. 13168925Smtm * 14168925Smtm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15168925Smtm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16168925Smtm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17168925Smtm * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18168925Smtm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19168925Smtm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20168925Smtm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21168925Smtm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22168925Smtm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23168925Smtm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24168925Smtm * SUCH DAMAGE. 25168925Smtm * 26168925Smtm */ 27168925Smtm 28168925Smtm#include <sys/cdefs.h> 29168925Smtm__FBSDID("$FreeBSD: releng/11.0/tools/regression/netinet6/inet6_rth/inet6_rth-segments.c 168925 2007-04-21 11:23:33Z mtm $"); 30168925Smtm 31168925Smtm#include <sys/types.h> 32168925Smtm#include <sys/socket.h> 33168925Smtm 34168925Smtm#include <netinet/in.h> 35168925Smtm#include <netinet/ip6.h> 36168925Smtm 37168925Smtm#include <netdb.h> 38168925Smtm#include <stdio.h> 39168925Smtm#include <stdlib.h> 40168925Smtm#include <string.h> 41168925Smtm 42168925Smtm#include "test_subr.h" 43168925Smtm 44168925Smtmstatic void init_hdrs(struct msghdr *, struct cmsghdr *, char *, size_t); 45168925Smtmstatic void test_cmsg_firsthdr(); 46168925Smtmstatic void test_cmsg_nexthdr(); 47168925Smtmstatic void test_rth_space(); 48168925Smtmstatic void test_rth_segments(); 49168925Smtmstatic void test_rth_add(); 50168925Smtmstatic void test_rth_init(); 51168925Smtm 52168925Smtmint 53168925Smtmmain(int argc, char* argv[]) 54168925Smtm{ 55168925Smtm /* 56168925Smtm * Initialize global variables. 57168925Smtm */ 58168925Smtm g_total = 0; 59168925Smtm g_pass = 0; 60168925Smtm g_fail = 0; 61168925Smtm memset(g_funcname, 0, sizeof(g_funcname)); 62168925Smtm 63168925Smtm /* 64168925Smtm * Start the tests. 65168925Smtm */ 66168925Smtm printf("Starting inet6_rth_* and cmsg macro regression tests...\n"); 67168925Smtm 68168925Smtm test_cmsg_firsthdr(); /* CMSG_FIRSTHDR */ 69168925Smtm test_cmsg_nexthdr(); /* CMSG_NEXTHDR */ 70168925Smtm test_rth_space(); /* inet6_rth_space */ 71168925Smtm test_rth_segments(); /* inet6_rth_segments */ 72168925Smtm test_rth_add(); /* inet6_rth_add */ 73168925Smtm test_rth_init(); /* inet6_rth_space */ 74168925Smtm 75168925Smtm if (g_fail == 0) 76168925Smtm printf("OK. "); 77168925Smtm else 78168925Smtm printf("NOT OK. "); 79168925Smtm printf("Total: %d Pass: %d Fail: %d\n", g_total, g_pass, g_fail); 80168925Smtm 81168925Smtm return (g_fail); 82168925Smtm} 83168925Smtm 84168925Smtmvoid 85168925Smtmtest_rth_init() 86168925Smtm{ 87168925Smtm char buf[10240]; 88168925Smtm char *pbuf; 89168925Smtm 90168925Smtm set_funcname("test_rth_init", sizeof("test_rth_init\0")); 91168925Smtm 92168925Smtm pbuf = inet6_rth_init((void *)buf, 10, IPV6_RTHDR_TYPE_0, 100); 93168925Smtm checkptr(NULL, pbuf, "buffer too small\0"); 94168925Smtm 95168925Smtm pbuf = inet6_rth_init((void *)buf, 10240, IPV6_RTHDR_TYPE_0, 0); 96168925Smtm checkptr((caddr_t)&buf, pbuf, "0 segments\0"); 97168925Smtm 98168925Smtm pbuf = inet6_rth_init((void *)buf, 10240, IPV6_RTHDR_TYPE_0, 127); 99168925Smtm checkptr((caddr_t)&buf, pbuf, "127 segments\0"); 100168925Smtm 101168925Smtm pbuf = inet6_rth_init((void *)buf, 10240, IPV6_RTHDR_TYPE_0, -1); 102168925Smtm checkptr(NULL, pbuf, "negative number of segments\0"); 103168925Smtm 104168925Smtm pbuf = inet6_rth_init((void *)buf, 10240, IPV6_RTHDR_TYPE_0, 128); 105168925Smtm checkptr(NULL, pbuf, "128 segments\0"); 106168925Smtm} 107168925Smtm 108168925Smtmvoid 109168925Smtmtest_rth_add() 110168925Smtm{ 111168925Smtm int i, ret; 112168925Smtm char buf[10240]; 113168925Smtm struct addrinfo *res; 114168925Smtm struct addrinfo hints; 115168925Smtm 116168925Smtm set_funcname("test_rth_add", sizeof("test_rth_add\0")); 117168925Smtm 118168925Smtm if (NULL == inet6_rth_init(buf, 10240, IPV6_RTHDR_TYPE_0, 127)) 119168925Smtm abort(); 120168925Smtm memset((void *)&hints, 0, sizeof(struct addrinfo)); 121168925Smtm hints.ai_family = AF_INET6; 122168925Smtm hints.ai_flags = AI_NUMERICHOST; 123168925Smtm if (0 != getaddrinfo("::1", NULL, (const struct addrinfo *)&hints, &res)) 124168925Smtm abort(); 125168925Smtm for (i = 0; i < 127; i++) 126168925Smtm inet6_rth_add((void *)buf, 127168925Smtm &((struct sockaddr_in6 *)(res->ai_addr))->sin6_addr); 128168925Smtm checknum(127, ((struct ip6_rthdr0 *)buf)->ip6r0_segleft, 0, 129168925Smtm "add 127 segments\0"); 130168925Smtm 131168925Smtm ret = inet6_rth_add((void *)buf, 132168925Smtm &((struct sockaddr_in6 *)(res->ai_addr))->sin6_addr); 133168925Smtm checknum(-1, ret, 0, "add 128th segment to 127 segment header\0"); 134168925Smtm 135168925Smtm freeaddrinfo(res); 136168925Smtm} 137168925Smtm 138168925Smtmvoid 139168925Smtmtest_rth_segments() 140168925Smtm{ 141168925Smtm int seg; 142168925Smtm char buf[10240]; 143168925Smtm 144168925Smtm set_funcname("test_rth_segments", sizeof("test_rth_segments\0")); 145168925Smtm 146168925Smtm /* 147168925Smtm * Test: invalid routing header type. 148168925Smtm */ 149168925Smtm if (NULL == inet6_rth_init((void *)buf, 10240, IPV6_RTHDR_TYPE_0, 0)) 150168925Smtm abort(); 151168925Smtm ((struct ip6_rthdr *)buf)->ip6r_type = ~IPV6_RTHDR_TYPE_0; 152168925Smtm seg = inet6_rth_segments((const void *)buf); 153168925Smtm checknum(-1, seg, 0, "invalid routing header type\0"); 154168925Smtm 155168925Smtm /* 156168925Smtm * Test: 0 segments. 157168925Smtm */ 158168925Smtm if (NULL == inet6_rth_init((void *)buf, 10240, IPV6_RTHDR_TYPE_0, 0)) 159168925Smtm abort(); 160168925Smtm seg = inet6_rth_segments((const void *)buf); 161168925Smtm checknum(0, seg, 0, "0 segments\0"); 162168925Smtm 163168925Smtm /* 164168925Smtm * Test: 127 segments. 165168925Smtm */ 166168925Smtm if (NULL == inet6_rth_init((void *)buf, 10240, IPV6_RTHDR_TYPE_0, 127)) 167168925Smtm abort(); 168168925Smtm seg = inet6_rth_segments((const void *)buf); 169168925Smtm checknum(127, seg, 0, "127 segments\0"); 170168925Smtm 171168925Smtm /* 172168925Smtm * Test: -1 segments. 173168925Smtm */ 174168925Smtm/* 175168925Smtm if (NULL == inet6_rth_init((void *)buf, 10240, IPV6_RTHDR_TYPE_0, 0)) 176168925Smtm abort(); 177168925Smtm ((struct ip6_rthdr0 *)buf)->ip6r0_len = -1 * 2; 178168925Smtm seg = inet6_rth_segments((const void *)buf); 179168925Smtm checknum(-1, seg, 0, "-1 segments\0"); 180168925Smtm*/ 181168925Smtm /* 182168925Smtm * Test: 128 segments. 183168925Smtm */ 184168925Smtm/* 185168925Smtm if (NULL == inet6_rth_init((void *)buf, 10240, IPV6_RTHDR_TYPE_0, 127)) 186168925Smtm abort(); 187168925Smtm ((struct ip6_rthdr0 *)buf)->ip6r0_len = 128 * 2; 188168925Smtm seg = inet6_rth_segments((const void *)buf); 189168925Smtm checknum(-1, seg, 0, "128 segments\0"); 190168925Smtm*/ 191168925Smtm} 192168925Smtm 193168925Smtmvoid 194168925Smtmtest_rth_space() 195168925Smtm{ 196168925Smtm socklen_t len; 197168925Smtm 198168925Smtm set_funcname("test_rth_space", sizeof("test_rth_space\0")); 199168925Smtm 200168925Smtm /* 201168925Smtm * Test: invalid routing header type. 202168925Smtm */ 203168925Smtm len = inet6_rth_space(~IPV6_RTHDR_TYPE_0, 0); 204168925Smtm checknum(0, len, 0, "invalid routing header type\0"); 205168925Smtm 206168925Smtm /* 207168925Smtm * Test: valid number of segments. 208168925Smtm */ 209168925Smtm len = inet6_rth_space(IPV6_RTHDR_TYPE_0, 0); 210168925Smtm checknum(0, len, 1, "0 segments\0"); 211168925Smtm len = inet6_rth_space(IPV6_RTHDR_TYPE_0, 127); 212168925Smtm checknum(0, len, 1, "0 segments\0"); 213168925Smtm 214168925Smtm /* 215168925Smtm * Test: invalid number of segments. 216168925Smtm */ 217168925Smtm len = inet6_rth_space(IPV6_RTHDR_TYPE_0, -1); 218168925Smtm checknum(0, len, 0, "-1 segments\0"); 219168925Smtm len = inet6_rth_space(IPV6_RTHDR_TYPE_0, 128); 220168925Smtm checknum(0, len, 0, "128 segments\0"); 221168925Smtm} 222168925Smtm 223168925Smtmvoid 224168925Smtmtest_cmsg_nexthdr() 225168925Smtm{ 226168925Smtm struct msghdr mh; 227168925Smtm struct cmsghdr cmh; 228168925Smtm struct cmsghdr *cmhp, *cmhnextp; 229168925Smtm char ancbuf[10240]; 230168925Smtm char magic[] = "MAGIC"; 231168925Smtm 232168925Smtm set_funcname("test_cmsg_nexthdr", sizeof("test_cmsg_nexthdr")); 233168925Smtm 234168925Smtm /* 235168925Smtm * Test: More than one cmsghdr 236168925Smtm */ 237168925Smtm init_hdrs(&mh, &cmh, ancbuf, sizeof(ancbuf)); 238168925Smtm mh.msg_control = (caddr_t)ancbuf; 239168925Smtm mh.msg_controllen = CMSG_SPACE(0) * 2; /* 2 cmsghdr with no data */ 240168925Smtm cmh.cmsg_len = CMSG_LEN(0); 241168925Smtm 242168925Smtm /* 243168925Smtm * Copy the same instance of cmsghdr twice. Use a magic value 244168925Smtm * to id the second copy. 245168925Smtm */ 246168925Smtm bcopy((void *)&cmh, (void *)ancbuf, sizeof(cmh)); 247168925Smtm strlcpy((char *)&cmh, (const char *)&magic, sizeof(magic)); 248168925Smtm bcopy((void *)&cmh, 249168925Smtm (void *)((caddr_t)ancbuf + CMSG_SPACE(0)), 250168925Smtm sizeof(cmh)); 251168925Smtm cmhp = CMSG_FIRSTHDR(&mh); 252168925Smtm cmhnextp = CMSG_NXTHDR(&mh, cmhp); 253168925Smtm checkstr((const char *)&magic, (const char *)cmhnextp, sizeof(magic), 254168925Smtm "more than one cmsghdr\0"); 255168925Smtm 256168925Smtm /* 257168925Smtm * Test: only one cmsghdr 258168925Smtm */ 259168925Smtm init_hdrs(&mh, &cmh, ancbuf, sizeof(ancbuf)); 260168925Smtm mh.msg_control = (caddr_t)ancbuf; 261168925Smtm mh.msg_controllen = CMSG_SPACE(0); 262168925Smtm cmh.cmsg_len = CMSG_LEN(0); 263168925Smtm bcopy((void *)&cmh, (void *)ancbuf, sizeof(cmh)); 264168925Smtm cmhp = CMSG_FIRSTHDR(&mh); 265168925Smtm cmhnextp = CMSG_NXTHDR(&mh, cmhp); 266168925Smtm checkptr(NULL, (caddr_t)cmhnextp, "only one cmsghdr\0"); 267168925Smtm 268168925Smtm /* 269168925Smtm * Test: NULL cmsg pointer 270168925Smtm */ 271168925Smtm init_hdrs(&mh, &cmh, ancbuf, sizeof(ancbuf)); 272168925Smtm mh.msg_control = (caddr_t)ancbuf; 273168925Smtm mh.msg_controllen = sizeof(ancbuf); 274168925Smtm cmh.cmsg_len = sizeof(ancbuf); 275168925Smtm bcopy((void *)&cmh, (void *)ancbuf, sizeof(cmh)); 276168925Smtm cmhp = CMSG_FIRSTHDR(&mh); 277168925Smtm cmhnextp = CMSG_NXTHDR(&mh, NULL); 278168925Smtm checkptr((caddr_t)cmhp, (caddr_t)cmhnextp, "null second argument\0"); 279168925Smtm} 280168925Smtm 281168925Smtmvoid 282168925Smtmtest_cmsg_firsthdr() 283168925Smtm{ 284168925Smtm struct msghdr mh; 285168925Smtm struct cmsghdr cmh; 286168925Smtm struct cmsghdr *cmhp; 287168925Smtm char ancbuf[1024]; 288168925Smtm char magic[] = "MAGIC"; 289168925Smtm 290168925Smtm set_funcname("test_cmsg_firsthdr", sizeof("test_cmsg_firsthdr")); 291168925Smtm 292168925Smtm /* CMSG_FIRSTHDR() where msg_control is NULL */ 293168925Smtm init_hdrs(&mh, NULL, NULL, 0); 294168925Smtm mh.msg_control = NULL; 295168925Smtm cmhp = CMSG_FIRSTHDR(&mh); 296168925Smtm checkptr(NULL, (caddr_t)cmhp, 297168925Smtm "msg_control is NULL\0"); 298168925Smtm 299168925Smtm /* - where msg_controllen < sizeof cmsghdr */ 300168925Smtm init_hdrs(&mh, NULL, NULL, 0); 301168925Smtm mh.msg_control = (caddr_t)&cmh; 302168925Smtm mh.msg_controllen = sizeof(cmh) - 1; 303168925Smtm cmhp = CMSG_FIRSTHDR(&mh); 304168925Smtm checkptr(NULL, (caddr_t)cmhp, 305168925Smtm "msg_controllen < sizeof cmsghdr\0"); 306168925Smtm 307168925Smtm /* - where msg_controllen == 0 */ 308168925Smtm init_hdrs(&mh, NULL, NULL, 0); 309168925Smtm mh.msg_control = (caddr_t)&cmh; 310168925Smtm mh.msg_controllen = 0; 311168925Smtm cmhp = CMSG_FIRSTHDR(&mh); 312168925Smtm checkptr(NULL, (caddr_t)cmhp, 313168925Smtm "msg_controllen == 0\0"); 314168925Smtm 315168925Smtm /* no errors */ 316168925Smtm init_hdrs(&mh, &cmh, ancbuf, sizeof(ancbuf)); 317168925Smtm memset((void *)ancbuf, 0, sizeof(ancbuf)); 318168925Smtm mh.msg_control = (caddr_t)ancbuf; 319168925Smtm mh.msg_controllen = sizeof(ancbuf); 320168925Smtm strlcpy((char *)&cmh, (const char *)&magic, sizeof(magic)); 321168925Smtm bcopy((void *)&cmh, (void *)ancbuf, sizeof(cmh)); 322168925Smtm cmhp = CMSG_FIRSTHDR(&mh); 323168925Smtm checkstr((const char *)&magic, (const char *)cmhp, sizeof(magic), 324168925Smtm "with payload\0"); 325168925Smtm} 326168925Smtm 327168925Smtmvoid 328168925Smtminit_hdrs(struct msghdr *mhp, struct cmsghdr *cmhp, char *bufp, size_t bufsize) 329168925Smtm{ 330168925Smtm if (mhp != NULL) 331168925Smtm memset((void *)mhp, 0, sizeof(struct msghdr)); 332168925Smtm if (cmhp != NULL) 333168925Smtm memset((void *)cmhp, 0, sizeof(struct cmsghdr)); 334168925Smtm if (bufp != NULL) 335168925Smtm memset((void *)bufp, 0, bufsize); 336168925Smtm} 337