aboutsummaryrefslogtreecommitdiffstats
path: root/src/process.c
diff options
context:
space:
mode:
authorKim F. Storm2003-09-13 23:34:33 +0000
committerKim F. Storm2003-09-13 23:34:33 +0000
commit161933c7a77f29f6ac4fa3b39168d74d01550957 (patch)
tree600a16e29fa62966d3f4e0b80a89dcfec48fd9d0 /src/process.c
parent6df2a64592c0f679f9cef0dd1f4844e468e085de (diff)
downloademacs-161933c7a77f29f6ac4fa3b39168d74d01550957.tar.gz
emacs-161933c7a77f29f6ac4fa3b39168d74d01550957.zip
[HAVE_SOCKETS]: Include sys/ioctl.h and net/if.h.
(Fnetwork_interface_list, Fget_network_interface_info): New defuns. (syms_of_process): Defsubr them.
Diffstat (limited to 'src/process.c')
-rw-r--r--src/process.c245
1 files changed, 245 insertions, 0 deletions
diff --git a/src/process.c b/src/process.c
index dbb26e43a7b..fdbdaaba2f7 100644
--- a/src/process.c
+++ b/src/process.c
@@ -98,6 +98,17 @@ Boston, MA 02111-1307, USA. */
98#include <bsdtty.h> 98#include <bsdtty.h>
99#endif 99#endif
100 100
101/* Can we use SIOCGIFCONF and/or SIOCGIFADDR */
102#ifdef HAVE_SOCKETS
103#if defined(HAVE_SYS_IOCTL_H) && defined(HAVE_NET_IF_H)
104/* sys/ioctl.h may have been included already */
105#ifndef SIOCGIFADDR
106#include <sys/ioctl.h>
107#endif
108#include <net/if.h>
109#endif
110#endif
111
101#ifdef IRIS 112#ifdef IRIS
102#include <sys/sysmacros.h> /* for "minor" */ 113#include <sys/sysmacros.h> /* for "minor" */
103#endif /* not IRIS */ 114#endif /* not IRIS */
@@ -3356,6 +3367,234 @@ usage: (make-network-process &rest ARGS) */)
3356} 3367}
3357#endif /* HAVE_SOCKETS */ 3368#endif /* HAVE_SOCKETS */
3358 3369
3370
3371#ifdef HAVE_SOCKETS
3372
3373#ifdef SIOCGIFCONF
3374DEFUN ("network-interface-list", Fnetwork_interface_list, Snetwork_interface_list, 0, 0, 0,
3375 doc: /* Return an alist of all network interfaces and their network address.
3376Each element is a cons, the car of which is a string containing the
3377interface name, and the cdr is the network address in internal
3378format; see the description of ADDRESS in 'make-network-process'. */)
3379 ()
3380{
3381 struct ifconf ifconf;
3382 struct ifreq *ifreqs = NULL;
3383 int ifaces = 0;
3384 int buf_size, s;
3385 Lisp_Object res;
3386
3387 s = socket (AF_INET, SOCK_STREAM, 0);
3388 if (s < 0)
3389 return Qnil;
3390
3391 again:
3392 ifaces += 25;
3393 buf_size = ifaces * sizeof(ifreqs[0]);
3394 ifreqs = (struct ifreq *)xrealloc(ifreqs, buf_size);
3395 if (!ifreqs)
3396 {
3397 close (s);
3398 return Qnil;
3399 }
3400
3401 ifconf.ifc_len = buf_size;
3402 ifconf.ifc_req = ifreqs;
3403 if (ioctl (s, SIOCGIFCONF, &ifconf))
3404 {
3405 close (s);
3406 return Qnil;
3407 }
3408
3409 if (ifconf.ifc_len == buf_size)
3410 goto again;
3411
3412 close (s);
3413 ifaces = ifconf.ifc_len / sizeof (ifreqs[0]);
3414
3415 res = Qnil;
3416 while (--ifaces >= 0)
3417 {
3418 struct ifreq *ifq = &ifreqs[ifaces];
3419 char namebuf[sizeof (ifq->ifr_name) + 1];
3420 if (ifq->ifr_addr.sa_family != AF_INET)
3421 continue;
3422 bcopy (ifq->ifr_name, namebuf, sizeof (ifq->ifr_name));
3423 namebuf[sizeof (ifq->ifr_name)] = 0;
3424 res = Fcons (Fcons (build_string (namebuf),
3425 conv_sockaddr_to_lisp (&ifq->ifr_addr,
3426 sizeof (struct sockaddr))),
3427 res);
3428 }
3429
3430 return res;
3431}
3432#endif
3433
3434#if defined(SIOCGIFADDR) || defined(SIOCGIFHWADDR) || defined(SIOCGIFFLAGS)
3435
3436struct ifflag_def {
3437 int flag_bit;
3438 char *flag_sym;
3439};
3440
3441static struct ifflag_def ifflag_table[] = {
3442#ifdef IFF_UP
3443 { IFF_UP, "up" },
3444#endif
3445#ifdef IFF_BROADCAST
3446 { IFF_BROADCAST, "broadcast" },
3447#endif
3448#ifdef IFF_DEBUG
3449 { IFF_DEBUG, "debug" },
3450#endif
3451#ifdef IFF_LOOPBACK
3452 { IFF_LOOPBACK, "loopback" },
3453#endif
3454#ifdef IFF_POINTOPOINT
3455 { IFF_POINTOPOINT, "pointopoint" },
3456#endif
3457#ifdef IFF_RUNNING
3458 { IFF_RUNNING, "running" },
3459#endif
3460#ifdef IFF_NOARP
3461 { IFF_NOARP, "noarp" },
3462#endif
3463#ifdef IFF_PROMISC
3464 { IFF_PROMISC, "promisc" },
3465#endif
3466#ifdef IFF_NOTRAILERS
3467 { IFF_NOTRAILERS, "notrailers" },
3468#endif
3469#ifdef IFF_ALLMULTI
3470 { IFF_ALLMULTI, "allmulti" },
3471#endif
3472#ifdef IFF_MASTER
3473 { IFF_MASTER, "master" },
3474#endif
3475#ifdef IFF_SLAVE
3476 { IFF_SLAVE, "slave" },
3477#endif
3478#ifdef IFF_MULTICAST
3479 { IFF_MULTICAST, "multicast" },
3480#endif
3481#ifdef IFF_PORTSEL
3482 { IFF_PORTSEL, "portsel" },
3483#endif
3484#ifdef IFF_AUTOMEDIA
3485 { IFF_AUTOMEDIA, "automedia" },
3486#endif
3487#ifdef IFF_DYNAMIC
3488 { IFF_DYNAMIC, "dynamic" },
3489#endif
3490 { 0, 0 }
3491};
3492
3493DEFUN ("get-network-interface-info", Fget_network_interface_info, Sget_network_interface_info, 1, 1, 0,
3494 doc: /* Return information about network interface named IFNAME.
3495The return value is a list (ADDR BCAST NETMASK HWADDR FLAGS),
3496where ADDR is the layer 3 address, BCAST is the layer 3 broadcast address,
3497NETMASK is the layer 3 network mask, HWADDR is the layer 2 addres, and
3498FLAGS is the current flags of the interface. */)
3499 (ifname)
3500 Lisp_Object ifname;
3501{
3502 struct ifreq rq;
3503 Lisp_Object res = Qnil;
3504 Lisp_Object elt;
3505 int s;
3506 int any = 0;
3507
3508 CHECK_STRING (ifname);
3509
3510 bzero (rq.ifr_name, sizeof rq.ifr_name);
3511 strncpy (rq.ifr_name, SDATA (ifname), sizeof (rq.ifr_name));
3512
3513 s = socket (AF_INET, SOCK_STREAM, 0);
3514 if (s < 0)
3515 return Qnil;
3516
3517 elt = Qnil;
3518#ifdef SIOCGIFFLAGS
3519 if (ioctl (s, SIOCGIFFLAGS, &rq) == 0)
3520 {
3521 int flags = rq.ifr_flags;
3522 struct ifflag_def *fp;
3523 int fnum;
3524
3525 any++;
3526 for (fp = ifflag_table; flags != 0 && fp; fp++)
3527 {
3528 if (flags & fp->flag_bit)
3529 {
3530 elt = Fcons (intern (fp->flag_sym), elt);
3531 flags -= fp->flag_bit;
3532 }
3533 }
3534 for (fnum = 0; flags && fnum < 32; fnum++)
3535 {
3536 if (flags & (1 << fnum))
3537 {
3538 elt = Fcons (make_number (fnum), elt);
3539 }
3540 }
3541 }
3542#endif
3543 res = Fcons (elt, res);
3544
3545 elt = Qnil;
3546#ifdef SIOCGIFHWADDR
3547 if (ioctl (s, SIOCGIFHWADDR, &rq) == 0)
3548 {
3549 Lisp_Object hwaddr = Fmake_vector (6, Qnil);
3550 register struct Lisp_Vector *p = XVECTOR (hwaddr);
3551 int n;
3552
3553 any++;
3554 for (n = 0; n < 6; n++)
3555 p->contents[n] = make_number (((unsigned char *)&rq.ifr_hwaddr.sa_data[0])[n]);
3556 elt = Fcons (XINT (rq.ifr_hwaddr.sa_family), hwaddr);
3557 }
3558#endif
3559 res = Fcons (elt, res);
3560
3561 elt = Qnil;
3562#ifdef SIOCGIFNETMASK
3563 if (ioctl (s, SIOCGIFNETMASK, &rq) == 0)
3564 {
3565 any++;
3566 elt = conv_sockaddr_to_lisp (&rq.ifr_netmask, sizeof (rq.ifr_netmask));
3567 }
3568#endif
3569 res = Fcons (elt, res);
3570
3571 elt = Qnil;
3572#ifdef SIOCGIFBRDADDR
3573 if (ioctl (s, SIOCGIFBRDADDR, &rq) == 0)
3574 {
3575 any++;
3576 elt = conv_sockaddr_to_lisp (&rq.ifr_broadaddr, sizeof (rq.ifr_broadaddr));
3577 }
3578#endif
3579 res = Fcons (elt, res);
3580
3581 elt = Qnil;
3582#ifdef SIOCGIFADDR
3583 if (ioctl (s, SIOCGIFADDR, &rq) == 0)
3584 {
3585 any++;
3586 elt = conv_sockaddr_to_lisp (&rq.ifr_addr, sizeof (rq.ifr_addr));
3587 }
3588#endif
3589 res = Fcons (elt, res);
3590
3591 close (s);
3592
3593 return any ? res : Qnil;
3594}
3595#endif
3596#endif /* HAVE_SOCKETS */
3597
3359void 3598void
3360deactivate_process (proc) 3599deactivate_process (proc)
3361 Lisp_Object proc; 3600 Lisp_Object proc;
@@ -6467,6 +6706,12 @@ The value takes effect when `start-process' is called. */);
6467 defsubr (&Sset_network_process_options); 6706 defsubr (&Sset_network_process_options);
6468 defsubr (&Smake_network_process); 6707 defsubr (&Smake_network_process);
6469 defsubr (&Sformat_network_address); 6708 defsubr (&Sformat_network_address);
6709#ifdef SIOCGIFCONF
6710 defsubr (&Snetwork_interface_list);
6711#endif
6712#if defined(SIOCGIFADDR) || defined(SIOCGIFHWADDR) || defined(SIOCGIFFLAGS)
6713 defsubr (&Sget_network_interface_info);
6714#endif
6470#endif /* HAVE_SOCKETS */ 6715#endif /* HAVE_SOCKETS */
6471#ifdef DATAGRAM_SOCKETS 6716#ifdef DATAGRAM_SOCKETS
6472 defsubr (&Sprocess_datagram_address); 6717 defsubr (&Sprocess_datagram_address);