14 struct nameval
{ const char *name
; int val
; };
15 const char *prog
= "<unset>";
17 static int parseint(const char *s
, const char *what
)
23 if (!isdigit((unsigned char)*s
)) goto fail
;
25 i
= strtoul(s
, &q
, 0);
26 if (errno
|| *q
|| i
> INT_MAX
) goto fail
;
31 fprintf(stderr
, "%s: bad numeric %s `%s'\n", prog
, what
, s
);
35 static int lookup(const char *name
, const char *what
,
36 const struct nameval
*nv
)
38 if (isdigit((unsigned char)*name
))
39 return (parseint(name
, what
));
40 for (; nv
->name
; nv
++)
41 if (strcmp(nv
->name
, name
) == 0) return nv
->val
;
42 fprintf(stderr
, "%s: unknown %s `%s'\n", prog
, what
, name
);
46 static const char *rlookup(int val
, const char *what
,
47 const struct nameval
*nv
)
50 for (; nv
->name
; nv
++)
51 if (nv
->val
== val
) return (nv
->name
);
52 sprintf(buf
, "%s#%d", what
, val
);
56 static const struct nameval familymap
[] = {
57 { "unspec", AF_UNSPEC
},
59 { "inet6", AF_INET6
},
63 static const struct nameval typemap
[] = {
65 { "stream", SOCK_STREAM
},
66 { "dgram", SOCK_DGRAM
},
71 static void usage(FILE *fp
)
75 "[-CNacgimnsuv] [-f FAMILY] [-p PROTOCOL] [-t TYPE] "
80 static void help(FILE *fp
)
85 -a plain v4 also (with -m) -n numeric host\n\
86 -c canonify name -N numeric service\n\
87 -C canonify to IDN (with -c) -s allow unassigned codepoints\n\
88 -g families with configured addrs -u check result is STD3 hostname\n\
89 -i convert to IDN -v passive\n\
90 -m v6-mapped v4 addresses\n\
92 -f unspec|inet|inet6 NAME -- hostname or `-' for none\n\
93 -p PROTOCOL -- /etc/protocols SERVICE -- number or /etc/services\n\
94 -t any|stream|dgram|raw\n\
98 int main(int argc
, char *argv
[])
100 struct addrinfo
*ai
, hint
= { .ai_family
= AF_UNSPEC
};
102 const char *serv
= 0;
103 char namebuf
[NI_MAXHOST
], servbuf
[NI_MAXSERV
];
106 prog
= strrchr(argv
[0], '/');
111 int opt
= getopt(argc
, argv
, "hf:t:p:nNcvgamiCus");
114 case 'h': help(stdout
); exit(0);
116 hint
.ai_family
= lookup(optarg
, "family", familymap
);
119 hint
.ai_socktype
= lookup(optarg
, "type", typemap
);
122 if (isdigit((unsigned char)*optarg
))
123 hint
.ai_protocol
= parseint(optarg
, "protocol");
125 struct protoent
*p
= getprotobyname(optarg
);
127 fprintf(stderr
, "%s: unknown protocol `%s'\n", prog
, optarg
);
130 hint
.ai_protocol
= p
->p_proto
;
133 case 'C': hint
.ai_flags
|= AI_CANONIDN
; break;
134 case 'N': hint
.ai_flags
|= AI_NUMERICSERV
; break;
135 case 'a': hint
.ai_flags
|= AI_ALL
; break;
136 case 'c': hint
.ai_flags
|= AI_CANONNAME
; break;
137 case 'g': hint
.ai_flags
|= AI_ADDRCONFIG
; break;
138 case 'i': hint
.ai_flags
|= AI_IDN
; break;
139 case 'm': hint
.ai_flags
|= AI_V4MAPPED
; break;
140 case 'n': hint
.ai_flags
|= AI_NUMERICHOST
; break;
141 case 's': hint
.ai_flags
|= AI_IDN_USE_STD3_ASCII_RULES
; break;
142 case 'u': hint
.ai_flags
|= AI_IDN_ALLOW_UNASSIGNED
; break;
143 case 'v': hint
.ai_flags
|= AI_PASSIVE
; break;
144 default: usage(stderr
); exit(1);
149 if (!*argv
) { usage(stderr
); exit(1); } name
= *argv
++;
150 if (*argv
) { serv
= *argv
++; }
151 if (*argv
) { usage(stderr
); exit(1); }
153 if (strcmp(name
, "-") == 0) name
= 0;
155 if ((err
= getaddrinfo(name
, serv
, &hint
, &ai
)) != 0) {
156 fprintf(stderr
, "%s: %s\n", prog
, gai_strerror(err
));
160 for (; ai
; ai
= ai
->ai_next
) {
161 if (ai
->ai_canonname
) printf("[%s]\n", ai
->ai_canonname
);
162 fputs(rlookup(ai
->ai_family
, "family", familymap
), stdout
);
164 fputs(rlookup(ai
->ai_socktype
, "type", typemap
), stdout
);
166 if ((err
= getnameinfo(ai
->ai_addr
, ai
->ai_addrlen
,
167 namebuf
, sizeof(namebuf
),
168 servbuf
, sizeof(servbuf
),
169 (NI_NUMERICHOST
| NI_NUMERICSERV
|
170 (ai
->ai_socktype
== SOCK_DGRAM ?
171 NI_DGRAM
: 0)))) != 0)
172 printf("(error: %s)", gai_strerror(err
));
174 printf("%s %s", namebuf
, servbuf
);