Path: blob/main/tools/regression/netinet6/inet6_rth/inet6_rth-segments.c
39485 views
/*-1* Copyright (c) 2007 Michael Telahun Makonnen2* All rights reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9* 2. Redistributions in binary form must reproduce the above copyright10* notice, this list of conditions and the following disclaimer in the11* documentation and/or other materials provided with the distribution.12*13* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND14* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE15* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE16* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE17* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL18* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS19* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)20* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT21* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY22* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF23* SUCH DAMAGE.24*25*/2627#include <sys/types.h>28#include <sys/socket.h>2930#include <netinet/in.h>31#include <netinet/ip6.h>3233#include <netdb.h>34#include <stdio.h>35#include <stdlib.h>36#include <string.h>3738#include "test_subr.h"3940static void init_hdrs(struct msghdr *, struct cmsghdr *, char *, size_t);41static void test_cmsg_firsthdr();42static void test_cmsg_nexthdr();43static void test_rth_space();44static void test_rth_segments();45static void test_rth_add();46static void test_rth_init();4748int49main(int argc, char* argv[])50{51/*52* Initialize global variables.53*/54g_total = 0;55g_pass = 0;56g_fail = 0;57memset(g_funcname, 0, sizeof(g_funcname));5859/*60* Start the tests.61*/62printf("Starting inet6_rth_* and cmsg macro regression tests...\n");6364test_cmsg_firsthdr(); /* CMSG_FIRSTHDR */65test_cmsg_nexthdr(); /* CMSG_NEXTHDR */66test_rth_space(); /* inet6_rth_space */67test_rth_segments(); /* inet6_rth_segments */68test_rth_add(); /* inet6_rth_add */69test_rth_init(); /* inet6_rth_space */7071if (g_fail == 0)72printf("OK. ");73else74printf("NOT OK. ");75printf("Total: %d Pass: %d Fail: %d\n", g_total, g_pass, g_fail);7677return (g_fail);78}7980void81test_rth_init()82{83char buf[10240];84char *pbuf;8586set_funcname("test_rth_init", sizeof("test_rth_init\0"));8788pbuf = inet6_rth_init((void *)buf, 10, IPV6_RTHDR_TYPE_0, 100);89checkptr(NULL, pbuf, "buffer too small\0");9091pbuf = inet6_rth_init((void *)buf, 10240, IPV6_RTHDR_TYPE_0, 0);92checkptr((caddr_t)&buf, pbuf, "0 segments\0");9394pbuf = inet6_rth_init((void *)buf, 10240, IPV6_RTHDR_TYPE_0, 127);95checkptr((caddr_t)&buf, pbuf, "127 segments\0");9697pbuf = inet6_rth_init((void *)buf, 10240, IPV6_RTHDR_TYPE_0, -1);98checkptr(NULL, pbuf, "negative number of segments\0");99100pbuf = inet6_rth_init((void *)buf, 10240, IPV6_RTHDR_TYPE_0, 128);101checkptr(NULL, pbuf, "128 segments\0");102}103104void105test_rth_add()106{107int i, ret;108char buf[10240];109struct addrinfo *res;110struct addrinfo hints;111112set_funcname("test_rth_add", sizeof("test_rth_add\0"));113114if (NULL == inet6_rth_init(buf, 10240, IPV6_RTHDR_TYPE_0, 127))115abort();116memset((void *)&hints, 0, sizeof(struct addrinfo));117hints.ai_family = AF_INET6;118hints.ai_flags = AI_NUMERICHOST;119if (0 != getaddrinfo("::1", NULL, (const struct addrinfo *)&hints, &res))120abort();121for (i = 0; i < 127; i++)122inet6_rth_add((void *)buf,123&((struct sockaddr_in6 *)(res->ai_addr))->sin6_addr);124checknum(127, ((struct ip6_rthdr0 *)buf)->ip6r0_segleft, 0,125"add 127 segments\0");126127ret = inet6_rth_add((void *)buf,128&((struct sockaddr_in6 *)(res->ai_addr))->sin6_addr);129checknum(-1, ret, 0, "add 128th segment to 127 segment header\0");130131freeaddrinfo(res);132}133134void135test_rth_segments()136{137int seg;138char buf[10240];139140set_funcname("test_rth_segments", sizeof("test_rth_segments\0"));141142/*143* Test: invalid routing header type.144*/145if (NULL == inet6_rth_init((void *)buf, 10240, IPV6_RTHDR_TYPE_0, 0))146abort();147((struct ip6_rthdr *)buf)->ip6r_type = ~IPV6_RTHDR_TYPE_0;148seg = inet6_rth_segments((const void *)buf);149checknum(-1, seg, 0, "invalid routing header type\0");150151/*152* Test: 0 segments.153*/154if (NULL == inet6_rth_init((void *)buf, 10240, IPV6_RTHDR_TYPE_0, 0))155abort();156seg = inet6_rth_segments((const void *)buf);157checknum(0, seg, 0, "0 segments\0");158159/*160* Test: 127 segments.161*/162if (NULL == inet6_rth_init((void *)buf, 10240, IPV6_RTHDR_TYPE_0, 127))163abort();164seg = inet6_rth_segments((const void *)buf);165checknum(127, seg, 0, "127 segments\0");166167/*168* Test: -1 segments.169*/170/*171if (NULL == inet6_rth_init((void *)buf, 10240, IPV6_RTHDR_TYPE_0, 0))172abort();173((struct ip6_rthdr0 *)buf)->ip6r0_len = -1 * 2;174seg = inet6_rth_segments((const void *)buf);175checknum(-1, seg, 0, "-1 segments\0");176*/177/*178* Test: 128 segments.179*/180/*181if (NULL == inet6_rth_init((void *)buf, 10240, IPV6_RTHDR_TYPE_0, 127))182abort();183((struct ip6_rthdr0 *)buf)->ip6r0_len = 128 * 2;184seg = inet6_rth_segments((const void *)buf);185checknum(-1, seg, 0, "128 segments\0");186*/187}188189void190test_rth_space()191{192socklen_t len;193194set_funcname("test_rth_space", sizeof("test_rth_space\0"));195196/*197* Test: invalid routing header type.198*/199len = inet6_rth_space(~IPV6_RTHDR_TYPE_0, 0);200checknum(0, len, 0, "invalid routing header type\0");201202/*203* Test: valid number of segments.204*/205len = inet6_rth_space(IPV6_RTHDR_TYPE_0, 0);206checknum(0, len, 1, "0 segments\0");207len = inet6_rth_space(IPV6_RTHDR_TYPE_0, 127);208checknum(0, len, 1, "0 segments\0");209210/*211* Test: invalid number of segments.212*/213len = inet6_rth_space(IPV6_RTHDR_TYPE_0, -1);214checknum(0, len, 0, "-1 segments\0");215len = inet6_rth_space(IPV6_RTHDR_TYPE_0, 128);216checknum(0, len, 0, "128 segments\0");217}218219void220test_cmsg_nexthdr()221{222struct msghdr mh;223struct cmsghdr cmh;224struct cmsghdr *cmhp, *cmhnextp;225char ancbuf[10240];226char magic[] = "MAGIC";227228set_funcname("test_cmsg_nexthdr", sizeof("test_cmsg_nexthdr"));229230/*231* Test: More than one cmsghdr232*/233init_hdrs(&mh, &cmh, ancbuf, sizeof(ancbuf));234mh.msg_control = (caddr_t)ancbuf;235mh.msg_controllen = CMSG_SPACE(0) * 2; /* 2 cmsghdr with no data */236cmh.cmsg_len = CMSG_LEN(0);237238/*239* Copy the same instance of cmsghdr twice. Use a magic value240* to id the second copy.241*/242bcopy((void *)&cmh, (void *)ancbuf, sizeof(cmh));243strlcpy((char *)&cmh, (const char *)&magic, sizeof(magic));244bcopy((void *)&cmh,245(void *)((caddr_t)ancbuf + CMSG_SPACE(0)),246sizeof(cmh));247cmhp = CMSG_FIRSTHDR(&mh);248cmhnextp = CMSG_NXTHDR(&mh, cmhp);249checkstr((const char *)&magic, (const char *)cmhnextp, sizeof(magic),250"more than one cmsghdr\0");251252/*253* Test: only one cmsghdr254*/255init_hdrs(&mh, &cmh, ancbuf, sizeof(ancbuf));256mh.msg_control = (caddr_t)ancbuf;257mh.msg_controllen = CMSG_SPACE(0);258cmh.cmsg_len = CMSG_LEN(0);259bcopy((void *)&cmh, (void *)ancbuf, sizeof(cmh));260cmhp = CMSG_FIRSTHDR(&mh);261cmhnextp = CMSG_NXTHDR(&mh, cmhp);262checkptr(NULL, (caddr_t)cmhnextp, "only one cmsghdr\0");263264/*265* Test: NULL cmsg pointer266*/267init_hdrs(&mh, &cmh, ancbuf, sizeof(ancbuf));268mh.msg_control = (caddr_t)ancbuf;269mh.msg_controllen = sizeof(ancbuf);270cmh.cmsg_len = sizeof(ancbuf);271bcopy((void *)&cmh, (void *)ancbuf, sizeof(cmh));272cmhp = CMSG_FIRSTHDR(&mh);273cmhnextp = CMSG_NXTHDR(&mh, NULL);274checkptr((caddr_t)cmhp, (caddr_t)cmhnextp, "null second argument\0");275}276277void278test_cmsg_firsthdr()279{280struct msghdr mh;281struct cmsghdr cmh;282struct cmsghdr *cmhp;283char ancbuf[1024];284char magic[] = "MAGIC";285286set_funcname("test_cmsg_firsthdr", sizeof("test_cmsg_firsthdr"));287288/* CMSG_FIRSTHDR() where msg_control is NULL */289init_hdrs(&mh, NULL, NULL, 0);290mh.msg_control = NULL;291cmhp = CMSG_FIRSTHDR(&mh);292checkptr(NULL, (caddr_t)cmhp,293"msg_control is NULL\0");294295/* - where msg_controllen < sizeof cmsghdr */296init_hdrs(&mh, NULL, NULL, 0);297mh.msg_control = (caddr_t)&cmh;298mh.msg_controllen = sizeof(cmh) - 1;299cmhp = CMSG_FIRSTHDR(&mh);300checkptr(NULL, (caddr_t)cmhp,301"msg_controllen < sizeof cmsghdr\0");302303/* - where msg_controllen == 0 */304init_hdrs(&mh, NULL, NULL, 0);305mh.msg_control = (caddr_t)&cmh;306mh.msg_controllen = 0;307cmhp = CMSG_FIRSTHDR(&mh);308checkptr(NULL, (caddr_t)cmhp,309"msg_controllen == 0\0");310311/* no errors */312init_hdrs(&mh, &cmh, ancbuf, sizeof(ancbuf));313memset((void *)ancbuf, 0, sizeof(ancbuf));314mh.msg_control = (caddr_t)ancbuf;315mh.msg_controllen = sizeof(ancbuf);316strlcpy((char *)&cmh, (const char *)&magic, sizeof(magic));317bcopy((void *)&cmh, (void *)ancbuf, sizeof(cmh));318cmhp = CMSG_FIRSTHDR(&mh);319checkstr((const char *)&magic, (const char *)cmhp, sizeof(magic),320"with payload\0");321}322323void324init_hdrs(struct msghdr *mhp, struct cmsghdr *cmhp, char *bufp, size_t bufsize)325{326if (mhp != NULL)327memset((void *)mhp, 0, sizeof(struct msghdr));328if (cmhp != NULL)329memset((void *)cmhp, 0, sizeof(struct cmsghdr));330if (bufp != NULL)331memset((void *)bufp, 0, bufsize);332}333334335