summaryrefslogtreecommitdiff
path: root/pjlib/src/pj/ip_helper_generic.c
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2007-11-17 10:27:34 +0000
committerBenny Prijono <bennylp@teluu.com>2007-11-17 10:27:34 +0000
commit54f99f73d8f744c4558645906c99cbab480f5b8c (patch)
tree386070c03c26f0d1c703e8e19654d82cecff22e5 /pjlib/src/pj/ip_helper_generic.c
parentf840a19eb406297268e9a86c639bfe9352aab2b9 (diff)
Ticket #414: Implement IP interface enumeration on Linux/Unix with SIOCGIFCONF ioctl() call to a socket
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@1584 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjlib/src/pj/ip_helper_generic.c')
-rw-r--r--pjlib/src/pj/ip_helper_generic.c65
1 files changed, 60 insertions, 5 deletions
diff --git a/pjlib/src/pj/ip_helper_generic.c b/pjlib/src/pj/ip_helper_generic.c
index 3b713f5a..092bb28e 100644
--- a/pjlib/src/pj/ip_helper_generic.c
+++ b/pjlib/src/pj/ip_helper_generic.c
@@ -21,12 +21,10 @@
#include <pj/assert.h>
#include <pj/errno.h>
#include <pj/string.h>
+#include <pj/compat/socket.h>
-/*
- * Enumerate the local IP interface currently active in the host.
- */
-PJ_DEF(pj_status_t) pj_enum_ip_interface(unsigned *p_cnt,
- pj_in_addr ifs[])
+static pj_status_t dummy_enum_ip_interface(unsigned *p_cnt,
+ pj_in_addr ifs[])
{
pj_status_t status;
@@ -43,6 +41,63 @@ PJ_DEF(pj_status_t) pj_enum_ip_interface(unsigned *p_cnt,
return PJ_SUCCESS;
}
+#ifdef SIOCGIFCONF
+static pj_status_t sock_enum_ip_interface(unsigned *p_cnt,
+ pj_in_addr ifs[])
+{
+ pj_sock_t sock;
+ char buf[512];
+ struct ifconf ifc;
+ struct ifreq *ifr;
+ int i, count;
+ pj_status_t status;
+
+ status = pj_sock_socket(PJ_AF_INET, PJ_SOCK_DGRAM, 0, &sock);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* Query available interfaces */
+ ifc.ifc_len = sizeof(buf);
+ ifc.ifc_buf = buf;
+
+ if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) {
+ int oserr = pj_get_netos_error();
+ pj_sock_close(sock);
+ return PJ_RETURN_OS_ERROR(oserr);
+ }
+
+ /* Done with socket */
+ pj_sock_close(sock);
+
+ /* Interface interfaces */
+ ifr = (struct ifreq*) ifc.ifc_req;
+ count = ifc.ifc_len / sizeof(struct ifreq);
+ if (count > *p_cnt)
+ count = *p_cnt;
+ else
+ *p_cnt = count;
+ for (i=0; i<count; ++i) {
+ struct ifreq *itf = &ifr[i];
+ ifs[i].s_addr = ((struct sockaddr_in *)&itf->ifr_addr)->sin_addr.s_addr;
+ }
+
+ return PJ_SUCCESS;
+}
+#endif /* SIOCGIFCONF */
+
+/*
+ * Enumerate the local IP interface currently active in the host.
+ */
+PJ_DEF(pj_status_t) pj_enum_ip_interface(unsigned *p_cnt,
+ pj_in_addr ifs[])
+{
+#ifdef SIOCGIFCONF
+ if (sock_enum_ip_interface(p_cnt, ifs) == PJ_SUCCESS)
+ return PJ_SUCCESS;
+#endif
+ return dummy_enum_ip_interface(p_cnt, ifs);
+}
+
/*
* Enumerate the IP routing table for this host.
*/