aboutsummaryrefslogtreecommitdiffstats
path: root/src/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/process.c')
-rw-r--r--src/process.c93
1 files changed, 83 insertions, 10 deletions
diff --git a/src/process.c b/src/process.c
index f2c2bfd81c5..887090df26c 100644
--- a/src/process.c
+++ b/src/process.c
@@ -58,6 +58,17 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
58#include <net/if.h> 58#include <net/if.h>
59#endif /* HAVE_NET_IF_H */ 59#endif /* HAVE_NET_IF_H */
60 60
61#if defined(HAVE_IFADDRS_H)
62/* Must be after net/if.h */
63#include <ifaddrs.h>
64
65/* We only use structs from this header when we use getifaddrs. */
66#if defined(HAVE_NET_IF_DL_H)
67#include <net/if_dl.h>
68#endif
69
70#endif
71
61#ifdef NEED_BSDTTY 72#ifdef NEED_BSDTTY
62#include <bsdtty.h> 73#include <bsdtty.h>
63#endif 74#endif
@@ -3557,9 +3568,10 @@ format; see the description of ADDRESS in `make-network-process'. */)
3557 (void) 3568 (void)
3558{ 3569{
3559 struct ifconf ifconf; 3570 struct ifconf ifconf;
3560 struct ifreq *ifreqs = NULL; 3571 struct ifreq *ifreq;
3561 ptrdiff_t ifaces = 0; 3572 void *buf = NULL;
3562 int buf_size, s; 3573 ptrdiff_t buf_size = 512;
3574 int s, i;
3563 Lisp_Object res; 3575 Lisp_Object res;
3564 3576
3565 s = socket (AF_INET, SOCK_STREAM, 0); 3577 s = socket (AF_INET, SOCK_STREAM, 0);
@@ -3567,14 +3579,14 @@ format; see the description of ADDRESS in `make-network-process'. */)
3567 return Qnil; 3579 return Qnil;
3568 3580
3569 again: 3581 again:
3570 ifreqs = xpalloc (ifreqs, &ifaces, 25, 3582
3571 INT_MAX / sizeof *ifreqs, sizeof *ifreqs); 3583 buf = xpalloc (buf, &buf_size, sizeof *ifreq, INT_MAX, 1);
3572 buf_size = ifaces * sizeof (ifreqs[0]); 3584 ifconf.ifc_buf = buf;
3573 ifconf.ifc_len = buf_size; 3585 ifconf.ifc_len = buf_size;
3574 ifconf.ifc_req = ifreqs;
3575 if (ioctl (s, SIOCGIFCONF, &ifconf)) 3586 if (ioctl (s, SIOCGIFCONF, &ifconf))
3576 { 3587 {
3577 close (s); 3588 close (s);
3589 xfree (buf);
3578 return Qnil; 3590 return Qnil;
3579 } 3591 }
3580 3592
@@ -3582,15 +3594,29 @@ format; see the description of ADDRESS in `make-network-process'. */)
3582 goto again; 3594 goto again;
3583 3595
3584 close (s); 3596 close (s);
3585 ifaces = ifconf.ifc_len / sizeof (ifreqs[0]);
3586 3597
3587 res = Qnil; 3598 res = Qnil;
3588 while (--ifaces >= 0) 3599 for (ifreq = ifconf.ifc_req;
3600 (char *) ifreq < (char *) (ifconf.ifc_req) + ifconf.ifc_len;
3601 )
3589 { 3602 {
3590 struct ifreq *ifq = &ifreqs[ifaces]; 3603 struct ifreq *ifq = ifreq;
3604#ifdef HAVE_STRUCT_IFREQ_IFR_ADDR_SA_LEN
3605#define SIZEOF_IFREQ(sif) \
3606 ((sif)->ifr_addr.sa_len < sizeof(struct sockaddr) ? \
3607 sizeof((*sif)) : sizeof ((sif)->ifr_name) + sif->ifr_addr.sa_len)
3608
3609 int len = SIZEOF_IFREQ (ifq);
3610#else
3611 int len = sizeof (*ifreq);
3612#endif
3591 char namebuf[sizeof (ifq->ifr_name) + 1]; 3613 char namebuf[sizeof (ifq->ifr_name) + 1];
3614 i += len;
3615 ifreq = (struct ifreq*) ((char*) ifreq + len);
3616
3592 if (ifq->ifr_addr.sa_family != AF_INET) 3617 if (ifq->ifr_addr.sa_family != AF_INET)
3593 continue; 3618 continue;
3619
3594 memcpy (namebuf, ifq->ifr_name, sizeof (ifq->ifr_name)); 3620 memcpy (namebuf, ifq->ifr_name, sizeof (ifq->ifr_name));
3595 namebuf[sizeof (ifq->ifr_name)] = 0; 3621 namebuf[sizeof (ifq->ifr_name)] = 0;
3596 res = Fcons (Fcons (build_string (namebuf), 3622 res = Fcons (Fcons (build_string (namebuf),
@@ -3599,6 +3625,7 @@ format; see the description of ADDRESS in `make-network-process'. */)
3599 res); 3625 res);
3600 } 3626 }
3601 3627
3628 xfree (buf);
3602 return res; 3629 return res;
3603} 3630}
3604#endif /* SIOCGIFCONF */ 3631#endif /* SIOCGIFCONF */
@@ -3636,8 +3663,13 @@ static const struct ifflag_def ifflag_table[] = {
3636 { IFF_PROMISC, "promisc" }, 3663 { IFF_PROMISC, "promisc" },
3637#endif 3664#endif
3638#ifdef IFF_NOTRAILERS 3665#ifdef IFF_NOTRAILERS
3666#ifdef NS_IMPL_COCOA
3667 /* Really means smart, notrailers is obsolete */
3668 { IFF_NOTRAILERS, "smart" },
3669#else
3639 { IFF_NOTRAILERS, "notrailers" }, 3670 { IFF_NOTRAILERS, "notrailers" },
3640#endif 3671#endif
3672#endif
3641#ifdef IFF_ALLMULTI 3673#ifdef IFF_ALLMULTI
3642 { IFF_ALLMULTI, "allmulti" }, 3674 { IFF_ALLMULTI, "allmulti" },
3643#endif 3675#endif
@@ -3690,6 +3722,10 @@ FLAGS is the current flags of the interface. */)
3690 Lisp_Object elt; 3722 Lisp_Object elt;
3691 int s; 3723 int s;
3692 int any = 0; 3724 int any = 0;
3725#if (! (defined SIOCGIFHWADDR && defined HAVE_STRUCT_IFREQ_IFR_HWADDR) \
3726 && defined HAVE_GETIFADDRS && defined LLADDR)
3727 struct ifaddrs *ifap;
3728#endif
3693 3729
3694 CHECK_STRING (ifname); 3730 CHECK_STRING (ifname);
3695 3731
@@ -3708,6 +3744,12 @@ FLAGS is the current flags of the interface. */)
3708 const struct ifflag_def *fp; 3744 const struct ifflag_def *fp;
3709 int fnum; 3745 int fnum;
3710 3746
3747 /* If flags is smaller than int (i.e. short) it may have the high bit set
3748 due to IFF_MULTICAST. In that case, sign extending it into
3749 an int is wrong. */
3750 if (flags < 0 && sizeof (rq.ifr_flags) < sizeof (flags))
3751 flags = (unsigned short) rq.ifr_flags;
3752
3711 any = 1; 3753 any = 1;
3712 for (fp = ifflag_table; flags != 0 && fp->flag_sym; fp++) 3754 for (fp = ifflag_table; flags != 0 && fp->flag_sym; fp++)
3713 { 3755 {
@@ -3741,7 +3783,38 @@ FLAGS is the current flags of the interface. */)
3741 p->contents[n] = make_number (((unsigned char *)&rq.ifr_hwaddr.sa_data[0])[n]); 3783 p->contents[n] = make_number (((unsigned char *)&rq.ifr_hwaddr.sa_data[0])[n]);
3742 elt = Fcons (make_number (rq.ifr_hwaddr.sa_family), hwaddr); 3784 elt = Fcons (make_number (rq.ifr_hwaddr.sa_family), hwaddr);
3743 } 3785 }
3786#elif defined(HAVE_GETIFADDRS) && defined(LLADDR)
3787 if (getifaddrs (&ifap) != -1)
3788 {
3789 Lisp_Object hwaddr = Fmake_vector (make_number (6), Qnil);
3790 register struct Lisp_Vector *p = XVECTOR (hwaddr);
3791 struct ifaddrs *it;
3792
3793 for (it = ifap; it != NULL; it = it->ifa_next)
3794 {
3795 struct sockaddr_dl *sdl = (struct sockaddr_dl*) it->ifa_addr;
3796 unsigned char linkaddr[6];
3797 int n;
3798
3799 if (it->ifa_addr->sa_family != AF_LINK
3800 || strcmp (it->ifa_name, SSDATA (ifname)) != 0
3801 || sdl->sdl_alen != 6)
3802 continue;
3803
3804 memcpy (linkaddr, LLADDR(sdl), sdl->sdl_alen);
3805 for (n = 0; n < 6; n++)
3806 p->contents[n] = make_number (linkaddr[n]);
3807
3808 elt = Fcons (make_number (it->ifa_addr->sa_family), hwaddr);
3809 break;
3810 }
3811 }
3812#ifdef HAVE_FREEIFADDRS
3813 freeifaddrs (ifap);
3744#endif 3814#endif
3815
3816#endif /* HAVE_GETIFADDRS && LLADDR */
3817
3745 res = Fcons (elt, res); 3818 res = Fcons (elt, res);
3746 3819
3747 elt = Qnil; 3820 elt = Qnil;