18ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
28ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * System-dependent procedures for pppd under Solaris 2.
38ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
48ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Parts re-written by Adi Masputra <adi.masputra@sun.com>, based on
58ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * the original sys-svr4.c
68ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
78ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Copyright (c) 2000 by Sun Microsystems, Inc.
88ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * All rights reserved.
98ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Permission to use, copy, modify, and distribute this software and its
118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * documentation is hereby granted, provided that the above copyright
128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * notice appears in all copies.
138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * SUN MAKES NO REPRESENTATION OR WARRANTIES ABOUT THE SUITABILITY OF
158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * PARTICULAR PURPOSE, OR NON-INFRINGEMENT.  SUN SHALL NOT BE LIABLE FOR
188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES
208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Copyright (c) 1995-2002 Paul Mackerras. All rights reserved.
228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Redistribution and use in source and binary forms, with or without
248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * modification, are permitted provided that the following conditions
258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * are met:
268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 2. The name(s) of the authors of this software must not be used to
318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *    endorse or promote products derived from this software without
328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *    prior written permission.
338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 3. Redistributions of any form whatsoever must retain the following
358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *    acknowledgment:
368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *    "This product includes software developed by Paul Mackerras
378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *     <paulus@samba.org>".
388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Derived from main.c and pppd.h, which are:
488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved.
508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Redistribution and use in source and binary forms, with or without
528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * modification, are permitted provided that the following conditions
538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * are met:
548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *    notice, this list of conditions and the following disclaimer in
608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *    the documentation and/or other materials provided with the
618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *    distribution.
628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 3. The name "Carnegie Mellon University" must not be used to
648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *    endorse or promote products derived from this software without
658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *    prior written permission. For permission or any legal
668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *    details, please contact
678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *      Office of Technology Transfer
688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *      Carnegie Mellon University
698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *      5000 Forbes Avenue
708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *      Pittsburgh, PA  15213-3890
718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *      (412) 268-4387, fax: (412) 268-7395
728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *      tech-transfer@andrew.cmu.edu
738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 4. Redistributions of any form whatsoever must retain the following
758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *    acknowledgment:
768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *    "This product includes software developed by Computing Services
778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define RCSID	"$Id: sys-solaris.c,v 1.13 2004/11/04 10:02:26 paulus Exp $"
898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <limits.h>
918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <stdio.h>
928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <stddef.h>
938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <stdlib.h>
948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <string.h>
958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <ctype.h>
968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <errno.h>
978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <fcntl.h>
988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <unistd.h>
998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <termios.h>
1008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifndef CRTSCTS
1018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/termiox.h>
1028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
1038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <signal.h>
1048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <utmpx.h>
1058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <stropts.h>
1068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/types.h>
1078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/ioccom.h>
1088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/stream.h>
1098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/stropts.h>
1108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/socket.h>
1118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/sockio.h>
1128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/sysmacros.h>
1138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/systeminfo.h>
1148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/dlpi.h>
1158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/stat.h>
1168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/mkdev.h>
1178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <net/if.h>
1188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <net/if_arp.h>
1198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <net/route.h>
1208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <net/ppp_defs.h>
1218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <net/pppio.h>
1228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <netinet/in.h>
1238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef SOL2
1248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/tihdr.h>
1258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/tiuser.h>
1268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <inet/common.h>
1278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <inet/mib2.h>
1288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/ethernet.h>
1298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
1308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "pppd.h"
1328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "fsm.h"
1338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "lcp.h"
1348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "ipcp.h"
1358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "ccp.h"
1368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if !defined(PPP_DRV_NAME)
1388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define PPP_DRV_NAME	"ppp"
1398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* !defined(PPP_DRV_NAME) */
1408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if !defined(PPP_DEV_NAME)
1428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define PPP_DEV_NAME	"/dev/" PPP_DRV_NAME
1438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* !defined(PPP_DEV_NAME) */
1448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if !defined(AHDLC_MOD_NAME)
1468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define AHDLC_MOD_NAME	"ppp_ahdl"
1478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* !defined(AHDLC_MOD_NAME) */
1488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if !defined(COMP_MOD_NAME)
1508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define COMP_MOD_NAME	"ppp_comp"
1518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* !defined(COMP_MOD_NAME) */
1528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if !defined(IP_DEV_NAME)
1548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define	IP_DEV_NAME	"/dev/ip"
1558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* !defined(IP_DEV_NAME) */
1568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if !defined(IP_MOD_NAME)
1588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define	IP_MOD_NAME	"ip"
1598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* !defined(IP_MOD_NAME) */
1608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if !defined(UDP_DEV_NAME) && defined(SOL2)
1628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define	UDP_DEV_NAME	"/dev/udp"
1638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* !defined(UDP_DEV_NAME) && defined(SOL2) */
1648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if !defined(UDP6_DEV_NAME) && defined(SOL2)
1668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define	UDP6_DEV_NAME	"/dev/udp6"
1678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* !defined(UDP6_DEV_NAME) && defined(SOL2) */
1688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic const char rcsid[] = RCSID;
1708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if defined(SOL2)
1728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
1738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * "/dev/udp" is used as a multiplexor to PLINK the interface stream
1748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * under. It is used in place of "/dev/ip" since STREAMS will not let
1758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * a driver be PLINK'ed under itself, and "/dev/ip" is typically the
1768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * driver at the bottom of the tunneling interfaces stream.
1778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
1788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic char *mux_dev_name = UDP_DEV_NAME;
1798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#else
1808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic char *mux_dev_name = IP_DEV_NAME;
1818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
1828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int	pppfd;
1838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int	fdmuxid = -1;
1848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int	ipfd;
1858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int	ipmuxid = -1;
1868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if defined(INET6) && defined(SOL2)
1888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int	ip6fd;		/* IP file descriptor */
1898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int	ip6muxid = -1;	/* Multiplexer file descriptor */
1908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int	if6_is_up = 0;	/* IPv6 interface has been marked up */
1918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define _IN6_LLX_FROM_EUI64(l, s, eui64, as) do {	\
1938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	s->sin6_addr.s6_addr32[0] = htonl(as); 	\
1948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	eui64_copy(eui64, s->sin6_addr.s6_addr32[2]);	\
1958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	s->sin6_family = AF_INET6;		\
1968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	l.lifr_addr.ss_family = AF_INET6;	\
1978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	l.lifr_addrlen = 10;			\
1988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	l.lifr_addr = laddr;			\
1998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	} while (0)
2008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define IN6_LLADDR_FROM_EUI64(l, s, eui64)  \
2028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    _IN6_LLX_FROM_EUI64(l, s, eui64, 0xfe800000)
2038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define IN6_LLTOKEN_FROM_EUI64(l, s, eui64) \
2058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    _IN6_LLX_FROM_EUI64(l, s, eui64, 0)
2068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* defined(INET6) && defined(SOL2) */
2088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if defined(INET6) && defined(SOL2)
2108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic char	first_ether_name[LIFNAMSIZ];	/* Solaris 8 and above */
2118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#else
2128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic char	first_ether_name[IFNAMSIZ];	/* Before Solaris 8 */
2138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define MAXIFS		256			/* Max # of interfaces */
2148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* defined(INET6) && defined(SOL2) */
2158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int	restore_term;
2178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic struct termios inittermios;
2188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifndef CRTSCTS
2198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic struct termiox inittermiox;
2208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int	termiox_ok;
2218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
2228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic struct winsize wsinfo;	/* Initial window size info */
2238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic pid_t	tty_sid;	/* original session ID for terminal */
2248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectextern u_char	inpacket_buf[];	/* borrowed from main.c */
2268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define MAX_POLLFDS	32
2288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic struct pollfd pollfds[MAX_POLLFDS];
2298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int n_pollfds;
2308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int	link_mtu, link_mru;
2328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define NMODULES	32
2348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int	tty_nmodules;
2358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic char	tty_modules[NMODULES][FMNAMESZ+1];
2368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int	tty_npushed;
2378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int	if_is_up;	/* Interface has been marked up */
2398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic u_int32_t remote_addr;		/* IP address of peer */
2408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic u_int32_t default_route_gateway;	/* Gateway for default route added */
2418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic u_int32_t proxy_arp_addr;	/* Addr for proxy arp entry added */
2428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* Prototypes for procedures local to this file. */
2448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int translate_speed __P((int));
2458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int baud_rate_of __P((int));
2468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int get_ether_addr __P((u_int32_t, struct sockaddr *));
2478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int get_hw_addr __P((char *, u_int32_t, struct sockaddr *));
2488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int get_hw_addr_dlpi __P((char *, struct sockaddr *));
2498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int dlpi_attach __P((int, int));
2508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int dlpi_info_req __P((int));
2518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int dlpi_get_reply __P((int, union DL_primitives *, int, int));
2528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int strioctl __P((int, int, void *, int, int));
2538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef SOL2
2558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
2568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * sifppa - Sets interface ppa
2578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
2588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * without setting the ppa, ip module will return EINVAL upon setting the
2598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * interface UP (SIOCSxIFFLAGS). This is because ip module in 2.8 expects
2608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * two DLPI_INFO_REQ to be sent down to the driver (below ip) before
2618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * IFF_UP can be set. Plumbing the device causes one DLPI_INFO_REQ to
2628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * be sent down, and the second DLPI_INFO_REQ is sent upon receiving
2638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * IF_UNITSEL (old) or SIOCSLIFNAME (new) ioctls. Such setting of the ppa
2648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * is required because the ppp DLPI provider advertises itself as
2658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * a DLPI style 2 type, which requires a point of attachment to be
2668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * specified. The only way the user can specify a point of attachment
2678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * is via SIOCSLIFNAME or IF_UNITSEL.
2688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
2698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Such changes in the behavior of ip module was made to meet new or
2708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * evolving standards requirements.
2718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
2728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
2738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
2748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectsifppa(fd, ppa)
2758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int fd;
2768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int ppa;
2778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
2788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return (int)ioctl(fd, IF_UNITSEL, (char *)&ppa);
2798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
2808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* SOL2 */
2818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if defined(SOL2) && defined(INET6)
2838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
2848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * get_first_ethernet - returns the first Ethernet interface name found in
2858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * the system, or NULL if none is found
2868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
2878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * NOTE: This is the lifreq version (Solaris 8 and above)
2888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
2898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectchar *
2908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectget_first_ethernet()
2918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
2928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct lifnum lifn;
2938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct lifconf lifc;
2948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct lifreq *plifreq;
2958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct lifreq lifr;
2968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int	fd, num_ifs, i, found;
2978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    uint_t fl, req_size;
2988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char *req;
2998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fd = socket(AF_INET, SOCK_DGRAM, 0);
3018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (fd < 0) {
3028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
3038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
3048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
3068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Find out how many interfaces are running
3078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
3088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lifn.lifn_family = AF_UNSPEC;
3098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lifn.lifn_flags = LIFC_NOXMIT;
3108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(fd, SIOCGLIFNUM, &lifn) < 0) {
3118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(fd);
3128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("could not determine number of interfaces: %m");
3138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
3148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
3158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    num_ifs = lifn.lifn_count;
3178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    req_size = num_ifs * sizeof(struct lifreq);
3188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    req = malloc(req_size);
3198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (req == NULL) {
3208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(fd);
3218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("out of memory");
3228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
3238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
3248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
3268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Get interface configuration info for all interfaces
3278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
3288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lifc.lifc_family = AF_UNSPEC;
3298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lifc.lifc_flags = LIFC_NOXMIT;
3308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lifc.lifc_len = req_size;
3318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lifc.lifc_buf = req;
3328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(fd, SIOCGLIFCONF, &lifc) < 0) {
3338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(fd);
3348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	free(req);
3358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("SIOCGLIFCONF: %m");
3368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
3378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
3388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
3408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * And traverse each interface to look specifically for the first
3418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * occurence of an Ethernet interface which has been marked up
3428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
3438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    plifreq = lifc.lifc_req;
3448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    found = 0;
3458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    for (i = lifc.lifc_len / sizeof(struct lifreq); i > 0; i--, plifreq++) {
3468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (strchr(plifreq->lifr_name, ':') != NULL)
3488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    continue;
3498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	memset(&lifr, 0, sizeof(lifr));
3518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	strncpy(lifr.lifr_name, plifreq->lifr_name, sizeof(lifr.lifr_name));
3528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (ioctl(fd, SIOCGLIFFLAGS, &lifr) < 0) {
3538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    close(fd);
3548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    free(req);
3558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    error("SIOCGLIFFLAGS: %m");
3568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return 0;
3578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
3588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fl = lifr.lifr_flags;
3598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if ((fl & (IFF_UP|IFF_BROADCAST|IFF_POINTOPOINT|IFF_LOOPBACK|IFF_NOARP))
3618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		!= (IFF_UP | IFF_BROADCAST))
3628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    continue;
3638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	found = 1;
3658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	break;
3668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
3678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    free(req);
3688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    close(fd);
3698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (found) {
3718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	strncpy(first_ether_name, lifr.lifr_name, sizeof(first_ether_name));
3728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return (char *)first_ether_name;
3738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } else
3748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return NULL;
3758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
3768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#else
3778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
3788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * get_first_ethernet - returns the first Ethernet interface name found in
3798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * the system, or NULL if none is found
3808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
3818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * NOTE: This is the ifreq version (before Solaris 8).
3828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
3838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectchar *
3848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectget_first_ethernet()
3858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
3868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct ifconf ifc;
3878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct ifreq *pifreq;
3888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct ifreq ifr;
3898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int	fd, num_ifs, i, found;
3908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    uint_t fl, req_size;
3918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char *req;
3928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fd = socket(AF_INET, SOCK_DGRAM, 0);
3948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (fd < 0) {
3958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
3968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
3978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
3998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Find out how many interfaces are running
4008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
4018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(fd, SIOCGIFNUM, (char *)&num_ifs) < 0) {
4028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	num_ifs = MAXIFS;
4038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
4048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    req_size = num_ifs * sizeof(struct ifreq);
4068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    req = malloc(req_size);
4078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (req == NULL) {
4088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(fd);
4098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("out of memory");
4108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
4118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
4128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
4148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Get interface configuration info for all interfaces
4158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
4168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ifc.ifc_len = req_size;
4178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ifc.ifc_buf = req;
4188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(fd, SIOCGIFCONF, &ifc) < 0) {
4198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(fd);
4208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	free(req);
4218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("SIOCGIFCONF: %m");
4228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
4238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
4248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
4268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * And traverse each interface to look specifically for the first
4278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * occurence of an Ethernet interface which has been marked up
4288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
4298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    pifreq = ifc.ifc_req;
4308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    found = 0;
4318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    for (i = ifc.ifc_len / sizeof(struct ifreq); i > 0; i--, pifreq++) {
4328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (strchr(pifreq->ifr_name, ':') != NULL)
4348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    continue;
4358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	memset(&ifr, 0, sizeof(ifr));
4378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	strncpy(ifr.ifr_name, pifreq->ifr_name, sizeof(ifr.ifr_name));
4388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
4398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    close(fd);
4408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    free(req);
4418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    error("SIOCGIFFLAGS: %m");
4428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return 0;
4438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
4448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fl = ifr.ifr_flags;
4458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if ((fl & (IFF_UP|IFF_BROADCAST|IFF_POINTOPOINT|IFF_LOOPBACK|IFF_NOARP))
4478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		!= (IFF_UP | IFF_BROADCAST))
4488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    continue;
4498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	found = 1;
4518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	break;
4528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
4538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    free(req);
4548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    close(fd);
4558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (found) {
4578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	strncpy(first_ether_name, ifr.ifr_name, sizeof(first_ether_name));
4588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return (char *)first_ether_name;
4598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } else
4608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return NULL;
4618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
4628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* defined(SOL2) && defined(INET6) */
4638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if defined(SOL2)
4658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
4668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * get_if_hwaddr - get the hardware address for the specified
4678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * network interface device.
4688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
4698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
4708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectget_if_hwaddr(u_char *addr, char *if_name)
4718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
4728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct sockaddr s_eth_addr;
4738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct ether_addr *eth_addr = (struct ether_addr *)&s_eth_addr.sa_data;
4748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (if_name == NULL)
4768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return -1;
4778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
4798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Send DL_INFO_REQ to the driver to solicit its MAC address
4808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
4818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!get_hw_addr_dlpi(if_name, &s_eth_addr)) {
4828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("could not obtain hardware address for %s", if_name);
4838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return -1;
4848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
4858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memcpy(addr, eth_addr->ether_addr_octet, 6);
4878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
4888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
4898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* SOL2 */
4908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if defined(SOL2) && defined(INET6)
4928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
4938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * slifname - Sets interface ppa and flags
4948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
4958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * in addition to the comments stated in sifppa(), IFF_IPV6 bit must
4968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * be set in order to declare this as an IPv6 interface
4978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
4988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
4998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectslifname(fd, ppa)
5008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int fd;
5018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int ppa;
5028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
5038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct  lifreq lifr;
5048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int	    ret;
5058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset(&lifr, 0, sizeof(lifr));
5078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ret = ioctl(fd, SIOCGLIFFLAGS, &lifr);
5088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ret < 0)
5098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	goto slifname_done;
5108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lifr.lifr_flags |= IFF_IPV6;
5128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lifr.lifr_flags &= ~(IFF_BROADCAST | IFF_IPV4);
5138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lifr.lifr_ppa = ppa;
5148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name));
5158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ret = ioctl(fd, SIOCSLIFNAME, &lifr);
5178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectslifname_done:
5198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return ret;
5208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
5238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
5268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ether_to_eui64 - Convert 48-bit Ethernet address into 64-bit EUI
5278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
5288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * walks the list of valid ethernet interfaces, and convert the first
5298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * found 48-bit MAC address into EUI 64. caller also assumes that
5308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * the system has a properly configured Ethernet interface for this
5318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * function to return non-zero.
5328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
5338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
5348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectether_to_eui64(eui64_t *p_eui64)
5358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
5368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct sockaddr s_eth_addr;
5378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct ether_addr *eth_addr = (struct ether_addr *)&s_eth_addr.sa_data;
5388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char *if_name;
5398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if ((if_name = get_first_ethernet()) == NULL) {
5418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("no persistent id can be found");
5428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
5438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
5448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
5468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Send DL_INFO_REQ to the driver to solicit its MAC address
5478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
5488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!get_hw_addr_dlpi(if_name, &s_eth_addr)) {
5498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("could not obtain hardware address for %s", if_name);
5508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
5518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
5528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
5548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * And convert the EUI-48 into EUI-64, per RFC 2472 [sec 4.1]
5558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
5568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    p_eui64->e8[0] = (eth_addr->ether_addr_octet[0] & 0xFF) | 0x02;
5578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    p_eui64->e8[1] = (eth_addr->ether_addr_octet[1] & 0xFF);
5588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    p_eui64->e8[2] = (eth_addr->ether_addr_octet[2] & 0xFF);
5598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    p_eui64->e8[3] = 0xFF;
5608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    p_eui64->e8[4] = 0xFE;
5618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    p_eui64->e8[5] = (eth_addr->ether_addr_octet[3] & 0xFF);
5628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    p_eui64->e8[6] = (eth_addr->ether_addr_octet[4] & 0xFF);
5638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    p_eui64->e8[7] = (eth_addr->ether_addr_octet[5] & 0xFF);
5648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
5668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
5678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* defined(SOL2) && defined(INET6) */
5688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
5708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * sys_init - System-dependent initialization.
5718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
5728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
5738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectsys_init()
5748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
5758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int ifd, x;
5768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct ifreq ifr;
5778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if defined(INET6) && defined(SOL2)
5788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int i6fd;
5798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct lifreq lifr;
5808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* defined(INET6) && defined(SOL2) */
5818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if !defined(SOL2)
5828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct {
5838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	union DL_primitives prim;
5848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	char space[64];
5858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } reply;
5868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* !defined(SOL2) */
5878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ipfd = open(mux_dev_name, O_RDWR, 0);
5898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ipfd < 0)
5908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fatal("Couldn't open IP device: %m");
5918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if defined(INET6) && defined(SOL2)
5938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ip6fd = open(UDP6_DEV_NAME, O_RDWR, 0);
5948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ip6fd < 0)
5958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fatal("Couldn't open IP device (2): %m");
5968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* defined(INET6) && defined(SOL2) */
5978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (default_device && !notty)
5998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	tty_sid = getsid((pid_t)0);
6008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    pppfd = open(PPP_DEV_NAME, O_RDWR | O_NONBLOCK, 0);
6028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (pppfd < 0)
6038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fatal("Can't open %s: %m", PPP_DEV_NAME);
6048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (kdebugflag & 1) {
6058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	x = PPPDBG_LOG + PPPDBG_DRIVER;
6068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	strioctl(pppfd, PPPIO_DEBUG, &x, sizeof(int), 0);
6078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
6088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* Assign a new PPA and get its unit number. */
6108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (strioctl(pppfd, PPPIO_NEWPPA, &ifunit, 0, sizeof(int)) < 0)
6118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fatal("Can't create new PPP interface: %m");
6128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if defined(SOL2)
6148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
6158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Since sys_init() is called prior to ifname being set in main(),
6168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * we need to get the ifname now, otherwise slifname(), and others,
6178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * will fail, or maybe, I should move them to a later point ?
6188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * <adi.masputra@sun.com>
6198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
6208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    sprintf(ifname, PPP_DRV_NAME "%d", ifunit);
6218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* defined(SOL2) */
6228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
6238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Open the ppp device again and link it under the ip multiplexor.
6248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * IP will assign a unit number which hopefully is the same as ifunit.
6258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * I don't know any way to be certain they will be the same. :-(
6268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
6278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ifd = open(PPP_DEV_NAME, O_RDWR, 0);
6288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ifd < 0)
6298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fatal("Can't open %s (2): %m", PPP_DEV_NAME);
6308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (kdebugflag & 1) {
6318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	x = PPPDBG_LOG + PPPDBG_DRIVER;
6328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	strioctl(ifd, PPPIO_DEBUG, &x, sizeof(int), 0);
6338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
6348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if defined(INET6) && defined(SOL2)
6368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    i6fd = open(PPP_DEV_NAME, O_RDWR, 0);
6378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (i6fd < 0) {
6388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(ifd);
6398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fatal("Can't open %s (3): %m", PPP_DEV_NAME);
6408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
6418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (kdebugflag & 1) {
6428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	x = PPPDBG_LOG + PPPDBG_DRIVER;
6438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	strioctl(i6fd, PPPIO_DEBUG, &x, sizeof(int), 0);
6448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
6458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* defined(INET6) && defined(SOL2) */
6468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if defined(SOL2)
6488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ifd, I_PUSH, IP_MOD_NAME) < 0) {
6498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(ifd);
6508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if defined(INET6)
6518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(i6fd);
6528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* defined(INET6) */
6538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fatal("Can't push IP module: %m");
6548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
6558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
6578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Assign ppa according to the unit number returned by ppp device
6588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * after plumbing is completed above.
6598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
6608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (sifppa(ifd, ifunit) < 0) {
6618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        close (ifd);
6628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if defined(INET6)
6638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(i6fd);
6648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* defined(INET6) */
6658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        fatal("Can't set ppa for unit %d: %m", ifunit);
6668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
6678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if defined(INET6)
6698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
6708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * An IPv6 interface is created anyway, even when the user does not
6718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * explicitly enable it. Note that the interface will be marked
6728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * IPv6 during slifname().
6738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
6748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(i6fd, I_PUSH, IP_MOD_NAME) < 0) {
6758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(ifd);
6768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(i6fd);
6778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fatal("Can't push IP module (2): %m");
6788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
6798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
6818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Assign ppa according to the unit number returned by ppp device
6828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * after plumbing is completed above. In addition, mark the interface
6838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * as an IPv6 interface.
6848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
6858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (slifname(i6fd, ifunit) < 0) {
6868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(ifd);
6878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(i6fd);
6888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fatal("Can't set ifname for unit %d: %m", ifunit);
6898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
6908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* defined(INET6) */
6918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ipmuxid = ioctl(ipfd, I_PLINK, ifd);
6938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    close(ifd);
6948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ipmuxid < 0) {
6958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if defined(INET6)
6968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(i6fd);
6978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* defined(INET6) */
6988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fatal("Can't I_PLINK PPP device to IP: %m");
6998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
7008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset(&ifr, 0, sizeof(ifr));
7028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    sprintf(ifr.ifr_name, "%s", ifname);
7038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ifr.ifr_ip_muxid = ipmuxid;
7048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
7068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * In Sol 8 and later, STREAMS dynamic module plumbing feature exists.
7078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * This is so that an arbitrary module can be inserted, or deleted,
7088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * between ip module and the device driver without tearing down the
7098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * existing stream. Such feature requires the mux ids, which is set
7108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * by SIOCSIFMUXID (or SIOCLSIFMUXID).
7118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
7128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ipfd, SIOCSIFMUXID, &ifr) < 0) {
7138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ioctl(ipfd, I_PUNLINK, ipmuxid);
7148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if defined(INET6)
7158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(i6fd);
7168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* defined(INET6) */
7178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fatal("SIOCSIFMUXID: %m");
7188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
7198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#else /* else if !defined(SOL2) */
7218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (dlpi_attach(ifd, ifunit) < 0 ||
7238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	dlpi_get_reply(ifd, &reply.prim, DL_OK_ACK, sizeof(reply)) < 0) {
7248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(ifd);
7258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fatal("Can't attach to ppp%d: %m", ifunit);
7268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
7278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ipmuxid = ioctl(ipfd, I_LINK, ifd);
7298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    close(ifd);
7308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ipmuxid < 0)
7318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fatal("Can't link PPP device to IP: %m");
7328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* defined(SOL2) */
7338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if defined(INET6) && defined(SOL2)
7358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ip6muxid = ioctl(ip6fd, I_PLINK, i6fd);
7368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    close(i6fd);
7378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ip6muxid < 0) {
7388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ioctl(ipfd, I_PUNLINK, ipmuxid);
7398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fatal("Can't I_PLINK PPP device to IP (2): %m");
7408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
7418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset(&lifr, 0, sizeof(lifr));
7438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    sprintf(lifr.lifr_name, "%s", ifname);
7448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lifr.lifr_ip_muxid = ip6muxid;
7458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
7478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Let IP know of the mux id [see comment for SIOCSIFMUXID above]
7488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
7498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ip6fd, SIOCSLIFMUXID, &lifr) < 0) {
7508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ioctl(ipfd, I_PUNLINK, ipmuxid);
7518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ioctl(ip6fd, I_PUNLINK, ip6muxid);
7528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fatal("Can't link PPP device to IP (2): %m");
7538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
7548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* defined(INET6) && defined(SOL2) */
7558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if !defined(SOL2)
7578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* Set the interface name for the link. */
7588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    slprintf(ifr.ifr_name, sizeof(ifr.ifr_name), PPP_DRV_NAME "%d", ifunit);
7598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ifr.ifr_metric = ipmuxid;
7608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (strioctl(ipfd, SIOCSIFNAME, (char *)&ifr, sizeof ifr, 0) < 0)
7618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fatal("Can't set interface name %s: %m", ifr.ifr_name);
7628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* !defined(SOL2) */
7638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    n_pollfds = 0;
7658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
7668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
7688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * sys_cleanup - restore any system state we modified before exiting:
7698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * mark the interface down, delete default route and/or proxy arp entry.
7708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * This should call die() because it's called from die().
7718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
7728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
7738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectsys_cleanup()
7748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
7758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if defined(SOL2)
7768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct ifreq ifr;
7778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if defined(INET6)
7788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct lifreq lifr;
7798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* defined(INET6) */
7808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* defined(SOL2) */
7818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if defined(SOL2) && defined(INET6)
7838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (if6_is_up)
7848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	sif6down(0);
7858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* defined(SOL2) && defined(INET6) */
7868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (if_is_up)
7878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	sifdown(0);
7888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (default_route_gateway)
7898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	cifdefaultroute(0, default_route_gateway, default_route_gateway);
7908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (proxy_arp_addr)
7918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	cifproxyarp(0, proxy_arp_addr);
7928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if defined(SOL2)
7938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
7948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Make sure we ask ip what the muxid, because 'ifconfig modlist' will
7958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * unlink and re-link the modules, causing the muxid to change.
7968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
7978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset(&ifr, 0, sizeof(ifr));
7988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    sprintf(ifr.ifr_name, "%s", ifname);
7998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ipfd, SIOCGIFFLAGS, &ifr) < 0) {
8008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("SIOCGIFFLAGS: %m");
8018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return;
8028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
8038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ipfd, SIOCGIFMUXID, &ifr) < 0) {
8058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("SIOCGIFMUXID: %m");
8068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return;
8078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
8088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ipmuxid = ifr.ifr_ip_muxid;
8108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ipfd, I_PUNLINK, ipmuxid) < 0) {
8128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Can't I_PUNLINK PPP from IP: %m");
8138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return;
8148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
8158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if defined(INET6)
8168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
8178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Make sure we ask ip what the muxid, because 'ifconfig modlist' will
8188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * unlink and re-link the modules, causing the muxid to change.
8198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
8208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset(&lifr, 0, sizeof(lifr));
8218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    sprintf(lifr.lifr_name, "%s", ifname);
8228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ip6fd, SIOCGLIFFLAGS, &lifr) < 0) {
8238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("SIOCGLIFFLAGS: %m");
8248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return;
8258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
8268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ip6fd, SIOCGLIFMUXID, &lifr) < 0) {
8288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("SIOCGLIFMUXID: %m");
8298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return;
8308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
8318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ip6muxid = lifr.lifr_ip_muxid;
8338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ip6fd, I_PUNLINK, ip6muxid) < 0) {
8358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Can't I_PUNLINK PPP from IP (2): %m");
8368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
8378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* defined(INET6) */
8388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* defined(SOL2) */
8398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
8408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
8428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * sys_close - Clean up in a child process before execing.
8438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
8448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
8458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectsys_close()
8468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
8478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    close(ipfd);
8488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if defined(INET6) && defined(SOL2)
8498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    close(ip6fd);
8508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* defined(INET6) && defined(SOL2) */
8518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (pppfd >= 0)
8528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(pppfd);
8538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
8548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
8568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * sys_check_options - check the options that the user specified
8578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
8588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
8598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectsys_check_options()
8608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
8618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
8628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
8638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if 0
8658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
8668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * daemon - Detach us from controlling terminal session.
8678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
8688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
8698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectdaemon(nochdir, noclose)
8708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int nochdir, noclose;
8718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
8728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int pid;
8738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if ((pid = fork()) < 0)
8758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return -1;
8768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (pid != 0)
8778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	exit(0);		/* parent dies */
8788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    setsid();
8798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!nochdir)
8808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	chdir("/");
8818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!noclose) {
8828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fclose(stdin);		/* don't need stdin, stdout, stderr */
8838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fclose(stdout);
8848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fclose(stderr);
8858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
8868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 0;
8878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
8888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
8898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
8918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ppp_available - check whether the system has any ppp interfaces
8928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
8938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
8948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectppp_available()
8958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
8968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct stat buf;
8978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return stat(PPP_DEV_NAME, &buf) >= 0;
8998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
9008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
9028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * any_compressions - see if compression is enabled or not
9038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *
9048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * In the STREAMS implementation of kernel-portion pppd,
9058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * the comp STREAMS module performs the ACFC, PFC, as well
9068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * CCP and VJ compressions. However, if the user has explicitly
9078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * declare to not enable them from the command line, there is
9088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * no point of having the comp module be pushed on the stream.
9098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
9108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
9118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectany_compressions()
9128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
9138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if ((!lcp_wantoptions[0].neg_accompression) &&
9148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	(!lcp_wantoptions[0].neg_pcompression) &&
9158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	(!ccp_protent.enabled_flag) &&
9168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	(!ipcp_wantoptions[0].neg_vj)) {
9178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return 0;
9188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
9198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
9208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
9218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
9238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * tty_establish_ppp - Turn the serial port into a ppp interface.
9248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
9258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
9268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecttty_establish_ppp(fd)
9278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int fd;
9288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
9298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int i;
9308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* Pop any existing modules off the tty stream. */
9328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    for (i = 0;; ++i)
9338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (ioctl(fd, I_LOOK, tty_modules[i]) < 0
9348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    || strcmp(tty_modules[i], "ptem") == 0
9358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    || ioctl(fd, I_POP, 0) < 0)
9368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
9378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    tty_nmodules = i;
9388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* Push the async hdlc module and the compressor module. */
9408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    tty_npushed = 0;
9418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if(!sync_serial) {
9438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        if (ioctl(fd, I_PUSH, AHDLC_MOD_NAME) < 0) {
9448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project            error("Couldn't push PPP Async HDLC module: %m");
9458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return -1;
9468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        }
9478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        ++tty_npushed;
9488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
9498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (kdebugflag & 4) {
9508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	i = PPPDBG_LOG + PPPDBG_AHDLC;
9518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	strioctl(pppfd, PPPIO_DEBUG, &i, sizeof(int), 0);
9528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
9538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
9548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * There's no need to push comp module if we don't intend
9558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * to compress anything
9568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
9578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (any_compressions()) {
9588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project        if (ioctl(fd, I_PUSH, COMP_MOD_NAME) < 0)
9598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    error("Couldn't push PPP compression module: %m");
9608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	else
9618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ++tty_npushed;
9628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
9638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (kdebugflag & 2) {
9658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	i = PPPDBG_LOG;
9668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (any_compressions())
9678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    i += PPPDBG_COMP;
9688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	strioctl(pppfd, PPPIO_DEBUG, &i, sizeof(int), 0);
9698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
9708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* Link the serial port under the PPP multiplexor. */
9728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if ((fdmuxid = ioctl(pppfd, I_LINK, fd)) < 0) {
9738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Can't link tty to PPP mux: %m");
9748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return -1;
9758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
9768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return pppfd;
9788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
9798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
9818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * tty_disestablish_ppp - Restore the serial port to normal operation.
9828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * It attempts to reconstruct the stream with the previously popped
9838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * modules.  This shouldn't call die() because it's called from die().
9848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
9858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
9868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecttty_disestablish_ppp(fd)
9878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int fd;
9888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
9898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int i;
9908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (fdmuxid >= 0) {
9928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (ioctl(pppfd, I_UNLINK, fdmuxid) < 0) {
9938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (!hungup)
9948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		error("Can't unlink tty from PPP mux: %m");
9958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
9968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fdmuxid = -1;
9978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (!hungup) {
9998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    while (tty_npushed > 0 && ioctl(fd, I_POP, 0) >= 0)
10008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		--tty_npushed;
10018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    for (i = tty_nmodules - 1; i >= 0; --i)
10028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (ioctl(fd, I_PUSH, tty_modules[i]) < 0)
10038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    error("Couldn't restore tty module %s: %m",
10048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			   tty_modules[i]);
10058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
10068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (hungup && default_device && tty_sid > 0) {
10078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /*
10088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * If we have received a hangup, we need to send a SIGHUP
10098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * to the terminal's controlling process.  The reason is
10108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * that the original stream head for the terminal hasn't
10118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * seen the M_HANGUP message (it went up through the ppp
10128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * driver to the stream head for our fd to /dev/ppp).
10138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     */
10148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    kill(tty_sid, SIGHUP);
10158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
10168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
10178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
10188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
10208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Check whether the link seems not to be 8-bit clean.
10218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
10228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
10238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectclean_check()
10248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
10258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int x;
10268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char *s;
10278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (strioctl(pppfd, PPPIO_GCLEAN, &x, 0, sizeof(x)) < 0)
10298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return;
10308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    s = NULL;
10318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    switch (~x) {
10328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case RCV_B7_0:
10338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	s = "bit 7 set to 1";
10348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	break;
10358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case RCV_B7_1:
10368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	s = "bit 7 set to 0";
10378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	break;
10388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case RCV_EVNP:
10398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	s = "odd parity";
10408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	break;
10418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case RCV_ODDP:
10428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	s = "even parity";
10438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	break;
10448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
10458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (s != NULL) {
10468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	warn("Serial link is not 8-bit clean:");
10478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	warn("All received characters had %s", s);
10488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
10498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
10508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
10528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * List of valid speeds.
10538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
10548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstruct speed {
10558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int speed_int, speed_val;
10568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} speeds[] = {
10578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef B50
10588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { 50, B50 },
10598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
10608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef B75
10618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { 75, B75 },
10628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
10638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef B110
10648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { 110, B110 },
10658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
10668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef B134
10678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { 134, B134 },
10688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
10698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef B150
10708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { 150, B150 },
10718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
10728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef B200
10738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { 200, B200 },
10748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
10758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef B300
10768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { 300, B300 },
10778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
10788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef B600
10798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { 600, B600 },
10808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
10818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef B1200
10828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { 1200, B1200 },
10838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
10848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef B1800
10858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { 1800, B1800 },
10868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
10878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef B2000
10888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { 2000, B2000 },
10898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
10908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef B2400
10918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { 2400, B2400 },
10928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
10938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef B3600
10948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { 3600, B3600 },
10958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
10968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef B4800
10978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { 4800, B4800 },
10988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
10998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef B7200
11008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { 7200, B7200 },
11018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
11028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef B9600
11038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { 9600, B9600 },
11048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
11058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef B19200
11068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { 19200, B19200 },
11078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
11088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef B38400
11098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { 38400, B38400 },
11108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
11118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef EXTA
11128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { 19200, EXTA },
11138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
11148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef EXTB
11158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { 38400, EXTB },
11168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
11178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef B57600
11188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { 57600, B57600 },
11198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
11208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef B76800
11218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { 76800, B76800 },
11228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
11238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef B115200
11248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { 115200, B115200 },
11258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
11268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef B153600
11278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { 153600, B153600 },
11288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
11298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef B230400
11308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { 230400, B230400 },
11318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
11328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef B307200
11338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { 307200, B307200 },
11348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
11358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef B460800
11368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { 460800, B460800 },
11378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
11388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { 0, 0 }
11398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project};
11408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
11428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Translate from bits/second to a speed_t.
11438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
11448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
11458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecttranslate_speed(bps)
11468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int bps;
11478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
11488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct speed *speedp;
11498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (bps == 0)
11518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
11528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    for (speedp = speeds; speedp->speed_int; speedp++)
11538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (bps == speedp->speed_int)
11548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return speedp->speed_val;
11558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    warn("speed %d not supported", bps);
11568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 0;
11578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
11588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
11608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Translate from a speed_t to bits/second.
11618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
11628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
11638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectbaud_rate_of(speed)
11648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int speed;
11658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
11668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct speed *speedp;
11678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (speed == 0)
11698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
11708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    for (speedp = speeds; speedp->speed_int; speedp++)
11718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (speed == speedp->speed_val)
11728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return speedp->speed_int;
11738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 0;
11748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
11758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
11778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * set_up_tty: Set up the serial port on `fd' for 8 bits, no parity,
11788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * at the requested speed, etc.  If `local' is true, set CLOCAL
11798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * regardless of whether the modem option was specified.
11808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
11818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
11828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectset_up_tty(fd, local)
11838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int fd, local;
11848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
11858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int speed;
11868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct termios tios;
11878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if !defined (CRTSCTS)
11888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct termiox tiox;
11898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
11908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!sync_serial && tcgetattr(fd, &tios) < 0)
11928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fatal("tcgetattr: %m");
11938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifndef CRTSCTS
11958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    termiox_ok = 1;
11968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!sync_serial && ioctl (fd, TCGETX, &tiox) < 0) {
11978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	termiox_ok = 0;
11988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (errno != ENOTTY)
11998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    error("TCGETX: %m");
12008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
12018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
12028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!restore_term) {
12048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	inittermios = tios;
12058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifndef CRTSCTS
12068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	inittermiox = tiox;
12078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
12088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (!sync_serial)
12098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ioctl(fd, TIOCGWINSZ, &wsinfo);
12108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
12118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);
12138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef CRTSCTS
12148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (crtscts > 0)
12158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	tios.c_cflag |= CRTSCTS;
12168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    else if (crtscts < 0)
12178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	tios.c_cflag &= ~CRTSCTS;
12188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#else
12198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (crtscts != 0 && !termiox_ok) {
12208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Can't set RTS/CTS flow control");
12218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } else if (crtscts > 0) {
12228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	tiox.x_hflag |= RTSXOFF|CTSXON;
12238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } else if (crtscts < 0) {
12248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	tiox.x_hflag &= ~(RTSXOFF|CTSXON);
12258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
12268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
12278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    tios.c_cflag |= CS8 | CREAD | HUPCL;
12298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (local || !modem)
12308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	tios.c_cflag |= CLOCAL;
12318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    tios.c_iflag = IGNBRK | IGNPAR;
12328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    tios.c_oflag = 0;
12338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    tios.c_lflag = 0;
12348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    tios.c_cc[VMIN] = 1;
12358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    tios.c_cc[VTIME] = 0;
12368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (crtscts == -2) {
12388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	tios.c_iflag |= IXON | IXOFF;
12398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	tios.c_cc[VSTOP] = 0x13;	/* DC3 = XOFF = ^S */
12408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	tios.c_cc[VSTART] = 0x11;	/* DC1 = XON  = ^Q */
12418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
12428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    speed = translate_speed(inspeed);
12448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (speed) {
12458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	cfsetospeed(&tios, speed);
12468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	cfsetispeed(&tios, speed);
12478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } else {
12488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	speed = cfgetospeed(&tios);
12498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/*
12508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * We can't proceed if the serial port speed is 0,
12518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * since that implies that the serial port is disabled.
12528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 */
12538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if ((speed == B0) && !sync_serial)
12548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    fatal("Baud rate for %s is 0; need explicit baud rate", devnam);
12558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
12568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!sync_serial && tcsetattr(fd, TCSAFLUSH, &tios) < 0)
12588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fatal("tcsetattr: %m");
12598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifndef CRTSCTS
12618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!sync_serial && termiox_ok && ioctl (fd, TCSETXF, &tiox) < 0){
12628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("TCSETXF: %m");
12638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
12648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
12658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    baud_rate = inspeed = baud_rate_of(speed);
12678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!sync_serial)
12688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	restore_term = 1;
12698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
12708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
12728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * restore_tty - restore the terminal to the saved settings.
12738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
12748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
12758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectrestore_tty(fd)
12768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int fd;
12778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
12788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (restore_term) {
12798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (!default_device) {
12808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /*
12818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * Turn off echoing, because otherwise we can get into
12828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * a loop with the tty and the modem echoing to each other.
12838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * We presume we are the sole user of this tty device, so
12848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * when we close it, it will revert to its defaults anyway.
12858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     */
12868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    inittermios.c_lflag &= ~(ECHO | ECHONL);
12878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
12888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (!sync_serial && tcsetattr(fd, TCSAFLUSH, &inittermios) < 0)
12898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (!hungup && errno != ENXIO)
12908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		warn("tcsetattr: %m");
12918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifndef CRTSCTS
12928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (!sync_serial && ioctl (fd, TCSETXF, &inittermiox) < 0){
12938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (!hungup && errno != ENXIO)
12948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		error("TCSETXF: %m");
12958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
12968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
12978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (!sync_serial)
12988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ioctl(fd, TIOCSWINSZ, &wsinfo);
12998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	restore_term = 0;
13008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
13018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
13028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
13048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * setdtr - control the DTR line on the serial port.
13058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * This is called from die(), so it shouldn't call die().
13068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
13078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
13088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectsetdtr(fd, on)
13098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint fd, on;
13108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
13118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int modembits = TIOCM_DTR;
13128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ioctl(fd, (on? TIOCMBIS: TIOCMBIC), &modembits);
13148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
13158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
13178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * open_loopback - open the device we use for getting packets
13188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * in demand mode.  Under Solaris 2, we use our existing fd
13198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * to the ppp driver.
13208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
13218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
13228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectopen_ppp_loopback()
13238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
13248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return pppfd;
13258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
13268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
13288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * output - Output PPP packet.
13298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
13308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
13318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectoutput(unit, p, len)
13328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit;
13338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *p;
13348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int len;
13358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
13368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct strbuf data;
13378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int retries;
13388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct pollfd pfd;
13398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    dump_packet("sent", p, len);
13418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (snoop_send_hook) snoop_send_hook(p, len);
13428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    data.len = len;
13448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    data.buf = (caddr_t) p;
13458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    retries = 4;
13468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    while (putmsg(pppfd, NULL, &data, 0) < 0) {
13478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (--retries < 0 || (errno != EWOULDBLOCK && errno != EAGAIN)) {
13488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (errno != ENXIO)
13498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		error("Couldn't send packet: %m");
13508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
13518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
13528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	pfd.fd = pppfd;
13538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	pfd.events = POLLOUT;
13548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	poll(&pfd, 1, 250);	/* wait for up to 0.25 seconds */
13558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
13568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
13578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
13608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * wait_input - wait until there is data available,
13618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * for the length of time specified by *timo (indefinite
13628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * if timo is NULL).
13638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
13648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
13658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectwait_input(timo)
13668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct timeval *timo;
13678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
13688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int t;
13698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    t = timo == NULL? -1: timo->tv_sec * 1000 + timo->tv_usec / 1000;
13718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (poll(pollfds, n_pollfds, t) < 0 && errno != EINTR)
13728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fatal("poll: %m");
13738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
13748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
13768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * add_fd - add an fd to the set that wait_input waits for.
13778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
13788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid add_fd(fd)
13798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int fd;
13808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
13818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int n;
13828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    for (n = 0; n < n_pollfds; ++n)
13848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (pollfds[n].fd == fd)
13858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return;
13868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (n_pollfds < MAX_POLLFDS) {
13878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	pollfds[n_pollfds].fd = fd;
13888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	pollfds[n_pollfds].events = POLLIN | POLLPRI | POLLHUP;
13898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	++n_pollfds;
13908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } else
13918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Too many inputs!");
13928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
13938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
13958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * remove_fd - remove an fd from the set that wait_input waits for.
13968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
13978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid remove_fd(fd)
13988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int fd;
13998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
14008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int n;
14018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    for (n = 0; n < n_pollfds; ++n) {
14038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (pollfds[n].fd == fd) {
14048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    while (++n < n_pollfds)
14058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		pollfds[n-1] = pollfds[n];
14068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    --n_pollfds;
14078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
14088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
14098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
14108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
14118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if 0
14138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
14148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * wait_loop_output - wait until there is data available on the
14158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * loopback, for the length of time specified by *timo (indefinite
14168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * if timo is NULL).
14178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
14188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
14198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectwait_loop_output(timo)
14208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct timeval *timo;
14218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
14228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    wait_input(timo);
14238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
14248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
14268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * wait_time - wait for a given length of time or until a
14278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * signal is received.
14288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
14298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
14308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectwait_time(timo)
14318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct timeval *timo;
14328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
14338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int n;
14348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    n = select(0, NULL, NULL, NULL, timo);
14368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (n < 0 && errno != EINTR)
14378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fatal("select: %m");
14388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
14398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
14408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
14438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * read_packet - get a PPP packet from the serial device.
14448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
14458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
14468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectread_packet(buf)
14478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *buf;
14488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
14498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct strbuf ctrl, data;
14508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int flags, len;
14518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    unsigned char ctrlbuf[sizeof(union DL_primitives) + 64];
14528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    for (;;) {
14548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	data.maxlen = PPP_MRU + PPP_HDRLEN;
14558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	data.buf = (caddr_t) buf;
14568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ctrl.maxlen = sizeof(ctrlbuf);
14578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ctrl.buf = (caddr_t) ctrlbuf;
14588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	flags = 0;
14598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len = getmsg(pppfd, &ctrl, &data, &flags);
14608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (len < 0) {
14618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (errno == EAGAIN || errno == EINTR)
14628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		return -1;
14638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    fatal("Error reading packet: %m");
14648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
14658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (ctrl.len <= 0)
14678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return data.len;
14688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/*
14708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * Got a M_PROTO or M_PCPROTO message.  Interpret it
14718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * as a DLPI primitive??
14728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 */
14738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (debug)
14748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    dbglog("got dlpi prim 0x%x, len=%d",
14758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		   ((union DL_primitives *)ctrlbuf)->dl_primitive, ctrl.len);
14768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
14788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
14798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
14818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * get_loop_output - get outgoing packets from the ppp device,
14828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * and detect when we want to bring the real link up.
14838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Return value is 1 if we need to bring up the link, 0 otherwise.
14848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
14858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
14868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectget_loop_output()
14878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
14888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int len;
14898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int rv = 0;
14908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    while ((len = read_packet(inpacket_buf)) > 0) {
14928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (loop_frame(inpacket_buf, len))
14938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    rv = 1;
14948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
14958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return rv;
14968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
14978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
14998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * netif_set_mtu - set the MTU on the PPP network interface.
15008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
15018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
15028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectnetif_set_mtu(unit, mtu)
15038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit, mtu;
15048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
15058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct ifreq ifr;
15068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if defined(INET6) && defined(SOL2)
15078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct lifreq lifr;
15088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int	fd;
15098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* defined(INET6) && defined(SOL2) */
15108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset(&ifr, 0, sizeof(ifr));
15128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
15138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ifr.ifr_metric = link_mtu;
15148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ipfd, SIOCSIFMTU, &ifr) < 0) {
15158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Couldn't set IP MTU (%s): %m", ifr.ifr_name);
15168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
15178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if defined(INET6) && defined(SOL2)
15198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fd = socket(AF_INET6, SOCK_DGRAM, 0);
15208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (fd < 0)
15218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Couldn't open IPv6 socket: %m");
15228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset(&lifr, 0, sizeof(lifr));
15248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name));
15258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lifr.lifr_mtu = link_mtu;
15268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(fd, SIOCSLIFMTU, &lifr) < 0) {
15278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(fd);
15288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Couldn't set IPv6 MTU (%s): %m", ifr.ifr_name);
15298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
15308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    close(fd);
15318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* defined(INET6) && defined(SOL2) */
15328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
15338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
15358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * tty_send_config - configure the transmit characteristics of
15368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * the ppp interface.
15378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
15388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
15398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecttty_send_config(mtu, asyncmap, pcomp, accomp)
15408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int mtu;
15418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t asyncmap;
15428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int pcomp, accomp;
15438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
15448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int cf[2];
15458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    link_mtu = mtu;
15478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (strioctl(pppfd, PPPIO_MTU, &mtu, sizeof(mtu), 0) < 0) {
15488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (hungup && errno == ENXIO) {
15498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ++error_count;
15508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return;
15518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
15528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Couldn't set MTU: %m");
15538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
15548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (fdmuxid >= 0) {
15558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (!sync_serial) {
15568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (strioctl(pppfd, PPPIO_XACCM, &asyncmap, sizeof(asyncmap), 0) < 0)
15578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		error("Couldn't set transmit ACCM: %m");
15588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
15598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	cf[0] = (pcomp? COMP_PROT: 0) + (accomp? COMP_AC: 0);
15608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	cf[1] = COMP_PROT | COMP_AC;
15618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (any_compressions() &&
15628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0)
15638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    error("Couldn't set prot/AC compression: %m");
15648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
15658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
15668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
15688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * tty_set_xaccm - set the extended transmit ACCM for the interface.
15698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
15708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
15718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecttty_set_xaccm(accm)
15728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ext_accm accm;
15738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
15748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (sync_serial)
15758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return;
15768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (fdmuxid >= 0
15788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	&& strioctl(pppfd, PPPIO_XACCM, accm, sizeof(ext_accm), 0) < 0) {
15798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (!hungup || errno != ENXIO)
15808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    warn("Couldn't set extended ACCM: %m");
15818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
15828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
15838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
15858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * tty_recv_config - configure the receive-side characteristics of
15868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * the ppp interface.
15878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
15888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
15898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecttty_recv_config(mru, asyncmap, pcomp, accomp)
15908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int mru;
15918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t asyncmap;
15928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int pcomp, accomp;
15938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
15948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int cf[2];
15958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    link_mru = mru;
15978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (strioctl(pppfd, PPPIO_MRU, &mru, sizeof(mru), 0) < 0) {
15988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (hungup && errno == ENXIO) {
15998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ++error_count;
16008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return;
16018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
16028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Couldn't set MRU: %m");
16038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
16048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (fdmuxid >= 0) {
16058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (!sync_serial) {
16068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (strioctl(pppfd, PPPIO_RACCM, &asyncmap, sizeof(asyncmap), 0) < 0)
16078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		error("Couldn't set receive ACCM: %m");
16088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
16098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	cf[0] = (pcomp? DECOMP_PROT: 0) + (accomp? DECOMP_AC: 0);
16108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	cf[1] = DECOMP_PROT | DECOMP_AC;
16118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (any_compressions() &&
16128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0)
16138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    error("Couldn't set prot/AC decompression: %m");
16148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
16158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
16168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
16178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
16188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ccp_test - ask kernel whether a given compression method
16198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * is acceptable for use.
16208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
16218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
16228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectccp_test(unit, opt_ptr, opt_len, for_transmit)
16238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit, opt_len, for_transmit;
16248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *opt_ptr;
16258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
16268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (strioctl(pppfd, (for_transmit? PPPIO_XCOMP: PPPIO_RCOMP),
16278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 opt_ptr, opt_len, 0) >= 0)
16288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 1;
16298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return (errno == ENOSR)? 0: -1;
16308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
16318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
16328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
16338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ccp_flags_set - inform kernel about the current state of CCP.
16348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
16358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
16368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectccp_flags_set(unit, isopen, isup)
16378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit, isopen, isup;
16388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
16398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int cf[2];
16408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
16418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    cf[0] = (isopen? CCP_ISOPEN: 0) + (isup? CCP_ISUP: 0);
16428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    cf[1] = CCP_ISOPEN | CCP_ISUP | CCP_ERROR | CCP_FATALERROR;
16438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) {
16448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (!hungup || errno != ENXIO)
16458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    error("Couldn't set kernel CCP state: %m");
16468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
16478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
16488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
16498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
16508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * get_idle_time - return how long the link has been idle.
16518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
16528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
16538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectget_idle_time(u, ip)
16548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int u;
16558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct ppp_idle *ip;
16568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
16578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return strioctl(pppfd, PPPIO_GIDLE, ip, 0, sizeof(struct ppp_idle)) >= 0;
16588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
16598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
16608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
16618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * get_ppp_stats - return statistics for the link.
16628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
16638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
16648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectget_ppp_stats(u, stats)
16658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int u;
16668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct pppd_stats *stats;
16678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
16688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct ppp_stats s;
16698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
16708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!sync_serial &&
16718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	strioctl(pppfd, PPPIO_GETSTAT, &s, 0, sizeof(s)) < 0) {
16728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Couldn't get link statistics: %m");
16738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
16748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
16758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    stats->bytes_in = s.p.ppp_ibytes;
16768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    stats->bytes_out = s.p.ppp_obytes;
16778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    stats->pkts_in = s.p.ppp_ipackets;
16788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    stats->pkts_out = s.p.ppp_opackets;
16798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
16808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
16818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
16828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if 0
16838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
16848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * set_filters - transfer the pass and active filters to the kernel.
16858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
16868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
16878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectset_filters(pass, active)
16888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct bpf_program *pass, *active;
16898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
16908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int ret = 1;
16918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
16928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (pass->bf_len > 0) {
16938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (strioctl(pppfd, PPPIO_PASSFILT, pass,
16948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		     sizeof(struct bpf_program), 0) < 0) {
16958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    error("Couldn't set pass-filter in kernel: %m");
16968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ret = 0;
16978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
16988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
16998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (active->bf_len > 0) {
17008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (strioctl(pppfd, PPPIO_ACTIVEFILT, active,
17018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		     sizeof(struct bpf_program), 0) < 0) {
17028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    error("Couldn't set active-filter in kernel: %m");
17038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ret = 0;
17048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
17058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
17068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return ret;
17078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
17088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
17098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
17118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ccp_fatal_error - returns 1 if decompression was disabled as a
17128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * result of an error detected after decompression of a packet,
17138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 0 otherwise.  This is necessary because of patent nonsense.
17148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
17158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
17168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectccp_fatal_error(unit)
17178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit;
17188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
17198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int cf[2];
17208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    cf[0] = cf[1] = 0;
17228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) {
17238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (errno != ENXIO && errno != EINVAL)
17248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    error("Couldn't get compression flags: %m");
17258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
17268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
17278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return cf[0] & CCP_FATALERROR;
17288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
17298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
17318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * sifvjcomp - config tcp header compression
17328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
17338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
17348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectsifvjcomp(u, vjcomp, xcidcomp, xmaxcid)
17358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int u, vjcomp, xcidcomp, xmaxcid;
17368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
17378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int cf[2];
17388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char maxcid[2];
17398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (vjcomp) {
17418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	maxcid[0] = xcidcomp;
17428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	maxcid[1] = 15;		/* XXX should be rmaxcid */
17438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (strioctl(pppfd, PPPIO_VJINIT, maxcid, sizeof(maxcid), 0) < 0) {
17448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    error("Couldn't initialize VJ compression: %m");
17458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
17468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
17478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    cf[0] = (vjcomp? COMP_VJC + DECOMP_VJC: 0)	/* XXX this is wrong */
17498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	+ (xcidcomp? COMP_VJCCID + DECOMP_VJCCID: 0);
17508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    cf[1] = COMP_VJC + DECOMP_VJC + COMP_VJCCID + DECOMP_VJCCID;
17518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) {
17528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (vjcomp)
17538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    error("Couldn't enable VJ compression: %m");
17548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
17558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
17578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
17588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
17608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * sifup - Config the interface up and enable IP packets to pass.
17618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
17628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
17638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectsifup(u)
17648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int u;
17658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
17668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct ifreq ifr;
17678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
17698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ipfd, SIOCGIFFLAGS, &ifr) < 0) {
17708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Couldn't mark interface up (get): %m");
17718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
17728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
17738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ifr.ifr_flags |= IFF_UP;
17748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ipfd, SIOCSIFFLAGS, &ifr) < 0) {
17758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Couldn't mark interface up (set): %m");
17768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
17778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
17788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if_is_up = 1;
17798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
17808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
17818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
17838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * sifdown - Config the interface down and disable IP.
17848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
17858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
17868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectsifdown(u)
17878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int u;
17888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
17898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct ifreq ifr;
17908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ipmuxid < 0)
17928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 1;
17938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
17948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ipfd, SIOCGIFFLAGS, &ifr) < 0) {
17958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Couldn't mark interface down (get): %m");
17968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
17978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
17988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ifr.ifr_flags &= ~IFF_UP;
17998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ipfd, SIOCSIFFLAGS, &ifr) < 0) {
18008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Couldn't mark interface down (set): %m");
18018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
18028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
18038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if_is_up = 0;
18048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
18058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
18068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
18088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * sifnpmode - Set the mode for handling packets for a given NP.
18098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
18108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
18118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectsifnpmode(u, proto, mode)
18128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int u;
18138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int proto;
18148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    enum NPmode mode;
18158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
18168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int npi[2];
18178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    npi[0] = proto;
18198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    npi[1] = (int) mode;
18208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (strioctl(pppfd, PPPIO_NPMODE, &npi, 2 * sizeof(int), 0) < 0) {
18218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("ioctl(set NP %d mode to %d): %m", proto, mode);
18228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
18238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
18248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
18258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
18268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if defined(SOL2) && defined(INET6)
18288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
18298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * sif6up - Config the IPv6 interface up and enable IPv6 packets to pass.
18308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
18318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
18328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectsif6up(u)
18338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int u;
18348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
18358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct lifreq lifr;
18368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int fd;
18378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fd = socket(AF_INET6, SOCK_DGRAM, 0);
18398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (fd < 0) {
18408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
18418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
18428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset(&lifr, 0, sizeof(lifr));
18448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name));
18458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(fd, SIOCGLIFFLAGS, &lifr) < 0) {
18468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(fd);
18478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
18488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
18498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lifr.lifr_flags |= IFF_UP;
18518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name));
18528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(fd, SIOCSLIFFLAGS, &lifr) < 0) {
18538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(fd);
18548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
18558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
18568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if6_is_up = 1;
18588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    close(fd);
18598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
18608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
18618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
18638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * sifdown - Config the IPv6 interface down and disable IPv6.
18648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
18658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
18668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectsif6down(u)
18678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int u;
18688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
18698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct lifreq lifr;
18708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int fd;
18718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fd = socket(AF_INET6, SOCK_DGRAM, 0);
18738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (fd < 0)
18748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
18758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset(&lifr, 0, sizeof(lifr));
18778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name));
18788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(fd, SIOCGLIFFLAGS, &lifr) < 0) {
18798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(fd);
18808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
18818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
18828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lifr.lifr_flags &= ~IFF_UP;
18848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name));
18858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(fd, SIOCGLIFFLAGS, &lifr) < 0) {
18868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(fd);
18878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
18888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
18898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if6_is_up = 0;
18918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    close(fd);
18928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
18938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
18948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
18968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * sif6addr - Config the interface with an IPv6 link-local address
18978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
18988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
18998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectsif6addr(u, o, h)
19008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int u;
19018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    eui64_t o, h;
19028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
19038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct lifreq lifr;
19048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct sockaddr_storage laddr;
19058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&laddr;
19068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int fd;
19078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fd = socket(AF_INET6, SOCK_DGRAM, 0);
19098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (fd < 0)
19108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
19118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset(&lifr, 0, sizeof(lifr));
19138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name));
19148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
19168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Do this because /dev/ppp responds to DL_PHYS_ADDR_REQ with
19178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * zero values, hence the interface token came to be zero too,
19188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * and without this, in.ndpd will complain
19198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
19208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    IN6_LLTOKEN_FROM_EUI64(lifr, sin6, o);
19218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(fd, SIOCSLIFTOKEN, &lifr) < 0) {
19228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(fd);
19238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
19248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
19258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
19278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Set the interface address and destination address
19288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
19298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    IN6_LLADDR_FROM_EUI64(lifr, sin6, o);
19308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(fd, SIOCSLIFADDR, &lifr) < 0) {
19318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(fd);
19328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
19338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
19348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset(&lifr, 0, sizeof(lifr));
19368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name));
19378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    IN6_LLADDR_FROM_EUI64(lifr, sin6, h);
19388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(fd, SIOCSLIFDSTADDR, &lifr) < 0) {
19398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(fd);
19408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
19418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
19428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
19448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
19458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
19478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * cif6addr - Remove the IPv6 address from interface
19488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
19498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
19508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectcif6addr(u, o, h)
19518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int u;
19528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    eui64_t o, h;
19538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
19548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
19558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
19568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* defined(SOL2) && defined(INET6) */
19588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define INET_ADDR(x)	(((struct sockaddr_in *) &(x))->sin_addr.s_addr)
19618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
19638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * sifaddr - Config the interface IP addresses and netmask.
19648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
19658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
19668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectsifaddr(u, o, h, m)
19678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int u;
19688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t o, h, m;
19698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
19708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct ifreq ifr;
19718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int ret = 1;
19728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset(&ifr, 0, sizeof(ifr));
19748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
19758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ifr.ifr_addr.sa_family = AF_INET;
19768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    INET_ADDR(ifr.ifr_addr) = m;
19778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ipfd, SIOCSIFNETMASK, &ifr) < 0) {
19788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Couldn't set IP netmask: %m");
19798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ret = 0;
19808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
19818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ifr.ifr_addr.sa_family = AF_INET;
19828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    INET_ADDR(ifr.ifr_addr) = o;
19838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ipfd, SIOCSIFADDR, &ifr) < 0) {
19848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Couldn't set local IP address: %m");
19858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ret = 0;
19868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
19878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
19898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * On some systems, we have to explicitly set the point-to-point
19908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * flag bit before we can set a destination address.
19918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
19928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ipfd, SIOCGIFFLAGS, &ifr) >= 0
19938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	&& (ifr.ifr_flags & IFF_POINTOPOINT) == 0) {
19948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ifr.ifr_flags |= IFF_POINTOPOINT;
19958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (ioctl(ipfd, SIOCSIFFLAGS, &ifr) < 0) {
19968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    error("Couldn't mark interface pt-to-pt: %m");
19978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ret = 0;
19988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
19998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
20008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ifr.ifr_dstaddr.sa_family = AF_INET;
20018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    INET_ADDR(ifr.ifr_dstaddr) = h;
20028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ipfd, SIOCSIFDSTADDR, &ifr) < 0) {
20038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Couldn't set remote IP address: %m");
20048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ret = 0;
20058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
20068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
20078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    remote_addr = h;
20088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return ret;
20098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
20108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
20118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
20128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * cifaddr - Clear the interface IP addresses, and delete routes
20138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * through the interface if possible.
20148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
20158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
20168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectcifaddr(u, o, h)
20178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int u;
20188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t o, h;
20198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
20208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if defined(__USLC__)		/* was: #if 0 */
20218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    cifroute(unit, ouraddr, hisaddr);
20228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ipmuxid >= 0) {
20238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	notice("Removing ppp interface unit");
20248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (ioctl(ipfd, I_UNLINK, ipmuxid) < 0) {
20258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    error("Can't remove ppp interface unit: %m");
20268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return 0;
20278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
20288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ipmuxid = -1;
20298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
20308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
20318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    remote_addr = 0;
20328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
20338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
20348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
20358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
20368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * sifdefaultroute - assign a default route through the address given.
20378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
20388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
20398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectsifdefaultroute(u, l, g)
20408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int u;
20418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t l, g;
20428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
20438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct rtentry rt;
20448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
20458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if defined(__USLC__)
20468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    g = l;			/* use the local address as gateway */
20478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
20488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset(&rt, 0, sizeof(rt));
20498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rt.rt_dst.sa_family = AF_INET;
20508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    INET_ADDR(rt.rt_dst) = 0;
20518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rt.rt_gateway.sa_family = AF_INET;
20528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    INET_ADDR(rt.rt_gateway) = g;
20538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rt.rt_flags = RTF_GATEWAY;
20548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
20558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ipfd, SIOCADDRT, &rt) < 0) {
20568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Can't add default route: %m");
20578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
20588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
20598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
20608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    default_route_gateway = g;
20618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
20628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
20638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
20648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
20658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * cifdefaultroute - delete a default route through the address given.
20668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
20678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
20688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectcifdefaultroute(u, l, g)
20698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int u;
20708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t l, g;
20718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
20728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct rtentry rt;
20738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
20748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if defined(__USLC__)
20758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    g = l;			/* use the local address as gateway */
20768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
20778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset(&rt, 0, sizeof(rt));
20788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rt.rt_dst.sa_family = AF_INET;
20798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    INET_ADDR(rt.rt_dst) = 0;
20808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rt.rt_gateway.sa_family = AF_INET;
20818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    INET_ADDR(rt.rt_gateway) = g;
20828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rt.rt_flags = RTF_GATEWAY;
20838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
20848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ipfd, SIOCDELRT, &rt) < 0) {
20858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Can't delete default route: %m");
20868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
20878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
20888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
20898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    default_route_gateway = 0;
20908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
20918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
20928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
20938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
20948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * sifproxyarp - Make a proxy ARP entry for the peer.
20958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
20968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
20978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectsifproxyarp(unit, hisaddr)
20988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit;
20998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t hisaddr;
21008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
21018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct arpreq arpreq;
21028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
21038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset(&arpreq, 0, sizeof(arpreq));
21048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!get_ether_addr(hisaddr, &arpreq.arp_ha))
21058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
21068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
21078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    arpreq.arp_pa.sa_family = AF_INET;
21088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    INET_ADDR(arpreq.arp_pa) = hisaddr;
21098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    arpreq.arp_flags = ATF_PERM | ATF_PUBL;
21108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ipfd, SIOCSARP, (caddr_t) &arpreq) < 0) {
21118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Couldn't set proxy ARP entry: %m");
21128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
21138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
21148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
21158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    proxy_arp_addr = hisaddr;
21168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
21178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
21188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
21198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
21208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * cifproxyarp - Delete the proxy ARP entry for the peer.
21218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
21228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
21238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectcifproxyarp(unit, hisaddr)
21248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit;
21258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t hisaddr;
21268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
21278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct arpreq arpreq;
21288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
21298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset(&arpreq, 0, sizeof(arpreq));
21308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    arpreq.arp_pa.sa_family = AF_INET;
21318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    INET_ADDR(arpreq.arp_pa) = hisaddr;
21328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ipfd, SIOCDARP, (caddr_t)&arpreq) < 0) {
21338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Couldn't delete proxy ARP entry: %m");
21348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
21358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
21368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
21378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    proxy_arp_addr = 0;
21388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
21398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
21408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
21418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
21428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * get_ether_addr - get the hardware address of an interface on the
21438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * the same subnet as ipaddr.
21448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
21458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define MAX_IFS		32
21468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
21478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
21488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectget_ether_addr(ipaddr, hwaddr)
21498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t ipaddr;
21508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct sockaddr *hwaddr;
21518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
21528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct ifreq *ifr, *ifend, ifreq;
21538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int nif;
21548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct ifconf ifc;
21558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t ina, mask;
21568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
21578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
21588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Scan through the system's network interfaces.
21598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
21608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef SIOCGIFNUM
21618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ipfd, SIOCGIFNUM, &nif) < 0)
21628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
21638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	nif = MAX_IFS;
21648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ifc.ifc_len = nif * sizeof(struct ifreq);
21658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ifc.ifc_buf = (caddr_t) malloc(ifc.ifc_len);
21668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ifc.ifc_buf == 0)
21678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
21688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ipfd, SIOCGIFCONF, &ifc) < 0) {
21698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	warn("Couldn't get system interface list: %m");
21708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	free(ifc.ifc_buf);
21718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
21728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
21738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
21748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    for (ifr = ifc.ifc_req; ifr < ifend; ++ifr) {
21758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (ifr->ifr_addr.sa_family != AF_INET)
21768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    continue;
21778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/*
21788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * Check that the interface is up, and not point-to-point or loopback.
21798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 */
21808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
21818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (ioctl(ipfd, SIOCGIFFLAGS, &ifreq) < 0)
21828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    continue;
21838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if ((ifreq.ifr_flags &
21848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     (IFF_UP|IFF_BROADCAST|IFF_POINTOPOINT|IFF_LOOPBACK|IFF_NOARP))
21858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    != (IFF_UP|IFF_BROADCAST))
21868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    continue;
21878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/*
21888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * Get its netmask and check that it's on the right subnet.
21898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 */
21908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (ioctl(ipfd, SIOCGIFNETMASK, &ifreq) < 0)
21918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    continue;
21928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ina = INET_ADDR(ifr->ifr_addr);
21938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	mask = INET_ADDR(ifreq.ifr_addr);
21948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if ((ipaddr & mask) == (ina & mask))
21958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
21968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
21978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
21988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ifr >= ifend) {
21998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	warn("No suitable interface found for proxy ARP");
22008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	free(ifc.ifc_buf);
22018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
22028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
22038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    info("found interface %s for proxy ARP", ifr->ifr_name);
22058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!get_hw_addr(ifr->ifr_name, ina, hwaddr)) {
22068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Couldn't get hardware address for %s", ifr->ifr_name);
22078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	free(ifc.ifc_buf);
22088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
22098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
22108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    free(ifc.ifc_buf);
22128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
22138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
22148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
22168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * get_hw_addr_dlpi - obtain the hardware address using DLPI
22178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
22188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
22198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectget_hw_addr_dlpi(name, hwaddr)
22208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char *name;
22218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct sockaddr *hwaddr;
22228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
22238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char *p, *q;
22248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit, iffd, adrlen;
22258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    unsigned char *adrp;
22268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char ifdev[24];
22278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct {
22288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	union DL_primitives prim;
22298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	char space[64];
22308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } reply;
22318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
22338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * We have to open the device and ask it for its hardware address.
22348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * First split apart the device name and unit.
22358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
22368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    slprintf(ifdev, sizeof(ifdev), "/dev/%s", name);
22378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    for (q = ifdev + strlen(ifdev); --q >= ifdev; )
22388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (!isdigit(*q))
22398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
22408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    unit = atoi(q+1);
22418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    q[1] = 0;
22428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
22448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Open the device and do a DLPI attach and phys_addr_req.
22458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
22468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    iffd = open(ifdev, O_RDWR);
22478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (iffd < 0) {
22488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Can't open %s: %m", ifdev);
22498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
22508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
22518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (dlpi_attach(iffd, unit) < 0
22528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	|| dlpi_get_reply(iffd, &reply.prim, DL_OK_ACK, sizeof(reply)) < 0
22538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	|| dlpi_info_req(iffd) < 0
22548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	|| dlpi_get_reply(iffd, &reply.prim, DL_INFO_ACK, sizeof(reply)) < 0) {
22558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(iffd);
22568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
22578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
22588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    adrlen = reply.prim.info_ack.dl_addr_length;
22608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    adrp = (unsigned char *)&reply + reply.prim.info_ack.dl_addr_offset;
22618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if DL_CURRENT_VERSION >= 2
22638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (reply.prim.info_ack.dl_sap_length < 0)
22648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	adrlen += reply.prim.info_ack.dl_sap_length;
22658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    else
22668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	adrp += reply.prim.info_ack.dl_sap_length;
22678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
22688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    hwaddr->sa_family = AF_UNSPEC;
22708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memcpy(hwaddr->sa_data, adrp, adrlen);
22718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
22738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
22748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
22758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * get_hw_addr - obtain the hardware address for a named interface.
22768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
22778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
22788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectget_hw_addr(name, ina, hwaddr)
22798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char *name;
22808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t ina;
22818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct sockaddr *hwaddr;
22828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
22838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* New way - get the address by doing an arp request. */
22848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int s;
22858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct arpreq req;
22868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    s = socket(AF_INET, SOCK_DGRAM, 0);
22888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (s < 0)
22898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
22908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset(&req, 0, sizeof(req));
22918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    req.arp_pa.sa_family = AF_INET;
22928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    INET_ADDR(req.arp_pa) = ina;
22938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(s, SIOCGARP, &req) < 0) {
22948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Couldn't get ARP entry for %s: %m", ip_ntoa(ina));
22958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
22968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
22978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    *hwaddr = req.arp_ha;
22988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    hwaddr->sa_family = AF_UNSPEC;
22998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
23018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
23028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
23048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectdlpi_attach(fd, ppa)
23058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int fd, ppa;
23068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
23078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    dl_attach_req_t req;
23088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct strbuf buf;
23098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    req.dl_primitive = DL_ATTACH_REQ;
23118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    req.dl_ppa = ppa;
23128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    buf.len = sizeof(req);
23138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    buf.buf = (void *) &req;
23148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return putmsg(fd, &buf, NULL, RS_HIPRI);
23158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
23168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
23188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectdlpi_info_req(fd)
23198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int fd;
23208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
23218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    dl_info_req_t req;
23228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct strbuf buf;
23238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    req.dl_primitive = DL_INFO_REQ;
23258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    buf.len = sizeof(req);
23268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    buf.buf = (void *) &req;
23278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return putmsg(fd, &buf, NULL, RS_HIPRI);
23288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
23298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
23318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectdlpi_get_reply(fd, reply, expected_prim, maxlen)
23328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    union DL_primitives *reply;
23338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int fd, expected_prim, maxlen;
23348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
23358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct strbuf buf;
23368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int flags, n;
23378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct pollfd pfd;
23388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
23408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Use poll to wait for a message with a timeout.
23418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
23428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    pfd.fd = fd;
23438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    pfd.events = POLLIN | POLLPRI;
23448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    do {
23458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	n = poll(&pfd, 1, 1000);
23468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } while (n == -1 && errno == EINTR);
23478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (n <= 0)
23488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return -1;
23498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
23518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Get the reply.
23528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
23538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    buf.maxlen = maxlen;
23548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    buf.buf = (void *) reply;
23558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    flags = 0;
23568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (getmsg(fd, &buf, NULL, &flags) < 0)
23578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return -1;
23588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (buf.len < sizeof(ulong)) {
23608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (debug)
23618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    dbglog("dlpi response short (len=%d)\n", buf.len);
23628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return -1;
23638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
23648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (reply->dl_primitive == expected_prim)
23668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
23678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (debug) {
23698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (reply->dl_primitive == DL_ERROR_ACK) {
23708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    dbglog("dlpi error %d (unix errno %d) for prim %x\n",
23718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		   reply->error_ack.dl_errno, reply->error_ack.dl_unix_errno,
23728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		   reply->error_ack.dl_error_primitive);
23738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	} else {
23748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    dbglog("dlpi unexpected response prim %x\n",
23758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		   reply->dl_primitive);
23768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
23778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
23788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return -1;
23808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
23818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
23838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Return user specified netmask, modified by any mask we might determine
23848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * for address `addr' (in network byte order).
23858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Here we scan through the system's list of interfaces, looking for
23868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * any non-point-to-point interfaces which might appear to be on the same
23878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * network as `addr'.  If we find any, we OR in their netmask to the
23888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * user-specified netmask.
23898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
23908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectu_int32_t
23918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectGetMask(addr)
23928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t addr;
23938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
23948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t mask, nmask, ina;
23958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct ifreq *ifr, *ifend, ifreq;
23968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int nif;
23978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct ifconf ifc;
23988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    addr = ntohl(addr);
24008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (IN_CLASSA(addr))	/* determine network mask for address class */
24018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	nmask = IN_CLASSA_NET;
24028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    else if (IN_CLASSB(addr))
24038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	nmask = IN_CLASSB_NET;
24048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    else
24058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	nmask = IN_CLASSC_NET;
24068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* class D nets are disallowed by bad_ip_adrs */
24078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    mask = netmask | htonl(nmask);
24088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
24098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
24108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Scan through the system's network interfaces.
24118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
24128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef SIOCGIFNUM
24138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ipfd, SIOCGIFNUM, &nif) < 0)
24148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
24158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	nif = MAX_IFS;
24168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ifc.ifc_len = nif * sizeof(struct ifreq);
24178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ifc.ifc_buf = (caddr_t) malloc(ifc.ifc_len);
24188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ifc.ifc_buf == 0)
24198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return mask;
24208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ipfd, SIOCGIFCONF, &ifc) < 0) {
24218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	warn("Couldn't get system interface list: %m");
24228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	free(ifc.ifc_buf);
24238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return mask;
24248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
24258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
24268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    for (ifr = ifc.ifc_req; ifr < ifend; ++ifr) {
24278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/*
24288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * Check the interface's internet address.
24298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 */
24308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (ifr->ifr_addr.sa_family != AF_INET)
24318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    continue;
24328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ina = INET_ADDR(ifr->ifr_addr);
24338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if ((ntohl(ina) & nmask) != (addr & nmask))
24348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    continue;
24358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/*
24368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * Check that the interface is up, and not point-to-point or loopback.
24378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 */
24388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
24398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (ioctl(ipfd, SIOCGIFFLAGS, &ifreq) < 0)
24408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    continue;
24418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if ((ifreq.ifr_flags & (IFF_UP|IFF_POINTOPOINT|IFF_LOOPBACK))
24428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    != IFF_UP)
24438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    continue;
24448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/*
24458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * Get its netmask and OR it into our mask.
24468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 */
24478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (ioctl(ipfd, SIOCGIFNETMASK, &ifreq) < 0)
24488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    continue;
24498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	mask |= INET_ADDR(ifreq.ifr_addr);
24508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
24518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
24528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    free(ifc.ifc_buf);
24538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return mask;
24548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
24558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
24568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
24578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * logwtmp - write an accounting record to the /var/adm/wtmp file.
24588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
24598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
24608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlogwtmp(line, name, host)
24618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    const char *line, *name, *host;
24628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
24638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    static struct utmpx utmpx;
24648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
24658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (name[0] != 0) {
24668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* logging in */
24678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	strncpy(utmpx.ut_user, name, sizeof(utmpx.ut_user));
24688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	strncpy(utmpx.ut_id, ifname, sizeof(utmpx.ut_id));
24698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	strncpy(utmpx.ut_line, line, sizeof(utmpx.ut_line));
24708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	utmpx.ut_pid = getpid();
24718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	utmpx.ut_type = USER_PROCESS;
24728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } else {
24738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	utmpx.ut_type = DEAD_PROCESS;
24748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
24758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    gettimeofday(&utmpx.ut_tv, NULL);
24768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    updwtmpx("/var/adm/wtmpx", &utmpx);
24778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
24788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
24798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
24808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * get_host_seed - return the serial number of this machine.
24818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
24828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
24838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectget_host_seed()
24848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
24858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char buf[32];
24868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
24878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (sysinfo(SI_HW_SERIAL, buf, sizeof(buf)) < 0) {
24888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("sysinfo: %m");
24898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
24908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
24918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return (int) strtoul(buf, NULL, 16);
24928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
24938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
24948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
24958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstrioctl(fd, cmd, ptr, ilen, olen)
24968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int fd, cmd, ilen, olen;
24978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    void *ptr;
24988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
24998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct strioctl str;
25008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
25018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    str.ic_cmd = cmd;
25028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    str.ic_timout = 0;
25038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    str.ic_len = ilen;
25048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    str.ic_dp = ptr;
25058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(fd, I_STR, &str) == -1)
25068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return -1;
25078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (str.ic_len != olen)
25088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	dbglog("strioctl: expected %d bytes, got %d for cmd %x\n",
25098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	       olen, str.ic_len, cmd);
25108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 0;
25118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
25128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
25138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if 0
25148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
25158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lock - create a lock file for the named lock device
25168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
25178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
25188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define LOCK_PREFIX	"/var/spool/locks/LK."
25198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic char lock_file[40];	/* name of lock file created */
25208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
25218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
25228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlock(dev)
25238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char *dev;
25248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
25258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int n, fd, pid;
25268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct stat sbuf;
25278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char ascii_pid[12];
25288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
25298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (stat(dev, &sbuf) < 0) {
25308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Can't get device number for %s: %m", dev);
25318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return -1;
25328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
25338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if ((sbuf.st_mode & S_IFMT) != S_IFCHR) {
25348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Can't lock %s: not a character device", dev);
25358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return -1;
25368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
25378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    slprintf(lock_file, sizeof(lock_file), "%s%03d.%03d.%03d",
25388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     LOCK_PREFIX, major(sbuf.st_dev),
25398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     major(sbuf.st_rdev), minor(sbuf.st_rdev));
25408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
25418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) {
25428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (errno == EEXIST
25438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    && (fd = open(lock_file, O_RDONLY, 0)) >= 0) {
25448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /* Read the lock file to find out who has the device locked */
25458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    n = read(fd, ascii_pid, 11);
25468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (n <= 0) {
25478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		error("Can't read pid from lock file %s", lock_file);
25488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		close(fd);
25498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    } else {
25508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		ascii_pid[n] = 0;
25518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		pid = atoi(ascii_pid);
25528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (pid > 0 && kill(pid, 0) == -1 && errno == ESRCH) {
25538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    /* pid no longer exists - remove the lock file */
25548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    if (unlink(lock_file) == 0) {
25558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			close(fd);
25568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			notice("Removed stale lock on %s (pid %d)",
25578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			       dev, pid);
25588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			continue;
25598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    } else
25608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			warn("Couldn't remove stale lock on %s",
25618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			       dev);
25628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		} else
25638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    notice("Device %s is locked by pid %d",
25648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			   dev, pid);
25658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
25668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    close(fd);
25678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	} else
25688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    error("Can't create lock file %s: %m", lock_file);
25698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	lock_file[0] = 0;
25708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return -1;
25718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
25728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
25738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    slprintf(ascii_pid, sizeof(ascii_pid), "%10d\n", getpid());
25748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    write(fd, ascii_pid, 11);
25758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
25768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    close(fd);
25778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
25788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
25798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
25808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
25818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * unlock - remove our lockfile
25828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
25838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
25848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectunlock()
25858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
25868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (lock_file[0]) {
25878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	unlink(lock_file);
25888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	lock_file[0] = 0;
25898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
25908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
25918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
25928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
25938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
25948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * cifroute - delete a route through the addresses given.
25958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
25968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
25978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectcifroute(u, our, his)
25988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int u;
25998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t our, his;
26008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
26018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct rtentry rt;
26028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
26038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset(&rt, 0, sizeof(rt));
26048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rt.rt_dst.sa_family = AF_INET;
26058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    INET_ADDR(rt.rt_dst) = his;
26068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rt.rt_gateway.sa_family = AF_INET;
26078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    INET_ADDR(rt.rt_gateway) = our;
26088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rt.rt_flags = RTF_HOST;
26098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
26108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ipfd, SIOCDELRT, &rt) < 0) {
26118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Can't delete route: %m");
26128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
26138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
26148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
26158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
26168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
26178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
26188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
26198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * have_route_to - determine if the system has a route to the specified
26208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * IP address.  Returns 0 if not, 1 if so, -1 if we can't tell.
26218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * `addr' is in network byte order.
26228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * For demand mode to work properly, we have to ignore routes
26238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * through our own interface.
26248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
26258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifndef T_CURRENT		/* needed for Solaris 2.5 */
26268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define T_CURRENT	MI_T_CURRENT
26278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
26288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
26298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
26308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecthave_route_to(addr)
26318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t addr;
26328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
26338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef SOL2
26348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int fd, r, flags, i;
26358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct {
26368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	struct T_optmgmt_req req;
26378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	struct opthdr hdr;
26388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } req;
26398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    union {
26408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	struct T_optmgmt_ack ack;
26418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	unsigned char space[64];
26428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } ack;
26438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct opthdr *rh;
26448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct strbuf cbuf, dbuf;
26458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int nroutes;
26468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    mib2_ipRouteEntry_t routes[8];
26478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    mib2_ipRouteEntry_t *rp;
26488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
26498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fd = open(mux_dev_name, O_RDWR);
26508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (fd < 0) {
26518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	warn("have_route_to: couldn't open %s: %m", mux_dev_name);
26528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return -1;
26538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
26548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
26558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    req.req.PRIM_type = T_OPTMGMT_REQ;
26568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    req.req.OPT_offset = (char *) &req.hdr - (char *) &req;
26578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    req.req.OPT_length = sizeof(req.hdr);
26588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    req.req.MGMT_flags = T_CURRENT;
26598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
26608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    req.hdr.level = MIB2_IP;
26618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    req.hdr.name = 0;
26628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    req.hdr.len = 0;
26638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
26648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    cbuf.buf = (char *) &req;
26658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    cbuf.len = sizeof(req);
26668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
26678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (putmsg(fd, &cbuf, NULL, 0) == -1) {
26688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	warn("have_route_to: putmsg: %m");
26698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(fd);
26708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return -1;
26718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
26728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
26738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    for (;;) {
26748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	cbuf.buf = (char *) &ack;
26758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	cbuf.maxlen = sizeof(ack);
26768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	dbuf.buf = (char *) routes;
26778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	dbuf.maxlen = sizeof(routes);
26788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	flags = 0;
26798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	r = getmsg(fd, &cbuf, &dbuf, &flags);
26808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (r == -1) {
26818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    warn("have_route_to: getmsg: %m");
26828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    close(fd);
26838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return -1;
26848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
26858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
26868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cbuf.len < sizeof(struct T_optmgmt_ack)
26878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    || ack.ack.PRIM_type != T_OPTMGMT_ACK
26888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    || ack.ack.MGMT_flags != T_SUCCESS
26898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    || ack.ack.OPT_length < sizeof(struct opthdr)) {
26908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    dbglog("have_route_to: bad message len=%d prim=%d",
26918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		   cbuf.len, ack.ack.PRIM_type);
26928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    close(fd);
26938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return -1;
26948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
26958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
26968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	rh = (struct opthdr *) ((char *)&ack + ack.ack.OPT_offset);
26978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (rh->level == 0 && rh->name == 0)
26988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
26998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (rh->level != MIB2_IP || rh->name != MIB2_IP_21) {
27008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    while (r == MOREDATA)
27018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		r = getmsg(fd, NULL, &dbuf, &flags);
27028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    continue;
27038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
27048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
27058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	for (;;) {
27068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    nroutes = dbuf.len / sizeof(mib2_ipRouteEntry_t);
27078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    for (rp = routes, i = 0; i < nroutes; ++i, ++rp) {
27088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (rp->ipRouteMask != ~0) {
27098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    dbglog("have_route_to: dest=%x gw=%x mask=%x\n",
27108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			   rp->ipRouteDest, rp->ipRouteNextHop,
27118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			   rp->ipRouteMask);
27128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    if (((addr ^ rp->ipRouteDest) & rp->ipRouteMask) == 0
27138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			&& rp->ipRouteNextHop != remote_addr)
27148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			return 1;
27158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
27168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
27178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (r == 0)
27188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
27198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    r = getmsg(fd, NULL, &dbuf, &flags);
27208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
27218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
27228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    close(fd);
27238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 0;
27248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#else
27258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return -1;
27268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* SOL2 */
27278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
27288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
27298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
27308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * get_pty - get a pty master/slave pair and chown the slave side to
27318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * the uid given.  Assumes slave_name points to MAXPATHLEN bytes of space.
27328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
27338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
27348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectget_pty(master_fdp, slave_fdp, slave_name, uid)
27358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int *master_fdp;
27368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int *slave_fdp;
27378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char *slave_name;
27388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int uid;
27398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
27408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int mfd, sfd;
27418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char *pty_name;
27428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct termios tios;
27438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
27448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    mfd = open("/dev/ptmx", O_RDWR);
27458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (mfd < 0) {
27468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Couldn't open pty master: %m");
27478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
27488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
27498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
27508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    pty_name = ptsname(mfd);
27518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (pty_name == NULL) {
27528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Couldn't get name of pty slave");
27538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(mfd);
27548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
27558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
27568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (chown(pty_name, uid, -1) < 0)
27578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	warn("Couldn't change owner of pty slave: %m");
27588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (chmod(pty_name, S_IRUSR | S_IWUSR) < 0)
27598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	warn("Couldn't change permissions on pty slave: %m");
27608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (unlockpt(mfd) < 0)
27618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	warn("Couldn't unlock pty slave: %m");
27628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
27638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    sfd = open(pty_name, O_RDWR);
27648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (sfd < 0) {
27658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Couldn't open pty slave %s: %m", pty_name);
27668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(mfd);
27678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
27688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
27698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(sfd, I_PUSH, "ptem") < 0)
27708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	warn("Couldn't push ptem module on pty slave: %m");
27718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
27728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    dbglog("Using %s", pty_name);
27738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    strlcpy(slave_name, pty_name, MAXPATHLEN);
27748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    *master_fdp = mfd;
27758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    *slave_fdp = sfd;
27768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
27778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
27788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
2779