1570af302Sopenharmony_ci// inet_addr, inet_ntoa, inet_pton and inet_ntop tests with roundtrip check 2570af302Sopenharmony_ci#include <errno.h> 3570af302Sopenharmony_ci#include <string.h> 4570af302Sopenharmony_ci#include <stdio.h> 5570af302Sopenharmony_ci#include <arpa/inet.h> 6570af302Sopenharmony_ci#include "test.h" 7570af302Sopenharmony_ci 8570af302Sopenharmony_cistatic int digit(int c) 9570af302Sopenharmony_ci{ 10570af302Sopenharmony_ci c-='0'; 11570af302Sopenharmony_ci if (c>9) c-='a'-'0'-10; 12570af302Sopenharmony_ci return c; 13570af302Sopenharmony_ci} 14570af302Sopenharmony_ci 15570af302Sopenharmony_cistatic void tobin(void *d, char *s) 16570af302Sopenharmony_ci{ 17570af302Sopenharmony_ci int i; 18570af302Sopenharmony_ci unsigned char *p = d; 19570af302Sopenharmony_ci for (i=0; s[2*i]; i++) p[i] = digit(s[2*i])*16+digit(s[2*i+1]); 20570af302Sopenharmony_ci} 21570af302Sopenharmony_ci 22570af302Sopenharmony_cistatic void tohex(char *d, void *s, int n) 23570af302Sopenharmony_ci{ 24570af302Sopenharmony_ci int i; 25570af302Sopenharmony_ci unsigned char *p = s; 26570af302Sopenharmony_ci for (i=0; i<n; i++) sprintf(d+2*i, "%02x", p[i]); 27570af302Sopenharmony_ci} 28570af302Sopenharmony_ci 29570af302Sopenharmony_ci#define V6(src,ret,hex) do{\ 30570af302Sopenharmony_ci int r; \ 31570af302Sopenharmony_ci char binaddr[16]={0}; \ 32570af302Sopenharmony_ci char hexaddr[40]={0}; \ 33570af302Sopenharmony_ci char txtaddr[60]={0}; \ 34570af302Sopenharmony_ci \ 35570af302Sopenharmony_ci r=inet_pton(AF_INET6,src,binaddr); \ 36570af302Sopenharmony_ci if (r!=ret) \ 37570af302Sopenharmony_ci t_error("inet_pton(AF_INET6, "#src", addr) returned %d, want %d\n", r, ret); \ 38570af302Sopenharmony_ci if (ret!=1) break; \ 39570af302Sopenharmony_ci tohex(hexaddr,binaddr,16); \ 40570af302Sopenharmony_ci if (strcmp(hexaddr,hex)) \ 41570af302Sopenharmony_ci t_error("inet_pton(AF_INET6, "#src", addr) got addr %s, want %s\n", hexaddr, hex); \ 42570af302Sopenharmony_ci \ 43570af302Sopenharmony_ci tobin(binaddr,hex); \ 44570af302Sopenharmony_ci if (inet_ntop(AF_INET6,binaddr,txtaddr,sizeof txtaddr)!=txtaddr) \ 45570af302Sopenharmony_ci t_error("inet_ntop(AF_INET6, <"#hex">, buf, size) did not return buf\n"); \ 46570af302Sopenharmony_ci if (inet_pton(AF_INET6,txtaddr,binaddr)!=1) \ 47570af302Sopenharmony_ci t_error("inet_ntop(AF_INET6, <"#hex">, buf, size) got %s, it is rejected by inet_pton\n", txtaddr); \ 48570af302Sopenharmony_ci tohex(hexaddr,binaddr,16); \ 49570af302Sopenharmony_ci if (strcmp(hexaddr,hex)) \ 50570af302Sopenharmony_ci t_error("inet_ntop(AF_INET6, <"#hex">, buf, size) got %s that is %s, want %s\n", txtaddr, hexaddr, hex); \ 51570af302Sopenharmony_ci if (strncmp(hex,"00000000000000000000ffff",24)==0 && !strchr(txtaddr,'.')) \ 52570af302Sopenharmony_ci t_error("inet_ntop(AF_INET6, <"#hex">, buf, size) got %s, should be ipv4 mapped\n", txtaddr); \ 53570af302Sopenharmony_ci}while(0); 54570af302Sopenharmony_ci 55570af302Sopenharmony_ci// ret and hex are the results of inet_pton and inet_addr respectively 56570af302Sopenharmony_ci#define V4(src,ret,hex) do{\ 57570af302Sopenharmony_ci int r; \ 58570af302Sopenharmony_ci uint32_t a; \ 59570af302Sopenharmony_ci struct in_addr in; \ 60570af302Sopenharmony_ci char buf[20]={0}; \ 61570af302Sopenharmony_ci char *p; \ 62570af302Sopenharmony_ci \ 63570af302Sopenharmony_ci a=inet_addr(src); \ 64570af302Sopenharmony_ci tohex(buf,&a,4); \ 65570af302Sopenharmony_ci if (strcmp(buf,hex)) \ 66570af302Sopenharmony_ci t_error("inet_addr("#src") returned %s, want %s\n", buf, hex); \ 67570af302Sopenharmony_ci \ 68570af302Sopenharmony_ci r=inet_pton(AF_INET,src,&a); \ 69570af302Sopenharmony_ci if (r!=ret) \ 70570af302Sopenharmony_ci t_error("inet_pton(AF_INET, "#src", addr) returned %d, want %d\n", r, ret); \ 71570af302Sopenharmony_ci \ 72570af302Sopenharmony_ci if (ret!=1) break; \ 73570af302Sopenharmony_ci \ 74570af302Sopenharmony_ci tohex(buf,&a,4); \ 75570af302Sopenharmony_ci if (strcmp(buf,hex)) \ 76570af302Sopenharmony_ci t_error("inet_pton(AF_INET, "#src", addr) got addr %s, want %s\n", buf, hex); \ 77570af302Sopenharmony_ci \ 78570af302Sopenharmony_ci tobin(&a,hex); \ 79570af302Sopenharmony_ci if (inet_ntop(AF_INET,&a,buf,sizeof buf)!=buf) \ 80570af302Sopenharmony_ci t_error("inet_ntop(AF_INET, <"#hex">, buf, size) did not return buf\n"); \ 81570af302Sopenharmony_ci if (strcmp(buf,src)) \ 82570af302Sopenharmony_ci t_error("inet_ntop(AF_INET, <"#hex">, buf, size) got %s, want %s\n", buf, src); \ 83570af302Sopenharmony_ci \ 84570af302Sopenharmony_ci in.s_addr = a; \ 85570af302Sopenharmony_ci p=inet_ntoa(in); \ 86570af302Sopenharmony_ci if (strcmp(p,src)) \ 87570af302Sopenharmony_ci t_error("inet_ntoa(<"#hex">) returned %s, want %s\n", p, src); \ 88570af302Sopenharmony_ci}while(0); 89570af302Sopenharmony_ci 90570af302Sopenharmony_ciint main(void) 91570af302Sopenharmony_ci{ 92570af302Sopenharmony_ci 93570af302Sopenharmony_ci// errors 94570af302Sopenharmony_ciif (inet_pton(12345, "", 0) != -1 || errno != EAFNOSUPPORT) 95570af302Sopenharmony_ci t_error("inet_pton(12345,,) should fail with EAFNOSUPPORT, got %s\n", strerror(errno)); 96570af302Sopenharmony_cierrno=0; 97570af302Sopenharmony_ciif (inet_ntop(AF_INET,"xxxx","",0) != 0 || errno != ENOSPC) 98570af302Sopenharmony_ci t_error("inet_ntop(,,0,0) should fail with ENOSPC, got %s\n", strerror(errno)); 99570af302Sopenharmony_cierrno=0; 100570af302Sopenharmony_ci 101570af302Sopenharmony_ci// dotted-decimal notation 102570af302Sopenharmony_ciV4("0.0.0.0", 1, "00000000") 103570af302Sopenharmony_ciV4("127.0.0.1", 1, "7f000001") 104570af302Sopenharmony_ciV4("10.0.128.31", 1, "0a00801f") 105570af302Sopenharmony_ciV4("255.255.255.255", 1, "ffffffff") 106570af302Sopenharmony_ci 107570af302Sopenharmony_ci// numbers-and-dots notation, but not dotted-decimal 108570af302Sopenharmony_ciV4("1.2.03.4", 0, "01020304") 109570af302Sopenharmony_ciV4("1.2.0x33.4", 0, "01023304") 110570af302Sopenharmony_ciV4("1.2.0XAB.4", 0, "0102ab04") 111570af302Sopenharmony_ciV4("1.2.0xabcd", 0, "0102abcd") 112570af302Sopenharmony_ciV4("1.0xabcdef", 0, "01abcdef") 113570af302Sopenharmony_ciV4("00377.0x0ff.65534", 0, "fffffffe") 114570af302Sopenharmony_ci 115570af302Sopenharmony_ci// invalid 116570af302Sopenharmony_ciV4(".1.2.3", 0, "ffffffff") 117570af302Sopenharmony_ciV4("1..2.3", 0, "ffffffff") 118570af302Sopenharmony_ciV4("1.2.3.", 0, "ffffffff") 119570af302Sopenharmony_ciV4("1.2.3.4.5", 0, "ffffffff") 120570af302Sopenharmony_ciV4("1.2.3.a", 0, "ffffffff") 121570af302Sopenharmony_ciV4("1.256.2.3", 0, "ffffffff") 122570af302Sopenharmony_ciV4("1.2.4294967296.3", 0, "ffffffff") 123570af302Sopenharmony_ciV4("1.2.-4294967295.3", 0, "ffffffff") 124570af302Sopenharmony_ciV4("1.2. 3.4", 0, "ffffffff") 125570af302Sopenharmony_ci 126570af302Sopenharmony_ci// ipv6 127570af302Sopenharmony_ciV6(":", 0, "") 128570af302Sopenharmony_ciV6("::", 1, "00000000000000000000000000000000") 129570af302Sopenharmony_ciV6("::1", 1, "00000000000000000000000000000001") 130570af302Sopenharmony_ciV6(":::", 0, "") 131570af302Sopenharmony_ciV6("192.168.1.1", 0, "") 132570af302Sopenharmony_ciV6(":192.168.1.1", 0, "") 133570af302Sopenharmony_ciV6("::192.168.1.1", 1, "000000000000000000000000c0a80101") 134570af302Sopenharmony_ciV6("0:0:0:0:0:0:192.168.1.1", 1, "000000000000000000000000c0a80101") 135570af302Sopenharmony_ciV6("0:0::0:0:0:192.168.1.1", 1, "000000000000000000000000c0a80101") 136570af302Sopenharmony_ciV6("::012.34.56.78", 0, "") 137570af302Sopenharmony_ciV6(":ffff:192.168.1.1", 0, "") 138570af302Sopenharmony_ciV6("::ffff:192.168.1.1", 1, "00000000000000000000ffffc0a80101") 139570af302Sopenharmony_ciV6(".192.168.1.1", 0, "") 140570af302Sopenharmony_ciV6(":.192.168.1.1", 0, "") 141570af302Sopenharmony_ciV6("a:0b:00c:000d:E:F::", 1, "000a000b000c000d000e000f00000000") 142570af302Sopenharmony_ciV6("a:0b:00c:000d:0000e:f::", 0, "") 143570af302Sopenharmony_ciV6("1:2:3:4:5:6::", 1, "00010002000300040005000600000000") 144570af302Sopenharmony_ciV6("1:2:3:4:5:6:7::", 1, "00010002000300040005000600070000") 145570af302Sopenharmony_ciV6("1:2:3:4:5:6:7:8::", 0, "") 146570af302Sopenharmony_ciV6("1:2:3:4:5:6:7::9", 0, "") 147570af302Sopenharmony_ciV6("::1:2:3:4:5:6", 1, "00000000000100020003000400050006") 148570af302Sopenharmony_ciV6("::1:2:3:4:5:6:7", 1, "00000001000200030004000500060007") 149570af302Sopenharmony_ciV6("::1:2:3:4:5:6:7:8", 0, "") 150570af302Sopenharmony_ciV6("a:b::c:d:e:f", 1, "000a000b00000000000c000d000e000f") 151570af302Sopenharmony_ciV6("ffff:c0a8:5e4", 0, "") 152570af302Sopenharmony_ciV6(":ffff:c0a8:5e4", 0, "") 153570af302Sopenharmony_ciV6("0:0:0:0:0:ffff:c0a8:5e4", 1, "00000000000000000000ffffc0a805e4") 154570af302Sopenharmony_ciV6("0:0:0:0:ffff:c0a8:5e4", 0, "") 155570af302Sopenharmony_ciV6("0::ffff:c0a8:5e4", 1, "00000000000000000000ffffc0a805e4") 156570af302Sopenharmony_ciV6("::0::ffff:c0a8:5e4", 0, "") 157570af302Sopenharmony_ciV6("c0a8", 0, "") 158570af302Sopenharmony_ci 159570af302Sopenharmony_cireturn t_status; 160570af302Sopenharmony_ci} 161