1
/* ========================================================================
2
* Copyright 1988-2006 University of Washington
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
* you may not use this file except in compliance with the License.
6
* You may obtain a copy of the License at
8
* http://www.apache.org/licenses/LICENSE-2.0
11
* ========================================================================
15
* Program: UNIX IPv4 routines
17
* Author: Mark Crispin
18
* Networks and Distributed Computing
19
* Computing & Communications
20
* University of Washington
21
* Administration Building, AG-44
23
* Internet: MRC@CAC.Washington.EDU
25
* Date: 18 December 2003
26
* Last Edited: 30 August 2006
29
#define SADRLEN sizeof (struct sockaddr)
31
#define SADR4(sadr) ((struct sockaddr_in *) sadr)
32
#define SADR4LEN sizeof (struct sockaddr_in)
33
#define SADR4ADR(sadr) SADR4 (sadr)->sin_addr
34
#define ADR4LEN sizeof (struct in_addr)
35
#define SADR4PORT(sadr) SADR4 (sadr)->sin_port
38
/* IP abstraction layer */
40
char *ip_sockaddrtostring (struct sockaddr *sadr);
41
long ip_sockaddrtoport (struct sockaddr *sadr);
42
void *ip_stringtoaddr (char *text,size_t *len,int *family);
43
struct sockaddr *ip_newsockaddr (size_t *len);
44
struct sockaddr *ip_sockaddr (int family,void *adr,size_t adrlen,
45
unsigned short port,size_t *len);
46
char *ip_sockaddrtoname (struct sockaddr *sadr);
47
void *ip_nametoaddr (char *name,size_t *len,int *family,char **canonical,
50
/* Return IP address string from socket address
51
* Accepts: socket address
52
* Returns: IP address as name string
55
char *ip_sockaddrtostring (struct sockaddr *sadr)
57
return (sadr->sa_family == PF_INET) ?
58
inet_ntoa (SADR4ADR (sadr)) : "NON-IPv4";
62
/* Return port from socket address
63
* Accepts: socket address
64
* Returns: port number or -1 if can't determine it
67
long ip_sockaddrtoport (struct sockaddr *sadr)
69
return (sadr->sa_family == PF_INET) ? ntohs (SADR4PORT (sadr)) : -1;
73
/* Return IP address from string
74
* Accepts: name string
75
* pointer to returned length
76
* pointer to returned address family
77
* Returns: address if valid, length and family updated, or NIL
80
void *ip_stringtoaddr (char *text,size_t *len,int *family)
85
if ((adr = inet_addr (text)) == -1) ret = NIL;
86
else { /* make in_addr */
87
ret = (struct in_addr *) fs_get (*len = ADR4LEN);
88
*family = AF_INET; /* IPv4 */
89
ret->s_addr = adr; /* set address */
94
/* Create a maximum-size socket address
95
* Accepts: pointer to return maximum socket address length
96
* Returns: new, empty socket address of maximum size
99
struct sockaddr *ip_newsockaddr (size_t *len)
101
return (struct sockaddr *) memset (fs_get (SADRLEN),0,*len = SADRLEN);
105
/* Stuff a socket address
106
* Accepts: address family
108
* length of address (always 4 in IPv4)
110
* pointer to return socket address length
111
* Returns: socket address or NIL if error
114
struct sockaddr *ip_sockaddr (int family,void *adr,size_t adrlen,
115
unsigned short port,size_t *len)
117
struct sockaddr *sadr = ip_newsockaddr (len);
118
switch (family) { /* build socket address based upon family */
119
case AF_INET: /* IPv4 */
120
sadr->sa_family = PF_INET;
121
/* copy host address */
122
memcpy (&SADR4ADR (sadr),adr,adrlen);
123
/* copy port number in network format */
124
SADR4PORT (sadr) = htons (port);
127
default: /* non-IP?? */
128
sadr->sa_family = PF_UNSPEC;
134
/* Return name from socket address
135
* Accepts: socket address
136
* Returns: canonical name for that address or NIL if none
139
char *ip_sockaddrtoname (struct sockaddr *sadr)
142
return ((sadr->sa_family == PF_INET) &&
143
(he = gethostbyaddr ((char *) &SADR4ADR (sadr),ADR4LEN,AF_INET))) ?
144
(char *) he->h_name : NIL;
148
/* Return address from name
149
* Accepts: name or NIL to return next address
150
* pointer to previous/returned length
151
* pointer to previous/returned address family
152
* pointer to previous/returned canonical name
153
* pointer to previous/return state for next-address calls
154
* Returns: address with length/family/canonical updated if needed, or NIL
157
void *ip_nametoaddr (char *name,size_t *len,int *family,char **canonical,
160
char **adl,tmp[MAILTMPLEN];
162
if (name) { /* first lookup? */
163
/* yes, do case-independent lookup */
164
if ((strlen (name) < MAILTMPLEN) &&
165
(he = gethostbyname (lcase (strcpy (tmp,name))))) {
166
adl = he->h_addr_list;
167
if (len) *len = he->h_length;
168
if (family) *family = he->h_addrtype;
169
if (canonical) *canonical = (char *) he->h_name;
170
if (next) *next = (void *) adl;
175
if (family) *family = 0;
176
if (canonical) *canonical = NIL;
177
if (next) *next = NIL;
180
/* return next in series */
181
else if (next && (adl = (char **) *next)) *next = ++adl;
182
else adl = NIL; /* failure */
183
return adl ? (void *) *adl : NIL;