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
881286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley#define RCSID	"$Id: sys-solaris.c,v 1.16 2008/01/30 14:26:53 carlsonj 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;	\
1971286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	l.lifr_addrlen = 64;			\
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
12281286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley    if (stop_bits >= 2)
12291286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	tios.c_cflag |= CSTOPB;
12301286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley
12318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    tios.c_cflag |= CS8 | CREAD | HUPCL;
12328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (local || !modem)
12338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	tios.c_cflag |= CLOCAL;
12348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    tios.c_iflag = IGNBRK | IGNPAR;
12358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    tios.c_oflag = 0;
12368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    tios.c_lflag = 0;
12378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    tios.c_cc[VMIN] = 1;
12388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    tios.c_cc[VTIME] = 0;
12398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (crtscts == -2) {
12418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	tios.c_iflag |= IXON | IXOFF;
12428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	tios.c_cc[VSTOP] = 0x13;	/* DC3 = XOFF = ^S */
12438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	tios.c_cc[VSTART] = 0x11;	/* DC1 = XON  = ^Q */
12448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
12458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    speed = translate_speed(inspeed);
12478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (speed) {
12488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	cfsetospeed(&tios, speed);
12498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	cfsetispeed(&tios, speed);
12508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } else {
12518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	speed = cfgetospeed(&tios);
12528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/*
12538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * We can't proceed if the serial port speed is 0,
12548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * since that implies that the serial port is disabled.
12558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 */
12568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if ((speed == B0) && !sync_serial)
12578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    fatal("Baud rate for %s is 0; need explicit baud rate", devnam);
12588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
12598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!sync_serial && tcsetattr(fd, TCSAFLUSH, &tios) < 0)
12618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fatal("tcsetattr: %m");
12628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifndef CRTSCTS
12648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!sync_serial && termiox_ok && ioctl (fd, TCSETXF, &tiox) < 0){
12658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("TCSETXF: %m");
12668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
12678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
12688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    baud_rate = inspeed = baud_rate_of(speed);
12708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!sync_serial)
12718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	restore_term = 1;
12728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
12738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
12758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * restore_tty - restore the terminal to the saved settings.
12768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
12778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
12788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectrestore_tty(fd)
12798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int fd;
12808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
12818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (restore_term) {
12828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (!default_device) {
12838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /*
12848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * Turn off echoing, because otherwise we can get into
12858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * a loop with the tty and the modem echoing to each other.
12868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * We presume we are the sole user of this tty device, so
12878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     * when we close it, it will revert to its defaults anyway.
12888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     */
12898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    inittermios.c_lflag &= ~(ECHO | ECHONL);
12908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
12918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (!sync_serial && tcsetattr(fd, TCSAFLUSH, &inittermios) < 0)
12928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (!hungup && errno != ENXIO)
12938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		warn("tcsetattr: %m");
12948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifndef CRTSCTS
12958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (!sync_serial && ioctl (fd, TCSETXF, &inittermiox) < 0){
12968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (!hungup && errno != ENXIO)
12978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		error("TCSETXF: %m");
12988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
12998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
13008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (!sync_serial)
13018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ioctl(fd, TIOCSWINSZ, &wsinfo);
13028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	restore_term = 0;
13038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
13048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
13058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
13078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * setdtr - control the DTR line on the serial port.
13088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * This is called from die(), so it shouldn't call die().
13098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
13108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
13118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectsetdtr(fd, on)
13128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint fd, on;
13138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
13148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int modembits = TIOCM_DTR;
13158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ioctl(fd, (on? TIOCMBIS: TIOCMBIC), &modembits);
13178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
13188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
13208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * open_loopback - open the device we use for getting packets
13218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * in demand mode.  Under Solaris 2, we use our existing fd
13228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * to the ppp driver.
13238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
13248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
13258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectopen_ppp_loopback()
13268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
13278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return pppfd;
13288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
13298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
13318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * output - Output PPP packet.
13328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
13338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
13348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectoutput(unit, p, len)
13358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit;
13368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *p;
13378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int len;
13388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
13398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct strbuf data;
13408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int retries;
13418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct pollfd pfd;
13428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    dump_packet("sent", p, len);
13448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (snoop_send_hook) snoop_send_hook(p, len);
13458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    data.len = len;
13478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    data.buf = (caddr_t) p;
13488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    retries = 4;
13498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    while (putmsg(pppfd, NULL, &data, 0) < 0) {
13508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (--retries < 0 || (errno != EWOULDBLOCK && errno != EAGAIN)) {
13518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (errno != ENXIO)
13528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		error("Couldn't send packet: %m");
13538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
13548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
13558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	pfd.fd = pppfd;
13568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	pfd.events = POLLOUT;
13578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	poll(&pfd, 1, 250);	/* wait for up to 0.25 seconds */
13588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
13598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
13608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
13638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * wait_input - wait until there is data available,
13648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * for the length of time specified by *timo (indefinite
13658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * if timo is NULL).
13668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
13678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
13688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectwait_input(timo)
13698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct timeval *timo;
13708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
13718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int t;
13728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    t = timo == NULL? -1: timo->tv_sec * 1000 + timo->tv_usec / 1000;
13748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (poll(pollfds, n_pollfds, t) < 0 && errno != EINTR)
13758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fatal("poll: %m");
13768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
13778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
13798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * add_fd - add an fd to the set that wait_input waits for.
13808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
13818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid add_fd(fd)
13828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int fd;
13838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
13848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int n;
13858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    for (n = 0; n < n_pollfds; ++n)
13878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (pollfds[n].fd == fd)
13888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return;
13898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (n_pollfds < MAX_POLLFDS) {
13908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	pollfds[n_pollfds].fd = fd;
13918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	pollfds[n_pollfds].events = POLLIN | POLLPRI | POLLHUP;
13928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	++n_pollfds;
13938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } else
13948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Too many inputs!");
13958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
13968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
13988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * remove_fd - remove an fd from the set that wait_input waits for.
13998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
14008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid remove_fd(fd)
14018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int fd;
14028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
14038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int n;
14048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    for (n = 0; n < n_pollfds; ++n) {
14068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (pollfds[n].fd == fd) {
14078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    while (++n < n_pollfds)
14088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		pollfds[n-1] = pollfds[n];
14098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    --n_pollfds;
14108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
14118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
14128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
14138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
14148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if 0
14168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
14178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * wait_loop_output - wait until there is data available on the
14188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * loopback, for the length of time specified by *timo (indefinite
14198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * if timo is NULL).
14208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
14218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
14228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectwait_loop_output(timo)
14238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct timeval *timo;
14248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
14258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    wait_input(timo);
14268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
14278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
14298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * wait_time - wait for a given length of time or until a
14308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * signal is received.
14318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
14328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
14338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectwait_time(timo)
14348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct timeval *timo;
14358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
14368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int n;
14378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    n = select(0, NULL, NULL, NULL, timo);
14398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (n < 0 && errno != EINTR)
14408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	fatal("select: %m");
14418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
14428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
14438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
14468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * read_packet - get a PPP packet from the serial device.
14478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
14488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
14498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectread_packet(buf)
14508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *buf;
14518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
14528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct strbuf ctrl, data;
14538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int flags, len;
14548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    unsigned char ctrlbuf[sizeof(union DL_primitives) + 64];
14558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    for (;;) {
14578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	data.maxlen = PPP_MRU + PPP_HDRLEN;
14588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	data.buf = (caddr_t) buf;
14598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ctrl.maxlen = sizeof(ctrlbuf);
14608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ctrl.buf = (caddr_t) ctrlbuf;
14618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	flags = 0;
14628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	len = getmsg(pppfd, &ctrl, &data, &flags);
14638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (len < 0) {
14648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (errno == EAGAIN || errno == EINTR)
14658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		return -1;
14668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    fatal("Error reading packet: %m");
14678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
14688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (ctrl.len <= 0)
14708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return data.len;
14718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/*
14738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * Got a M_PROTO or M_PCPROTO message.  Interpret it
14748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * as a DLPI primitive??
14758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 */
14768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (debug)
14778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    dbglog("got dlpi prim 0x%x, len=%d",
14788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		   ((union DL_primitives *)ctrlbuf)->dl_primitive, ctrl.len);
14798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
14818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
14828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
14848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * get_loop_output - get outgoing packets from the ppp device,
14858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * and detect when we want to bring the real link up.
14868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Return value is 1 if we need to bring up the link, 0 otherwise.
14878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
14888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
14898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectget_loop_output()
14908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
14918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int len;
14928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int rv = 0;
14938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
14948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    while ((len = read_packet(inpacket_buf)) > 0) {
14958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (loop_frame(inpacket_buf, len))
14968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    rv = 1;
14978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
14988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return rv;
14998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
15008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
15028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * netif_set_mtu - set the MTU on the PPP network interface.
15038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
15048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
15058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectnetif_set_mtu(unit, mtu)
15068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit, mtu;
15078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
15088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct ifreq ifr;
15098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if defined(INET6) && defined(SOL2)
15108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct lifreq lifr;
15118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int	fd;
15128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* defined(INET6) && defined(SOL2) */
15138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset(&ifr, 0, sizeof(ifr));
15158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
15168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ifr.ifr_metric = link_mtu;
15178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ipfd, SIOCSIFMTU, &ifr) < 0) {
15188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Couldn't set IP MTU (%s): %m", ifr.ifr_name);
15198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
15208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if defined(INET6) && defined(SOL2)
15228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fd = socket(AF_INET6, SOCK_DGRAM, 0);
15238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (fd < 0)
15248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Couldn't open IPv6 socket: %m");
15258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset(&lifr, 0, sizeof(lifr));
15278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name));
15288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lifr.lifr_mtu = link_mtu;
15298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(fd, SIOCSLIFMTU, &lifr) < 0) {
15308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(fd);
15318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Couldn't set IPv6 MTU (%s): %m", ifr.ifr_name);
15328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
15338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    close(fd);
15348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* defined(INET6) && defined(SOL2) */
15358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
15368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
15388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * tty_send_config - configure the transmit characteristics of
15398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * the ppp interface.
15408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
15418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
15428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecttty_send_config(mtu, asyncmap, pcomp, accomp)
15438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int mtu;
15448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t asyncmap;
15458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int pcomp, accomp;
15468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
15478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int cf[2];
15488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    link_mtu = mtu;
15508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (strioctl(pppfd, PPPIO_MTU, &mtu, sizeof(mtu), 0) < 0) {
15518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (hungup && errno == ENXIO) {
15528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ++error_count;
15538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return;
15548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
15558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Couldn't set MTU: %m");
15568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
15578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (fdmuxid >= 0) {
15588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (!sync_serial) {
15598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (strioctl(pppfd, PPPIO_XACCM, &asyncmap, sizeof(asyncmap), 0) < 0)
15608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		error("Couldn't set transmit ACCM: %m");
15618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
15628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	cf[0] = (pcomp? COMP_PROT: 0) + (accomp? COMP_AC: 0);
15638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	cf[1] = COMP_PROT | COMP_AC;
15648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (any_compressions() &&
15658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0)
15668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    error("Couldn't set prot/AC compression: %m");
15678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
15688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
15698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
15718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * tty_set_xaccm - set the extended transmit ACCM for the interface.
15728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
15738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
15748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecttty_set_xaccm(accm)
15758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ext_accm accm;
15768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
15778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (sync_serial)
15788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return;
15798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (fdmuxid >= 0
15818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	&& strioctl(pppfd, PPPIO_XACCM, accm, sizeof(ext_accm), 0) < 0) {
15828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (!hungup || errno != ENXIO)
15838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    warn("Couldn't set extended ACCM: %m");
15848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
15858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
15868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
15888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * tty_recv_config - configure the receive-side characteristics of
15898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * the ppp interface.
15908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
15918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
15928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecttty_recv_config(mru, asyncmap, pcomp, accomp)
15938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int mru;
15948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t asyncmap;
15958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int pcomp, accomp;
15968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
15978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int cf[2];
15988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
15998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    link_mru = mru;
16008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (strioctl(pppfd, PPPIO_MRU, &mru, sizeof(mru), 0) < 0) {
16018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (hungup && errno == ENXIO) {
16028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ++error_count;
16038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return;
16048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
16058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Couldn't set MRU: %m");
16068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
16078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (fdmuxid >= 0) {
16088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (!sync_serial) {
16098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (strioctl(pppfd, PPPIO_RACCM, &asyncmap, sizeof(asyncmap), 0) < 0)
16108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		error("Couldn't set receive ACCM: %m");
16118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
16128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	cf[0] = (pcomp? DECOMP_PROT: 0) + (accomp? DECOMP_AC: 0);
16138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	cf[1] = DECOMP_PROT | DECOMP_AC;
16148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (any_compressions() &&
16158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0)
16168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    error("Couldn't set prot/AC decompression: %m");
16178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
16188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
16198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
16208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
16218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ccp_test - ask kernel whether a given compression method
16228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * is acceptable for use.
16238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
16248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
16258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectccp_test(unit, opt_ptr, opt_len, for_transmit)
16268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit, opt_len, for_transmit;
16278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char *opt_ptr;
16288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
16298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (strioctl(pppfd, (for_transmit? PPPIO_XCOMP: PPPIO_RCOMP),
16308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 opt_ptr, opt_len, 0) >= 0)
16318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 1;
16328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return (errno == ENOSR)? 0: -1;
16338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
16348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
16358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
16368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ccp_flags_set - inform kernel about the current state of CCP.
16378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
16388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
16398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectccp_flags_set(unit, isopen, isup)
16408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit, isopen, isup;
16418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
16428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int cf[2];
16438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
16448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    cf[0] = (isopen? CCP_ISOPEN: 0) + (isup? CCP_ISUP: 0);
16458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    cf[1] = CCP_ISOPEN | CCP_ISUP | CCP_ERROR | CCP_FATALERROR;
16468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) {
16478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (!hungup || errno != ENXIO)
16488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    error("Couldn't set kernel CCP state: %m");
16498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
16508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
16518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
16528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
16538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * get_idle_time - return how long the link has been idle.
16548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
16558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
16568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectget_idle_time(u, ip)
16578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int u;
16588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct ppp_idle *ip;
16598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
16608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return strioctl(pppfd, PPPIO_GIDLE, ip, 0, sizeof(struct ppp_idle)) >= 0;
16618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
16628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
16638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
16648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * get_ppp_stats - return statistics for the link.
16658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
16668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
16678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectget_ppp_stats(u, stats)
16688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int u;
16698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct pppd_stats *stats;
16708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
16718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct ppp_stats s;
16728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
16738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!sync_serial &&
16748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	strioctl(pppfd, PPPIO_GETSTAT, &s, 0, sizeof(s)) < 0) {
16758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Couldn't get link statistics: %m");
16768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
16778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
16788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    stats->bytes_in = s.p.ppp_ibytes;
16798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    stats->bytes_out = s.p.ppp_obytes;
16808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    stats->pkts_in = s.p.ppp_ipackets;
16818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    stats->pkts_out = s.p.ppp_opackets;
16828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
16838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
16848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
16858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if 0
16868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
16878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * set_filters - transfer the pass and active filters to the kernel.
16888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
16898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
16908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectset_filters(pass, active)
16918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct bpf_program *pass, *active;
16928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
16938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int ret = 1;
16948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
16958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (pass->bf_len > 0) {
16968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (strioctl(pppfd, PPPIO_PASSFILT, pass,
16978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		     sizeof(struct bpf_program), 0) < 0) {
16988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    error("Couldn't set pass-filter in kernel: %m");
16998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ret = 0;
17008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
17018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
17028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (active->bf_len > 0) {
17038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (strioctl(pppfd, PPPIO_ACTIVEFILT, active,
17048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		     sizeof(struct bpf_program), 0) < 0) {
17058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    error("Couldn't set active-filter in kernel: %m");
17068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ret = 0;
17078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
17088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
17098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return ret;
17108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
17118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
17128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
17148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * ccp_fatal_error - returns 1 if decompression was disabled as a
17158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * result of an error detected after decompression of a packet,
17168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * 0 otherwise.  This is necessary because of patent nonsense.
17178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
17188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
17198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectccp_fatal_error(unit)
17208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit;
17218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
17228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int cf[2];
17238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    cf[0] = cf[1] = 0;
17258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) {
17268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (errno != ENXIO && errno != EINVAL)
17278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    error("Couldn't get compression flags: %m");
17288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
17298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
17308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return cf[0] & CCP_FATALERROR;
17318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
17328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
17348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * sifvjcomp - config tcp header compression
17358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
17368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
17378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectsifvjcomp(u, vjcomp, xcidcomp, xmaxcid)
17388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int u, vjcomp, xcidcomp, xmaxcid;
17398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
17408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int cf[2];
17418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char maxcid[2];
17428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (vjcomp) {
17448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	maxcid[0] = xcidcomp;
17458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	maxcid[1] = 15;		/* XXX should be rmaxcid */
17468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (strioctl(pppfd, PPPIO_VJINIT, maxcid, sizeof(maxcid), 0) < 0) {
17478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    error("Couldn't initialize VJ compression: %m");
17488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
17498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
17508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    cf[0] = (vjcomp? COMP_VJC + DECOMP_VJC: 0)	/* XXX this is wrong */
17528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	+ (xcidcomp? COMP_VJCCID + DECOMP_VJCCID: 0);
17538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    cf[1] = COMP_VJC + DECOMP_VJC + COMP_VJCCID + DECOMP_VJCCID;
17548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (strioctl(pppfd, PPPIO_CFLAGS, cf, sizeof(cf), sizeof(int)) < 0) {
17558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (vjcomp)
17568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    error("Couldn't enable VJ compression: %m");
17578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
17588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
17608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
17618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
17638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * sifup - Config the interface up and enable IP packets to pass.
17648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
17658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
17668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectsifup(u)
17678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int u;
17688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
17698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct ifreq ifr;
17708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
17728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ipfd, SIOCGIFFLAGS, &ifr) < 0) {
17738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Couldn't mark interface up (get): %m");
17748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
17758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
17768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ifr.ifr_flags |= IFF_UP;
17778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ipfd, SIOCSIFFLAGS, &ifr) < 0) {
17788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Couldn't mark interface up (set): %m");
17798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
17808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
17818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if_is_up = 1;
17828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
17838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
17848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
17868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * sifdown - Config the interface down and disable IP.
17878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
17888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
17898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectsifdown(u)
17908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int u;
17918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
17928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct ifreq ifr;
17938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
17948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ipmuxid < 0)
17958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 1;
17968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
17978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ipfd, SIOCGIFFLAGS, &ifr) < 0) {
17988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Couldn't mark interface down (get): %m");
17998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
18008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
18018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ifr.ifr_flags &= ~IFF_UP;
18028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ipfd, SIOCSIFFLAGS, &ifr) < 0) {
18038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Couldn't mark interface down (set): %m");
18048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
18058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
18068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if_is_up = 0;
18078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
18088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
18098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
18118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * sifnpmode - Set the mode for handling packets for a given NP.
18128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
18138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
18148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectsifnpmode(u, proto, mode)
18158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int u;
18168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int proto;
18178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    enum NPmode mode;
18188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
18198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int npi[2];
18208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    npi[0] = proto;
18228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    npi[1] = (int) mode;
18238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (strioctl(pppfd, PPPIO_NPMODE, &npi, 2 * sizeof(int), 0) < 0) {
18248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("ioctl(set NP %d mode to %d): %m", proto, mode);
18258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
18268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
18278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
18288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
18298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if defined(SOL2) && defined(INET6)
18318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
18328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * sif6up - Config the IPv6 interface up and enable IPv6 packets to pass.
18338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
18348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
18358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectsif6up(u)
18368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int u;
18378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
18388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct lifreq lifr;
18398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int fd;
18408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fd = socket(AF_INET6, SOCK_DGRAM, 0);
18428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (fd < 0) {
18438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
18448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
18458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset(&lifr, 0, sizeof(lifr));
18478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name));
18488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(fd, SIOCGLIFFLAGS, &lifr) < 0) {
18498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(fd);
18508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
18518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
18528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lifr.lifr_flags |= IFF_UP;
18548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name));
18558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(fd, SIOCSLIFFLAGS, &lifr) < 0) {
18568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(fd);
18578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
18588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
18598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if6_is_up = 1;
18618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    close(fd);
18628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
18638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
18648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
18668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * sifdown - Config the IPv6 interface down and disable IPv6.
18678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
18688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
18698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectsif6down(u)
18708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int u;
18718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
18728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct lifreq lifr;
18738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int fd;
18748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fd = socket(AF_INET6, SOCK_DGRAM, 0);
18768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (fd < 0)
18778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
18788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset(&lifr, 0, sizeof(lifr));
18808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name));
18818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(fd, SIOCGLIFFLAGS, &lifr) < 0) {
18828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(fd);
18838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
18848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
18858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    lifr.lifr_flags &= ~IFF_UP;
18878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name));
18888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(fd, SIOCGLIFFLAGS, &lifr) < 0) {
18898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(fd);
18908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
18918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
18928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if6_is_up = 0;
18948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    close(fd);
18958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
18968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
18978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
18988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
18998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * sif6addr - Config the interface with an IPv6 link-local address
19008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
19018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
19028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectsif6addr(u, o, h)
19038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int u;
19048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    eui64_t o, h;
19058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
19068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct lifreq lifr;
19078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct sockaddr_storage laddr;
19088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&laddr;
19098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int fd;
19108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fd = socket(AF_INET6, SOCK_DGRAM, 0);
19128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (fd < 0)
19138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
19148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset(&lifr, 0, sizeof(lifr));
19168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name));
19178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
19198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Do this because /dev/ppp responds to DL_PHYS_ADDR_REQ with
19208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * zero values, hence the interface token came to be zero too,
19218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * and without this, in.ndpd will complain
19228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
19238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    IN6_LLTOKEN_FROM_EUI64(lifr, sin6, o);
19248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(fd, SIOCSLIFTOKEN, &lifr) < 0) {
19258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(fd);
19268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
19278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
19288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
19308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Set the interface address and destination address
19318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
19328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    IN6_LLADDR_FROM_EUI64(lifr, sin6, o);
19338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(fd, SIOCSLIFADDR, &lifr) < 0) {
19348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(fd);
19358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
19368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
19378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset(&lifr, 0, sizeof(lifr));
19398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name));
19408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    IN6_LLADDR_FROM_EUI64(lifr, sin6, h);
19418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(fd, SIOCSLIFDSTADDR, &lifr) < 0) {
19428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(fd);
19438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
19448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
19458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
19478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
19488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
19508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * cif6addr - Remove the IPv6 address from interface
19518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
19528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
19538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectcif6addr(u, o, h)
19548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int u;
19558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    eui64_t o, h;
19568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
19578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
19588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
19598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* defined(SOL2) && defined(INET6) */
19618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define INET_ADDR(x)	(((struct sockaddr_in *) &(x))->sin_addr.s_addr)
19648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
19668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * sifaddr - Config the interface IP addresses and netmask.
19678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
19688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
19698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectsifaddr(u, o, h, m)
19708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int u;
19718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t o, h, m;
19728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
19738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct ifreq ifr;
19748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int ret = 1;
19758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset(&ifr, 0, sizeof(ifr));
19778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
19788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ifr.ifr_addr.sa_family = AF_INET;
19798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    INET_ADDR(ifr.ifr_addr) = m;
19808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ipfd, SIOCSIFNETMASK, &ifr) < 0) {
19818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Couldn't set IP netmask: %m");
19828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ret = 0;
19838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
19848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ifr.ifr_addr.sa_family = AF_INET;
19858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    INET_ADDR(ifr.ifr_addr) = o;
19868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ipfd, SIOCSIFADDR, &ifr) < 0) {
19878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Couldn't set local IP address: %m");
19888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ret = 0;
19898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
19908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
19918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
19928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * On some systems, we have to explicitly set the point-to-point
19938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * flag bit before we can set a destination address.
19948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
19958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ipfd, SIOCGIFFLAGS, &ifr) >= 0
19968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	&& (ifr.ifr_flags & IFF_POINTOPOINT) == 0) {
19978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ifr.ifr_flags |= IFF_POINTOPOINT;
19988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (ioctl(ipfd, SIOCSIFFLAGS, &ifr) < 0) {
19998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    error("Couldn't mark interface pt-to-pt: %m");
20008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    ret = 0;
20018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
20028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
20038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ifr.ifr_dstaddr.sa_family = AF_INET;
20048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    INET_ADDR(ifr.ifr_dstaddr) = h;
20058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ipfd, SIOCSIFDSTADDR, &ifr) < 0) {
20068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Couldn't set remote IP address: %m");
20078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ret = 0;
20088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
20098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
20108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    remote_addr = h;
20118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return ret;
20128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
20138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
20148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
20158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * cifaddr - Clear the interface IP addresses, and delete routes
20168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * through the interface if possible.
20178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
20188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
20198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectcifaddr(u, o, h)
20208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int u;
20218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t o, h;
20228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
20238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if defined(__USLC__)		/* was: #if 0 */
20248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    cifroute(unit, ouraddr, hisaddr);
20258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ipmuxid >= 0) {
20268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	notice("Removing ppp interface unit");
20278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (ioctl(ipfd, I_UNLINK, ipmuxid) < 0) {
20288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    error("Can't remove ppp interface unit: %m");
20298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return 0;
20308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
20318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ipmuxid = -1;
20328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
20338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
20348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    remote_addr = 0;
20358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
20368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
20378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
20388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
20398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * sifdefaultroute - assign a default route through the address given.
20408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
20418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
20428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectsifdefaultroute(u, l, g)
20438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int u;
20448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t l, g;
20458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
20468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct rtentry rt;
20478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
20488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if defined(__USLC__)
20498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    g = l;			/* use the local address as gateway */
20508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
20518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset(&rt, 0, sizeof(rt));
20528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rt.rt_dst.sa_family = AF_INET;
20538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    INET_ADDR(rt.rt_dst) = 0;
20548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rt.rt_gateway.sa_family = AF_INET;
20558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    INET_ADDR(rt.rt_gateway) = g;
20568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rt.rt_flags = RTF_GATEWAY;
20578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
20588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ipfd, SIOCADDRT, &rt) < 0) {
20598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Can't add default route: %m");
20608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
20618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
20628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
20638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    default_route_gateway = g;
20648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
20658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
20668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
20678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
20688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * cifdefaultroute - delete a default route through the address given.
20698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
20708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
20718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectcifdefaultroute(u, l, g)
20728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int u;
20738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t l, g;
20748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
20758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct rtentry rt;
20768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
20778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if defined(__USLC__)
20788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    g = l;			/* use the local address as gateway */
20798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
20808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset(&rt, 0, sizeof(rt));
20818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rt.rt_dst.sa_family = AF_INET;
20828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    INET_ADDR(rt.rt_dst) = 0;
20838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rt.rt_gateway.sa_family = AF_INET;
20848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    INET_ADDR(rt.rt_gateway) = g;
20858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rt.rt_flags = RTF_GATEWAY;
20868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
20878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ipfd, SIOCDELRT, &rt) < 0) {
20888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Can't delete default route: %m");
20898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
20908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
20918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
20928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    default_route_gateway = 0;
20938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
20948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
20958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
20968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
20978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * sifproxyarp - Make a proxy ARP entry for the peer.
20988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
20998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
21008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectsifproxyarp(unit, hisaddr)
21018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit;
21028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t hisaddr;
21038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
21048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct arpreq arpreq;
21058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
21068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset(&arpreq, 0, sizeof(arpreq));
21078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!get_ether_addr(hisaddr, &arpreq.arp_ha))
21088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
21098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
21108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    arpreq.arp_pa.sa_family = AF_INET;
21118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    INET_ADDR(arpreq.arp_pa) = hisaddr;
21128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    arpreq.arp_flags = ATF_PERM | ATF_PUBL;
21138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ipfd, SIOCSARP, (caddr_t) &arpreq) < 0) {
21148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Couldn't set proxy ARP entry: %m");
21158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
21168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
21178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
21188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    proxy_arp_addr = hisaddr;
21198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
21208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
21218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
21228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
21238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * cifproxyarp - Delete the proxy ARP entry for the peer.
21248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
21258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
21268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectcifproxyarp(unit, hisaddr)
21278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit;
21288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t hisaddr;
21298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
21308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct arpreq arpreq;
21318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
21328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset(&arpreq, 0, sizeof(arpreq));
21338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    arpreq.arp_pa.sa_family = AF_INET;
21348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    INET_ADDR(arpreq.arp_pa) = hisaddr;
21358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ipfd, SIOCDARP, (caddr_t)&arpreq) < 0) {
21368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Couldn't delete proxy ARP entry: %m");
21378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
21388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
21398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
21408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    proxy_arp_addr = 0;
21418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
21428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
21438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
21448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
21458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * get_ether_addr - get the hardware address of an interface on the
21468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * the same subnet as ipaddr.
21478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
21488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define MAX_IFS		32
21498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
21508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
21518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectget_ether_addr(ipaddr, hwaddr)
21528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t ipaddr;
21538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct sockaddr *hwaddr;
21548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
21558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct ifreq *ifr, *ifend, ifreq;
21568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int nif;
21578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct ifconf ifc;
21588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t ina, mask;
21598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
21608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
21618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Scan through the system's network interfaces.
21628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
21638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef SIOCGIFNUM
21648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ipfd, SIOCGIFNUM, &nif) < 0)
21658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
21668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	nif = MAX_IFS;
21678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ifc.ifc_len = nif * sizeof(struct ifreq);
21688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ifc.ifc_buf = (caddr_t) malloc(ifc.ifc_len);
21698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ifc.ifc_buf == 0)
21708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
21718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ipfd, SIOCGIFCONF, &ifc) < 0) {
21728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	warn("Couldn't get system interface list: %m");
21738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	free(ifc.ifc_buf);
21748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
21758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
21768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
21778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    for (ifr = ifc.ifc_req; ifr < ifend; ++ifr) {
21788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (ifr->ifr_addr.sa_family != AF_INET)
21798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    continue;
21808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/*
21818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * Check that the interface is up, and not point-to-point or loopback.
21828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 */
21838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
21848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (ioctl(ipfd, SIOCGIFFLAGS, &ifreq) < 0)
21858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    continue;
21868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if ((ifreq.ifr_flags &
21878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     (IFF_UP|IFF_BROADCAST|IFF_POINTOPOINT|IFF_LOOPBACK|IFF_NOARP))
21888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    != (IFF_UP|IFF_BROADCAST))
21898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    continue;
21908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/*
21918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * Get its netmask and check that it's on the right subnet.
21928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 */
21938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (ioctl(ipfd, SIOCGIFNETMASK, &ifreq) < 0)
21948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    continue;
21958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ina = INET_ADDR(ifr->ifr_addr);
21968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	mask = INET_ADDR(ifreq.ifr_addr);
21978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if ((ipaddr & mask) == (ina & mask))
21988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
21998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
22008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ifr >= ifend) {
22028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	warn("No suitable interface found for proxy ARP");
22038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	free(ifc.ifc_buf);
22048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
22058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
22068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    info("found interface %s for proxy ARP", ifr->ifr_name);
22088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!get_hw_addr(ifr->ifr_name, ina, hwaddr)) {
22098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Couldn't get hardware address for %s", ifr->ifr_name);
22108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	free(ifc.ifc_buf);
22118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
22128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
22138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    free(ifc.ifc_buf);
22158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
22168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
22178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
22198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * get_hw_addr_dlpi - obtain the hardware address using DLPI
22208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
22218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
22228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectget_hw_addr_dlpi(name, hwaddr)
22238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char *name;
22248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct sockaddr *hwaddr;
22258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
22261286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley    char *q;
22278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int unit, iffd, adrlen;
22288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    unsigned char *adrp;
22298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char ifdev[24];
22308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct {
22318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	union DL_primitives prim;
22328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	char space[64];
22338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } reply;
22348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
22368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * We have to open the device and ask it for its hardware address.
22378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * First split apart the device name and unit.
22388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
22398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    slprintf(ifdev, sizeof(ifdev), "/dev/%s", name);
22408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    for (q = ifdev + strlen(ifdev); --q >= ifdev; )
22418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (!isdigit(*q))
22428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
22438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    unit = atoi(q+1);
22448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    q[1] = 0;
22458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
22478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Open the device and do a DLPI attach and phys_addr_req.
22488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
22498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    iffd = open(ifdev, O_RDWR);
22508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (iffd < 0) {
22518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Can't open %s: %m", ifdev);
22528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
22538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
22548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (dlpi_attach(iffd, unit) < 0
22558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	|| dlpi_get_reply(iffd, &reply.prim, DL_OK_ACK, sizeof(reply)) < 0
22568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	|| dlpi_info_req(iffd) < 0
22578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	|| dlpi_get_reply(iffd, &reply.prim, DL_INFO_ACK, sizeof(reply)) < 0) {
22588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(iffd);
22598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
22608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
22618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    adrlen = reply.prim.info_ack.dl_addr_length;
22638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    adrp = (unsigned char *)&reply + reply.prim.info_ack.dl_addr_offset;
22648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if DL_CURRENT_VERSION >= 2
22668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (reply.prim.info_ack.dl_sap_length < 0)
22678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	adrlen += reply.prim.info_ack.dl_sap_length;
22688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    else
22698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	adrp += reply.prim.info_ack.dl_sap_length;
22708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
22718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    hwaddr->sa_family = AF_UNSPEC;
22738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memcpy(hwaddr->sa_data, adrp, adrlen);
22748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
22768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
22778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
22788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * get_hw_addr - obtain the hardware address for a named interface.
22798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
22808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
22818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectget_hw_addr(name, ina, hwaddr)
22828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char *name;
22838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t ina;
22848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct sockaddr *hwaddr;
22858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
22868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* New way - get the address by doing an arp request. */
22878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int s;
22888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct arpreq req;
22898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
22908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    s = socket(AF_INET, SOCK_DGRAM, 0);
22918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (s < 0)
22928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
22938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset(&req, 0, sizeof(req));
22948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    req.arp_pa.sa_family = AF_INET;
22958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    INET_ADDR(req.arp_pa) = ina;
22968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(s, SIOCGARP, &req) < 0) {
22978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Couldn't get ARP entry for %s: %m", ip_ntoa(ina));
22988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
22998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
23008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    *hwaddr = req.arp_ha;
23018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    hwaddr->sa_family = AF_UNSPEC;
23028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
23048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
23058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
23078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectdlpi_attach(fd, ppa)
23088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int fd, ppa;
23098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
23108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    dl_attach_req_t req;
23118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct strbuf buf;
23128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    req.dl_primitive = DL_ATTACH_REQ;
23148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    req.dl_ppa = ppa;
23158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    buf.len = sizeof(req);
23168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    buf.buf = (void *) &req;
23178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return putmsg(fd, &buf, NULL, RS_HIPRI);
23188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
23198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
23218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectdlpi_info_req(fd)
23228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int fd;
23238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
23248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    dl_info_req_t req;
23258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct strbuf buf;
23268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    req.dl_primitive = DL_INFO_REQ;
23288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    buf.len = sizeof(req);
23298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    buf.buf = (void *) &req;
23308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return putmsg(fd, &buf, NULL, RS_HIPRI);
23318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
23328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
23348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectdlpi_get_reply(fd, reply, expected_prim, maxlen)
23358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    union DL_primitives *reply;
23368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int fd, expected_prim, maxlen;
23378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
23388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct strbuf buf;
23398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int flags, n;
23408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct pollfd pfd;
23418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
23438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Use poll to wait for a message with a timeout.
23448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
23458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    pfd.fd = fd;
23468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    pfd.events = POLLIN | POLLPRI;
23478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    do {
23488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	n = poll(&pfd, 1, 1000);
23498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } while (n == -1 && errno == EINTR);
23508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (n <= 0)
23518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return -1;
23528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
23548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Get the reply.
23558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
23568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    buf.maxlen = maxlen;
23578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    buf.buf = (void *) reply;
23588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    flags = 0;
23598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (getmsg(fd, &buf, NULL, &flags) < 0)
23608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return -1;
23618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (buf.len < sizeof(ulong)) {
23638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (debug)
23648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    dbglog("dlpi response short (len=%d)\n", buf.len);
23658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return -1;
23668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
23678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (reply->dl_primitive == expected_prim)
23698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
23708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (debug) {
23728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (reply->dl_primitive == DL_ERROR_ACK) {
23738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    dbglog("dlpi error %d (unix errno %d) for prim %x\n",
23748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		   reply->error_ack.dl_errno, reply->error_ack.dl_unix_errno,
23758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		   reply->error_ack.dl_error_primitive);
23768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	} else {
23778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    dbglog("dlpi unexpected response prim %x\n",
23788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		   reply->dl_primitive);
23798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
23808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
23818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return -1;
23838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
23848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
23858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
23868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Return user specified netmask, modified by any mask we might determine
23878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * for address `addr' (in network byte order).
23888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Here we scan through the system's list of interfaces, looking for
23898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * any non-point-to-point interfaces which might appear to be on the same
23908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * network as `addr'.  If we find any, we OR in their netmask to the
23918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * user-specified netmask.
23928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
23938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectu_int32_t
23948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectGetMask(addr)
23958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t addr;
23968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
23978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t mask, nmask, ina;
23988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct ifreq *ifr, *ifend, ifreq;
23998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int nif;
24008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct ifconf ifc;
24018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
24028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    addr = ntohl(addr);
24038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (IN_CLASSA(addr))	/* determine network mask for address class */
24048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	nmask = IN_CLASSA_NET;
24058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    else if (IN_CLASSB(addr))
24068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	nmask = IN_CLASSB_NET;
24078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    else
24088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	nmask = IN_CLASSC_NET;
24098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* class D nets are disallowed by bad_ip_adrs */
24108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    mask = netmask | htonl(nmask);
24118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
24128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
24138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Scan through the system's network interfaces.
24148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
24158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef SIOCGIFNUM
24168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ipfd, SIOCGIFNUM, &nif) < 0)
24178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
24188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	nif = MAX_IFS;
24198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ifc.ifc_len = nif * sizeof(struct ifreq);
24208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ifc.ifc_buf = (caddr_t) malloc(ifc.ifc_len);
24218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ifc.ifc_buf == 0)
24228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return mask;
24238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ipfd, SIOCGIFCONF, &ifc) < 0) {
24248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	warn("Couldn't get system interface list: %m");
24258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	free(ifc.ifc_buf);
24268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return mask;
24278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
24288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
24298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    for (ifr = ifc.ifc_req; ifr < ifend; ++ifr) {
24308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/*
24318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * Check the interface's internet address.
24328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 */
24338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (ifr->ifr_addr.sa_family != AF_INET)
24348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    continue;
24358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	ina = INET_ADDR(ifr->ifr_addr);
24368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if ((ntohl(ina) & nmask) != (addr & nmask))
24378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    continue;
24388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/*
24398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * Check that the interface is up, and not point-to-point or loopback.
24408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 */
24418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
24428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (ioctl(ipfd, SIOCGIFFLAGS, &ifreq) < 0)
24438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    continue;
24448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if ((ifreq.ifr_flags & (IFF_UP|IFF_POINTOPOINT|IFF_LOOPBACK))
24458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    != IFF_UP)
24468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    continue;
24478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/*
24488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 * Get its netmask and OR it into our mask.
24498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	 */
24508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (ioctl(ipfd, SIOCGIFNETMASK, &ifreq) < 0)
24518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    continue;
24528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	mask |= INET_ADDR(ifreq.ifr_addr);
24538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
24548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
24558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    free(ifc.ifc_buf);
24568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return mask;
24578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
24588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
24598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
24608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * logwtmp - write an accounting record to the /var/adm/wtmp file.
24618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
24628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
24638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlogwtmp(line, name, host)
24648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    const char *line, *name, *host;
24658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
24668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    static struct utmpx utmpx;
24678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
24688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (name[0] != 0) {
24698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* logging in */
24708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	strncpy(utmpx.ut_user, name, sizeof(utmpx.ut_user));
24718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	strncpy(utmpx.ut_line, line, sizeof(utmpx.ut_line));
24721286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	strncpy(utmpx.ut_host, host, sizeof(utmpx.ut_host));
24731286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	if (*host != '\0') {
24741286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	    utmpx.ut_syslen = strlen(host) + 1;
24751286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	    if (utmpx.ut_syslen > sizeof(utmpx.ut_host))
24761286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley		utmpx.ut_syslen = sizeof(utmpx.ut_host);
24771286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	}
24788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	utmpx.ut_pid = getpid();
24798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	utmpx.ut_type = USER_PROCESS;
24808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } else {
24818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	utmpx.ut_type = DEAD_PROCESS;
24828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
24838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    gettimeofday(&utmpx.ut_tv, NULL);
24848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    updwtmpx("/var/adm/wtmpx", &utmpx);
24858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
24868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
24878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
24888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * get_host_seed - return the serial number of this machine.
24898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
24908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
24918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectget_host_seed()
24928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
24938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char buf[32];
24948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
24958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (sysinfo(SI_HW_SERIAL, buf, sizeof(buf)) < 0) {
24968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("sysinfo: %m");
24978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
24988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
24998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return (int) strtoul(buf, NULL, 16);
25008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
25018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
25028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
25038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstrioctl(fd, cmd, ptr, ilen, olen)
25048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int fd, cmd, ilen, olen;
25058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    void *ptr;
25068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
25078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct strioctl str;
25088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
25098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    str.ic_cmd = cmd;
25108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    str.ic_timout = 0;
25118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    str.ic_len = ilen;
25128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    str.ic_dp = ptr;
25138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(fd, I_STR, &str) == -1)
25148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return -1;
25158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (str.ic_len != olen)
25168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	dbglog("strioctl: expected %d bytes, got %d for cmd %x\n",
25178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	       olen, str.ic_len, cmd);
25188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 0;
25198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
25208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
25218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if 0
25228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
25238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * lock - create a lock file for the named lock device
25248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
25258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
25268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define LOCK_PREFIX	"/var/spool/locks/LK."
25278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic char lock_file[40];	/* name of lock file created */
25288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
25298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
25308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlock(dev)
25318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char *dev;
25328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
25338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int n, fd, pid;
25348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct stat sbuf;
25358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char ascii_pid[12];
25368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
25378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (stat(dev, &sbuf) < 0) {
25388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Can't get device number for %s: %m", dev);
25398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return -1;
25408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
25418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if ((sbuf.st_mode & S_IFMT) != S_IFCHR) {
25428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Can't lock %s: not a character device", dev);
25438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return -1;
25448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
25458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    slprintf(lock_file, sizeof(lock_file), "%s%03d.%03d.%03d",
25468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     LOCK_PREFIX, major(sbuf.st_dev),
25478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	     major(sbuf.st_rdev), minor(sbuf.st_rdev));
25488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
25498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) {
25508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (errno == EEXIST
25518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    && (fd = open(lock_file, O_RDONLY, 0)) >= 0) {
25528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    /* Read the lock file to find out who has the device locked */
25538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    n = read(fd, ascii_pid, 11);
25548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (n <= 0) {
25558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		error("Can't read pid from lock file %s", lock_file);
25568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		close(fd);
25578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    } else {
25588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		ascii_pid[n] = 0;
25598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		pid = atoi(ascii_pid);
25608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (pid > 0 && kill(pid, 0) == -1 && errno == ESRCH) {
25618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    /* pid no longer exists - remove the lock file */
25628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    if (unlink(lock_file) == 0) {
25638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			close(fd);
25648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			notice("Removed stale lock on %s (pid %d)",
25658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			       dev, pid);
25668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			continue;
25678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    } else
25688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			warn("Couldn't remove stale lock on %s",
25698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			       dev);
25708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		} else
25718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    notice("Device %s is locked by pid %d",
25728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			   dev, pid);
25738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
25748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    close(fd);
25758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	} else
25768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    error("Can't create lock file %s: %m", lock_file);
25778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	lock_file[0] = 0;
25788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return -1;
25798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
25808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
25818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    slprintf(ascii_pid, sizeof(ascii_pid), "%10d\n", getpid());
25828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    write(fd, ascii_pid, 11);
25838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
25848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    close(fd);
25858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
25868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
25878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
25888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
25898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * unlock - remove our lockfile
25908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
25918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
25928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectunlock()
25938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
25948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (lock_file[0]) {
25958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	unlink(lock_file);
25968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	lock_file[0] = 0;
25978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
25988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
25998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
26008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
26018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
26028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * cifroute - delete a route through the addresses given.
26038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
26048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
26058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectcifroute(u, our, his)
26068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int u;
26078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t our, his;
26088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
26098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct rtentry rt;
26108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
26118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset(&rt, 0, sizeof(rt));
26128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rt.rt_dst.sa_family = AF_INET;
26138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    INET_ADDR(rt.rt_dst) = his;
26148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rt.rt_gateway.sa_family = AF_INET;
26158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    INET_ADDR(rt.rt_gateway) = our;
26168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rt.rt_flags = RTF_HOST;
26178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
26188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(ipfd, SIOCDELRT, &rt) < 0) {
26198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Can't delete route: %m");
26208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
26218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
26228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
26238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
26248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
26258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
26268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
26278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * have_route_to - determine if the system has a route to the specified
26288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * IP address.  Returns 0 if not, 1 if so, -1 if we can't tell.
26298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * `addr' is in network byte order.
26308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * For demand mode to work properly, we have to ignore routes
26318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * through our own interface.
26328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
26338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifndef T_CURRENT		/* needed for Solaris 2.5 */
26348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define T_CURRENT	MI_T_CURRENT
26358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
26368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
26378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
26388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projecthave_route_to(addr)
26398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t addr;
26408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
26418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef SOL2
26428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int fd, r, flags, i;
26438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct {
26448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	struct T_optmgmt_req req;
26458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	struct opthdr hdr;
26468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } req;
26478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    union {
26488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	struct T_optmgmt_ack ack;
26498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	unsigned char space[64];
26508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } ack;
26518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct opthdr *rh;
26528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct strbuf cbuf, dbuf;
26538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int nroutes;
26548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    mib2_ipRouteEntry_t routes[8];
26558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    mib2_ipRouteEntry_t *rp;
26568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
26578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    fd = open(mux_dev_name, O_RDWR);
26588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (fd < 0) {
26598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	warn("have_route_to: couldn't open %s: %m", mux_dev_name);
26608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return -1;
26618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
26628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
26638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    req.req.PRIM_type = T_OPTMGMT_REQ;
26648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    req.req.OPT_offset = (char *) &req.hdr - (char *) &req;
26658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    req.req.OPT_length = sizeof(req.hdr);
26668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    req.req.MGMT_flags = T_CURRENT;
26678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
26688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    req.hdr.level = MIB2_IP;
26698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    req.hdr.name = 0;
26708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    req.hdr.len = 0;
26718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
26728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    cbuf.buf = (char *) &req;
26738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    cbuf.len = sizeof(req);
26748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
26758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (putmsg(fd, &cbuf, NULL, 0) == -1) {
26768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	warn("have_route_to: putmsg: %m");
26778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(fd);
26788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return -1;
26798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
26808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
26818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    for (;;) {
26828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	cbuf.buf = (char *) &ack;
26838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	cbuf.maxlen = sizeof(ack);
26848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	dbuf.buf = (char *) routes;
26858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	dbuf.maxlen = sizeof(routes);
26868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	flags = 0;
26878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	r = getmsg(fd, &cbuf, &dbuf, &flags);
26888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (r == -1) {
26898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    warn("have_route_to: getmsg: %m");
26908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    close(fd);
26918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return -1;
26928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
26938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
26948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (cbuf.len < sizeof(struct T_optmgmt_ack)
26958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    || ack.ack.PRIM_type != T_OPTMGMT_ACK
26968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    || ack.ack.MGMT_flags != T_SUCCESS
26978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    || ack.ack.OPT_length < sizeof(struct opthdr)) {
26988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    dbglog("have_route_to: bad message len=%d prim=%d",
26998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		   cbuf.len, ack.ack.PRIM_type);
27008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    close(fd);
27018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return -1;
27028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
27038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
27048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	rh = (struct opthdr *) ((char *)&ack + ack.ack.OPT_offset);
27058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (rh->level == 0 && rh->name == 0)
27068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
27078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (rh->level != MIB2_IP || rh->name != MIB2_IP_21) {
27088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    while (r == MOREDATA)
27098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		r = getmsg(fd, NULL, &dbuf, &flags);
27108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    continue;
27118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
27128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
27138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	for (;;) {
27148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    nroutes = dbuf.len / sizeof(mib2_ipRouteEntry_t);
27158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    for (rp = routes, i = 0; i < nroutes; ++i, ++rp) {
27168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (rp->ipRouteMask != ~0) {
27178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    dbglog("have_route_to: dest=%x gw=%x mask=%x\n",
27188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			   rp->ipRouteDest, rp->ipRouteNextHop,
27198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			   rp->ipRouteMask);
27208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    if (((addr ^ rp->ipRouteDest) & rp->ipRouteMask) == 0
27218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			&& rp->ipRouteNextHop != remote_addr)
27228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			return 1;
27238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
27248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
27258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (r == 0)
27268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
27278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    r = getmsg(fd, NULL, &dbuf, &flags);
27288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
27298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
27308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    close(fd);
27318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 0;
27328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#else
27338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return -1;
27348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* SOL2 */
27358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
27368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
27378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*
27388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * get_pty - get a pty master/slave pair and chown the slave side to
27398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * the uid given.  Assumes slave_name points to MAXPATHLEN bytes of space.
27408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */
27418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint
27428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectget_pty(master_fdp, slave_fdp, slave_name, uid)
27438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int *master_fdp;
27448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int *slave_fdp;
27458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char *slave_name;
27468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int uid;
27478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
27488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int mfd, sfd;
27498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char *pty_name;
27508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
27518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    mfd = open("/dev/ptmx", O_RDWR);
27528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (mfd < 0) {
27538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Couldn't open pty master: %m");
27548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
27558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
27568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
27578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    pty_name = ptsname(mfd);
27588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (pty_name == NULL) {
27598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Couldn't get name of pty slave");
27608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(mfd);
27618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
27628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
27638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (chown(pty_name, uid, -1) < 0)
27648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	warn("Couldn't change owner of pty slave: %m");
27658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (chmod(pty_name, S_IRUSR | S_IWUSR) < 0)
27668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	warn("Couldn't change permissions on pty slave: %m");
27678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (unlockpt(mfd) < 0)
27688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	warn("Couldn't unlock pty slave: %m");
27698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
27708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    sfd = open(pty_name, O_RDWR);
27718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (sfd < 0) {
27728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("Couldn't open pty slave %s: %m", pty_name);
27738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	close(mfd);
27748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
27758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
27768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (ioctl(sfd, I_PUSH, "ptem") < 0)
27778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	warn("Couldn't push ptem module on pty slave: %m");
27788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
27798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    dbglog("Using %s", pty_name);
27808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    strlcpy(slave_name, pty_name, MAXPATHLEN);
27818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    *master_fdp = mfd;
27828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    *slave_fdp = sfd;
27838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
27848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
27858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
2786