| /* |
| * |
| * Copyright (c) International Business Machines Corp., 2001 |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by |
| * the Free Software Foundation; either version 2 of the License, or |
| * (at your option) any later version. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See |
| * the GNU General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public License |
| * along with this program; if not, write to the Free Software |
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| */ |
| |
| /* |
| * Test Name: in6_01 |
| * |
| * Test Description: |
| * Verify that in6 and sockaddr fields are present. Most of these are |
| * "PASS" if they just compile. |
| * |
| * Usage: <for command-line> |
| * in6_01 |
| * |
| * HISTORY |
| * 05/2004 written by David L Stevens |
| * |
| * RESTRICTIONS: |
| * None. |
| * |
| */ |
| |
| #include <stdio.h> |
| #include <unistd.h> |
| #include <errno.h> |
| |
| #include <netinet/in.h> |
| #include <arpa/inet.h> |
| |
| #include "test.h" |
| |
| char *TCID = "in6_01"; /* Test program identifier. */ |
| |
| void setup(void), cleanup(void); |
| |
| struct { |
| char *addr; |
| int ismap; |
| } maptab[] = { |
| { |
| "2002::1", 0}, { |
| "::ffff:10.0.0.1", 1}, { |
| "::fffe:10.0.0.1", 0}, { |
| "::7fff:10.0.0.1", 0}, { |
| "0:0:0:0:0:0:ffff:0a001", 1}, { |
| "0:0:1:0:0:0:ffff:0a001", 0},}; |
| |
| #define MAPSIZE (sizeof(maptab)/sizeof(maptab[0])) |
| |
| struct { |
| char *addr; |
| } sstab[] = { |
| { |
| "2002::1"}, { |
| "10.0.0.1"}, { |
| "::ffff:10.0.0.1"}, { |
| "::1"}, { |
| "::"},}; |
| |
| #define SSSIZE (sizeof(sstab)/sizeof(sstab[0])) |
| |
| int TST_TOTAL = 9 + MAPSIZE + SSSIZE; |
| |
| int main(int argc, char *argv[]) |
| { |
| uint8_t ui8 = 1; |
| uint32_t ui16 = 2; |
| uint32_t ui32 = 3; |
| struct in6_addr in6; |
| struct in6_addr ina6 = IN6ADDR_ANY_INIT; |
| struct in6_addr inl6 = IN6ADDR_LOOPBACK_INIT; |
| struct sockaddr_in6 sin6; |
| struct sockaddr_storage ss; |
| int i; |
| const char *msg; |
| |
| /* Parse standard options given to run the test. */ |
| msg = parse_opts(argc, argv, NULL, NULL); |
| if (msg != NULL) { |
| tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); |
| } |
| |
| setup(); |
| |
| /* struct in6_addr tests */ |
| in6.s6_addr[0] = ui8; |
| tst_resm(TPASS, "type of in6.s6_addr[0] is uint8_t"); |
| if (sizeof(in6.s6_addr) != 16) |
| tst_resm(TFAIL, "sizeof(in6.s6_addr) != 16"); |
| else |
| tst_resm(TPASS, "sizeof(in6.s6_addr) == 16"); |
| |
| /* struct sockaddr_in6 tests */ |
| sin6.sin6_family = AF_INET6; |
| sin6.sin6_port = ui16; |
| sin6.sin6_flowinfo = ui32; |
| sin6.sin6_addr = in6; |
| sin6.sin6_scope_id = ui32; |
| tst_resm(TPASS, "all sockaddr_in6 fields present and correct"); |
| |
| /* initializers and global in6 definitions tests */ |
| tst_resm(TPASS, "IN6ADDR_ANY_INIT present"); |
| if (memcmp(&ina6, &in6addr_any, sizeof(ina6)) == 0) |
| tst_resm(TPASS, "in6addr_any present and correct"); |
| else |
| tst_resm(TFAIL, "in6addr_any incorrect value"); |
| tst_resm(TPASS, "IN6ADDR_LOOPBACK_INIT present"); |
| if (memcmp(&inl6, &in6addr_loopback, sizeof(inl6)) == 0) |
| tst_resm(TPASS, "in6addr_loopback present and correct"); |
| else |
| tst_resm(TFAIL, "in6addr_loopback incorrect value"); |
| if (inet_pton(AF_INET6, "::1", &inl6) <= 0) |
| tst_resm(TBROK, "inet_pton(\"::1\")"); |
| else if (memcmp(&inl6, &in6addr_loopback, sizeof(inl6)) == 0) |
| tst_resm(TPASS, "in6addr_loopback in network byte order"); |
| else |
| tst_resm(TFAIL, "in6addr_loopback has wrong byte order"); |
| |
| /* IN6_IS_ADDR_V4MAPPED tests */ |
| |
| for (i = 0; i < MAPSIZE; ++i) { |
| if (inet_pton(AF_INET6, maptab[i].addr, &in6) <= 0) { |
| tst_resm(TBROK, "\"%s\" is not a valid IPv6 address", |
| maptab[i].addr); |
| continue; |
| } |
| TEST(IN6_IS_ADDR_V4MAPPED(in6.s6_addr)); |
| if (TEST_RETURN == maptab[i].ismap) |
| tst_resm(TEST_RETURN == maptab[i].ismap ? TPASS : TFAIL, |
| "IN6_IS_ADDR_V4MAPPED(\"%s\") %ld", |
| maptab[i].addr, TEST_RETURN); |
| } |
| |
| /* sockaddr_storage tests */ |
| |
| if (sizeof(ss) <= sizeof(struct sockaddr_in) || |
| sizeof(ss) <= sizeof(struct sockaddr_in6)) |
| tst_resm(TFAIL, "sockaddr_storage too small"); |
| else |
| tst_resm(TPASS, "sockaddr_storage size ok"); |
| for (i = 0; i < SSSIZE; ++i) { |
| struct sockaddr_in *psin = (struct sockaddr_in *)&ss; |
| struct sockaddr_in6 *psin6 = (struct sockaddr_in6 *)&ss; |
| int rv; |
| uint8_t af; |
| |
| af = psin->sin_family = AF_INET; |
| rv = inet_pton(AF_INET, sstab[i].addr, &psin->sin_addr); |
| if (rv == 0) { |
| af = psin6->sin6_family = AF_INET6; |
| rv = inet_pton(AF_INET6, sstab[i].addr, |
| &psin6->sin6_addr); |
| } |
| if (rv <= 0) { |
| tst_resm(TBROK, "\"%s\" is not a valid address", |
| sstab[i].addr); |
| continue; |
| } |
| if (ss.ss_family == af) |
| tst_resm(TPASS, "\"%s\" is AF_INET%s", |
| sstab[i].addr, af == AF_INET ? "" : "6"); |
| else |
| tst_resm(TFAIL, "\"%s\" ss_family (%d) != AF_INET%s", |
| sstab[i].addr, af, af == AF_INET ? "" : "6"); |
| } |
| |
| cleanup(); |
| |
| return (0); |
| } |
| |
| pid_t pid; |
| |
| void setup(void) |
| { |
| TEST_PAUSE; /* if -P option specified */ |
| } |
| |
| void cleanup(void) |
| { |
| } |