diff options
| author | Kim F. Storm | 2003-09-13 23:34:33 +0000 |
|---|---|---|
| committer | Kim F. Storm | 2003-09-13 23:34:33 +0000 |
| commit | 161933c7a77f29f6ac4fa3b39168d74d01550957 (patch) | |
| tree | 600a16e29fa62966d3f4e0b80a89dcfec48fd9d0 /src/process.c | |
| parent | 6df2a64592c0f679f9cef0dd1f4844e468e085de (diff) | |
| download | emacs-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.c | 245 |
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 | ||
| 3374 | DEFUN ("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. | ||
| 3376 | Each element is a cons, the car of which is a string containing the | ||
| 3377 | interface name, and the cdr is the network address in internal | ||
| 3378 | format; 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 | |||
| 3436 | struct ifflag_def { | ||
| 3437 | int flag_bit; | ||
| 3438 | char *flag_sym; | ||
| 3439 | }; | ||
| 3440 | |||
| 3441 | static 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 | |||
| 3493 | DEFUN ("get-network-interface-info", Fget_network_interface_info, Sget_network_interface_info, 1, 1, 0, | ||
| 3494 | doc: /* Return information about network interface named IFNAME. | ||
| 3495 | The return value is a list (ADDR BCAST NETMASK HWADDR FLAGS), | ||
| 3496 | where ADDR is the layer 3 address, BCAST is the layer 3 broadcast address, | ||
| 3497 | NETMASK is the layer 3 network mask, HWADDR is the layer 2 addres, and | ||
| 3498 | FLAGS 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 | |||
| 3359 | void | 3598 | void |
| 3360 | deactivate_process (proc) | 3599 | deactivate_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); |