]>
git.ipfire.org Git - thirdparty/cups.git/blob - cups/getifaddrs.c
2 * "$Id: getifaddrs.c 5503 2006-05-10 18:55:39Z mike $"
4 * Network interface functions for the Common UNIX Printing System
7 * Copyright 1997-2006 by Easy Software Products, all rights reserved.
9 * These coded instructions, statements, and computer programs are the
10 * property of Easy Software Products and are protected by Federal
11 * copyright law. Distribution and use rights are outlined in the file
12 * "LICENSE" which should have been included with this file. If this
13 * file is missing or damaged please contact Easy Software Products
16 * Attn: CUPS Licensing Information
17 * Easy Software Products
18 * 44141 Airport View Drive, Suite 204
19 * Hollywood, Maryland 20636 USA
21 * Voice: (301) 373-9600
22 * EMail: cups-info@cups.org
23 * WWW: http://www.cups.org
27 * _cups_getifaddrs() - Get a list of network interfaces on the system.
28 * _cups_freeifaddrs() - Free an interface list...
32 * Include necessary headers.
35 #include "http-private.h"
38 #ifndef HAVE_GETIFADDRS
40 * '_cups_getifaddrs()' - Get a list of network interfaces on the system.
43 int /* O - 0 on success, -1 on error */
44 _cups_getifaddrs(struct ifaddrs
**addrs
)/* O - List of interfaces */
46 int sock
; /* Socket */
47 char buffer
[65536], /* Buffer for address info */
48 *bufptr
, /* Pointer into buffer */
49 *bufend
; /* End of buffer */
50 struct ifconf conf
; /* Interface configurations */
51 struct sockaddr addr
; /* Address data */
52 struct ifreq
*ifp
; /* Interface data */
53 int ifpsize
; /* Size of interface data */
54 struct ifaddrs
*temp
; /* Pointer to current interface */
55 struct ifreq request
; /* Interface request */
59 * Start with an empty list...
68 * Create a UDP socket to get the interface data...
71 memset (&addr
, 0, sizeof(addr
));
72 if ((sock
= socket(AF_INET
, SOCK_DGRAM
, 0)) < 0)
76 * Try to get the list of interfaces...
79 conf
.ifc_len
= sizeof(buffer
);
80 conf
.ifc_buf
= buffer
;
82 if (ioctl(sock
, SIOCGIFCONF
, &conf
) < 0)
85 * Couldn't get the list of interfaces...
93 * OK, got the list of interfaces, now lets step through the
94 * buffer to pull them out...
97 # ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
98 # define sockaddr_len(a) ((a)->sa_len)
100 # define sockaddr_len(a) (sizeof(struct sockaddr))
101 # endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
103 for (bufptr
= buffer
, bufend
= buffer
+ conf
.ifc_len
;
108 * Get the current interface information...
111 ifp
= (struct ifreq
*)bufptr
;
112 ifpsize
= sizeof(ifp
->ifr_name
) + sockaddr_len(&(ifp
->ifr_addr
));
114 if (ifpsize
< sizeof(struct ifreq
))
115 ifpsize
= sizeof(struct ifreq
);
117 memset(&request
, 0, sizeof(request
));
118 memcpy(request
.ifr_name
, ifp
->ifr_name
, sizeof(ifp
->ifr_name
));
121 * Check the status of the interface...
124 if (ioctl(sock
, SIOCGIFFLAGS
, &request
) < 0)
128 * Allocate memory for a single interface record...
131 if ((temp
= calloc(1, sizeof(struct ifaddrs
))) == NULL
)
134 * Unable to allocate memory...
142 * Add this record to the front of the list and copy the name, flags,
143 * and network address...
146 temp
->ifa_next
= *addrs
;
148 temp
->ifa_name
= strdup(ifp
->ifr_name
);
149 temp
->ifa_flags
= request
.ifr_flags
;
150 if ((temp
->ifa_addr
= calloc(1, sockaddr_len(&(ifp
->ifr_addr
)))) != NULL
)
151 memcpy(temp
->ifa_addr
, &(ifp
->ifr_addr
), sockaddr_len(&(ifp
->ifr_addr
)));
154 * Try to get the netmask for the interface...
157 if (!ioctl(sock
, SIOCGIFNETMASK
, &request
))
160 * Got it, make a copy...
163 if ((temp
->ifa_netmask
= calloc(1, sizeof(request
.ifr_netmask
))) != NULL
)
164 memcpy(temp
->ifa_netmask
, &(request
.ifr_netmask
),
165 sizeof(request
.ifr_netmask
));
169 * Then get the broadcast or point-to-point (destination) address,
173 if (temp
->ifa_flags
& IFF_BROADCAST
)
176 * Have a broadcast address, so get it!
179 if (!ioctl(sock
, SIOCGIFBRDADDR
, &request
))
182 * Got it, make a copy...
185 if ((temp
->ifa_broadaddr
=
186 calloc(1, sizeof(request
.ifr_broadaddr
))) != NULL
)
187 memcpy(temp
->ifa_broadaddr
, &(request
.ifr_broadaddr
),
188 sizeof(request
.ifr_broadaddr
));
191 else if (temp
->ifa_flags
& IFF_POINTOPOINT
)
194 * Point-to-point interface; grab the remote address...
197 if (!ioctl(sock
, SIOCGIFDSTADDR
, &request
))
199 temp
->ifa_dstaddr
= malloc(sizeof(request
.ifr_dstaddr
));
200 memcpy(temp
->ifa_dstaddr
, &(request
.ifr_dstaddr
),
201 sizeof(request
.ifr_dstaddr
));
207 * OK, we're done with the socket, close it and return 0...
217 * '_cups_freeifaddrs()' - Free an interface list...
221 _cups_freeifaddrs(struct ifaddrs
*addrs
)/* I - Interface list to free */
223 struct ifaddrs
*next
; /* Next interface in list */
226 while (addrs
!= NULL
)
229 * Make a copy of the next interface pointer...
232 next
= addrs
->ifa_next
;
235 * Free data values as needed...
240 free(addrs
->ifa_name
);
241 addrs
->ifa_name
= NULL
;
246 free(addrs
->ifa_addr
);
247 addrs
->ifa_addr
= NULL
;
250 if (addrs
->ifa_netmask
)
252 free(addrs
->ifa_netmask
);
253 addrs
->ifa_netmask
= NULL
;
256 if (addrs
->ifa_dstaddr
)
258 free(addrs
->ifa_dstaddr
);
259 addrs
->ifa_dstaddr
= NULL
;
263 * Free this node and continue to the next...
271 #endif /* !HAVE_GETIFADDRS */
275 * End of "$Id: getifaddrs.c 5503 2006-05-10 18:55:39Z mike $".