comparison src/process.c @ 52503:256a27a47af1

[HAVE_SOCKETS]: Include sys/ioctl.h and net/if.h. (Fnetwork_interface_list, Fget_network_interface_info): New defuns. (syms_of_process): Defsubr them.
author Kim F. Storm <storm@cua.dk>
date Sat, 13 Sep 2003 23:34:33 +0000
parents 695cf19ef79e
children 0ca23eb697b9
comparison
equal deleted inserted replaced
52502:9afe1154d52b 52503:256a27a47af1
94 #undef O_NONBLOCK 94 #undef O_NONBLOCK
95 #endif /* BROKEN_O_NONBLOCK */ 95 #endif /* BROKEN_O_NONBLOCK */
96 96
97 #ifdef NEED_BSDTTY 97 #ifdef NEED_BSDTTY
98 #include <bsdtty.h> 98 #include <bsdtty.h>
99 #endif
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
99 #endif 110 #endif
100 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 */
3352 ? Qnil : Qt); 3363 ? Qnil : Qt);
3353 3364
3354 UNGCPRO; 3365 UNGCPRO;
3355 return proc; 3366 return proc;
3356 } 3367 }
3368 #endif /* HAVE_SOCKETS */
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
3357 #endif /* HAVE_SOCKETS */ 3596 #endif /* HAVE_SOCKETS */
3358 3597
3359 void 3598 void
3360 deactivate_process (proc) 3599 deactivate_process (proc)
3361 Lisp_Object proc; 3600 Lisp_Object proc;
6465 defsubr (&Sstart_process); 6704 defsubr (&Sstart_process);
6466 #ifdef HAVE_SOCKETS 6705 #ifdef HAVE_SOCKETS
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);
6473 defsubr (&Sset_process_datagram_address); 6718 defsubr (&Sset_process_datagram_address);
6474 #endif 6719 #endif