18ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*********************************************************************** 28ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* 38ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* if.c 48ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* 58ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* Implementation of user-space PPPoE redirector for Linux. 68ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* 78ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* Functions for opening a raw socket and reading/writing raw Ethernet frames. 88ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* 98ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* Copyright (C) 2000 by Roaring Penguin Software Inc. 108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* 118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* This program may be distributed according to the terms of the GNU 128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* General Public License, version 2 or (at your option) any later version. 138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* 148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project***********************************************************************/ 158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic char const RCSID[] = 178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project"$Id: if.c,v 1.1 2001/12/14 02:55:20 mostrows Exp $"; 188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "pppoe.h" 208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef HAVE_UNISTD_H 228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <unistd.h> 238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif 248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef HAVE_NETPACKET_PACKET_H 268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <netpacket/packet.h> 278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#elif defined(HAVE_LINUX_IF_PACKET_H) 288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <linux/if_packet.h> 298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif 308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef HAVE_NET_ETHERNET_H 328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <net/ethernet.h> 338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif 348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef HAVE_ASM_TYPES_H 368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <asm/types.h> 378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif 388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef HAVE_SYS_IOCTL_H 408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/ioctl.h> 418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif 428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef HAVE_SYSLOG_H 448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <syslog.h> 458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif 468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <errno.h> 488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <stdlib.h> 498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <string.h> 508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef HAVE_NET_IF_ARP_H 528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <net/if_arp.h> 538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif 548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef USE_DLPI 568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <limits.h> 588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <fcntl.h> 598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <stdlib.h> 608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/types.h> 618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/time.h> 628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/stream.h> 638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/stropts.h> 648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/dlpi.h> 658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/bufmod.h> 668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <stdio.h> 678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <signal.h> 688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <stropts.h> 698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* function declarations */ 718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid dlpromisconreq( int fd, u_long level); 738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid dlinforeq(int fd); 748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid dlunitdatareq(int fd, u_char *addrp, int addrlen, u_long minpri, u_long maxpri, u_char *datap, int datalen); 758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid dlinfoack(int fd, char *bufp); 768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid dlbindreq(int fd, u_long sap, u_long max_conind, u_long service_mode, u_long conn_mgmt, u_long xidtest); 778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid dlattachreq(int fd, u_long ppa); 788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid dlokack(int fd, char *bufp); 798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid dlbindack(int fd, char *bufp); 808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint strioctl(int fd, int cmd, int timout, int len, char *dp); 818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid strgetmsg(int fd, struct strbuf *ctlp, struct strbuf *datap, int *flagsp, char *caller); 828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid sigalrm(int sig); 838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid expecting(int prim, union DL_primitives *dlp); 848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectchar *dlprim(u_long prim); 858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* #define DL_DEBUG */ 878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int dl_abssaplen; 898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int dl_saplen; 908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int dl_addrlen; 918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif 938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef USE_BPF 958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <net/bpf.h> 968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <fcntl.h> 978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectunsigned char *bpfBuffer; /* Packet filter buffer */ 998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint bpfLength = 0; /* Packet filter buffer length */ 1008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint bpfSize = 0; /* Number of unread bytes in buffer */ 1018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint bpfOffset = 0; /* Current offset in bpfBuffer */ 1028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif 1038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* Initialize frame types to RFC 2516 values. Some broken peers apparently 1058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project use different frame types... sigh... */ 1068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectUINT16_t Eth_PPPOE_Discovery = ETH_PPPOE_DISCOVERY; 1088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectUINT16_t Eth_PPPOE_Session = ETH_PPPOE_SESSION; 1098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/********************************************************************** 1118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%FUNCTION: etherType 1128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%ARGUMENTS: 1138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* packet -- a received PPPoE packet 1148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%RETURNS: 1158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* ethernet packet type (see /usr/include/net/ethertypes.h) 1168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%DESCRIPTION: 1178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* Checks the ethernet packet header to determine its type. 1188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* We should only be receveing DISCOVERY and SESSION types if the BPF 1198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* is set up correctly. Logs an error if an unexpected type is received. 1208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* Note that the ethernet type names come from "pppoe.h" and the packet 1218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* packet structure names use the LINUX dialect to maintain consistency 1228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* with the rest of this file. See the BSD section of "pppoe.h" for 1238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* translations of the data structure names. 1248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project***********************************************************************/ 1258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectUINT16_t 1268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectetherType(PPPoEPacket *packet) 1278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 1288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project UINT16_t type = (UINT16_t) ntohs(packet->ethHdr.h_proto); 1298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (type != Eth_PPPOE_Discovery && type != Eth_PPPOE_Session) { 1308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project syslog(LOG_ERR, "Invalid ether type 0x%x", type); 1318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 1328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return type; 1338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 1348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef USE_BPF 1368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/********************************************************************** 1378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%FUNCTION: getHWaddr 1388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%ARGUMENTS: 1398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* ifname -- name of interface 1408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* hwaddr -- buffer for ehthernet address 1418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%RETURNS: 1428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* Nothing 1438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%DESCRIPTION: 1448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* Locates the Ethernet hardware address for an interface. 1458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project***********************************************************************/ 1468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid 1478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectgetHWaddr(int sock, char const *ifname, unsigned char *hwaddr) 1488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 1498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char inbuf[8192]; 1508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project const struct sockaddr_dl *sdl; 1518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct ifconf ifc; 1528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct ifreq ifreq, *ifr; 1538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int i; 1548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int found = 0; 1558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ifc.ifc_len = sizeof(inbuf); 1578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ifc.ifc_buf = inbuf; 1588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) { 1598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fatalSys("SIOCGIFCONF"); 1608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 1618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ifr = ifc.ifc_req; 1628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ifreq.ifr_name[0] = '\0'; 1638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project for (i = 0; i < ifc.ifc_len; ) { 1648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ifr = (struct ifreq *)((caddr_t)ifc.ifc_req + i); 1658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project i += sizeof(ifr->ifr_name) + 1668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (ifr->ifr_addr.sa_len > sizeof(struct sockaddr) 1678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ? ifr->ifr_addr.sa_len 1688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project : sizeof(struct sockaddr)); 1698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (ifr->ifr_addr.sa_family == AF_LINK) { 1708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sdl = (const struct sockaddr_dl *) &ifr->ifr_addr; 1718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((sdl->sdl_type == IFT_ETHER) && 1728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (sdl->sdl_alen == ETH_ALEN) && 1738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project !strncmp(ifname, ifr->ifr_name, sizeof(ifr->ifr_name))) { 1748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (found) { 1758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char buffer[256]; 1768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sprintf(buffer, "interface %.16s has more than one ethernet address", ifname); 1778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project rp_fatal(buffer); 1788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } else { 1798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project found = 1; 1808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memcpy(hwaddr, LLADDR(sdl), ETH_ALEN); 1818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 1828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 1838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 1848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 1858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (!found) { 1868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char buffer[256]; 1878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sprintf(buffer, "interface %.16s has no ethernet address", ifname); 1888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project rp_fatal(buffer); 1898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 1908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 1918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/********************************************************************** 1938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%FUNCTION: initFilter 1948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%ARGUMENTS: 1958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* fd -- file descriptor of BSD device 1968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* type -- Ethernet frame type (0 for watch mode) 1978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* hwaddr -- buffer with ehthernet address 1988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%RETURNS: 1998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* Nothing 2008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%DESCRIPTION: 2018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* Initializes the packet filter rules. 2028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project***********************************************************************/ 2038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid 2048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectinitFilter(int fd, UINT16_t type, unsigned char *hwaddr) 2058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 2068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Packet Filter Instructions: 2078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Note that the ethernet type names come from "pppoe.h" and are 2088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * used here to maintain consistency with the rest of this file. */ 2098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project static struct bpf_insn bpfRun[] = { /* run PPPoE */ 2108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12), /* ethernet type */ 2118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ETH_PPPOE_SESSION, 5, 0), 2128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ETH_PPPOE_DISCOVERY, 0, 9), 2138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 0), /* first word of dest. addr */ 2148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define PPPOE_BCAST_CMPW 4 /* offset of word compare */ 2158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0, 0, 2), 2168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 4), /* next 1/2 word of dest. */ 2178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define PPPOE_BCAST_CMPH 6 /* offset of 1/2 word compare */ 2188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0, 4, 0), 2198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 0), /* first word of dest. addr */ 2208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define PPPOE_FILTER_CMPW 8 /* offset of word compare */ 2218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0, 0, 3), 2228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 4), /* next 1/2 word of dest. */ 2238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define PPPOE_FILTER_CMPH 10 /* offset of 1/rd compare */ 2248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0, 0, 1), 2258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project BPF_STMT(BPF_RET+BPF_K, (u_int) -1), /* keep packet */ 2268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project BPF_STMT(BPF_RET+BPF_K, 0), /* drop packet */ 2278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project }; 2288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Fix the potentially varying parts */ 2308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project bpfRun[1].code = (u_short) BPF_JMP+BPF_JEQ+BPF_K; 2318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project bpfRun[1].jt = 5; 2328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project bpfRun[1].jf = 0; 2338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project bpfRun[1].k = Eth_PPPOE_Session; 2348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project bpfRun[2].code = (u_short) BPF_JMP+BPF_JEQ+BPF_K; 2368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project bpfRun[2].jt = 0; 2378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project bpfRun[2].jf = 9; 2388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project bpfRun[2].k = Eth_PPPOE_Discovery; 2398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { 2418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct bpf_insn bpfInsn[sizeof(bpfRun) / sizeof(bpfRun[0])]; 2428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct bpf_program bpfProgram; 2438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memcpy(bpfInsn, bpfRun, sizeof(bpfRun)); 2448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project bpfInsn[PPPOE_BCAST_CMPW].k = ((0xff << 24) | (0xff << 16) | 2458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (0xff << 8) | 0xff); 2468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project bpfInsn[PPPOE_BCAST_CMPH].k = ((0xff << 8) | 0xff); 2478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project bpfInsn[PPPOE_FILTER_CMPW].k = ((hwaddr[0] << 24) | (hwaddr[1] << 16) | 2488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (hwaddr[2] << 8) | hwaddr[3]); 2498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project bpfInsn[PPPOE_FILTER_CMPH].k = ((hwaddr[4] << 8) | hwaddr[5]); 2508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project bpfProgram.bf_len = (sizeof(bpfInsn) / sizeof(bpfInsn[0])); 2518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project bpfProgram.bf_insns = &bpfInsn[0]; 2528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Apply the filter */ 2548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (ioctl(fd, BIOCSETF, &bpfProgram) < 0) { 2558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fatalSys("ioctl(BIOCSETF)"); 2568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 2578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 2588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 2598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/********************************************************************** 2618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%FUNCTION: openInterface 2628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%ARGUMENTS: 2638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* ifname -- name of interface 2648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* type -- Ethernet frame type (0 for any frame type) 2658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* hwaddr -- if non-NULL, set to the hardware address 2668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%RETURNS: 2678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* A file descriptor for talking with the Ethernet card. Exits on error. 2688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* Note that the Linux version of this routine returns a socket instead. 2698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%DESCRIPTION: 2708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* Opens a BPF on an interface for all PPPoE traffic (discovery and 2718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* session). If 'type' is 0, uses promiscuous mode to watch any PPPoE 2728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* traffic on this network. 2738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project***********************************************************************/ 2748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint 2758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectopenInterface(char const *ifname, UINT16_t type, unsigned char *hwaddr) 2768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 2778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project static int fd = -1; 2788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char bpfName[32]; 2798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project u_int optval; 2808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct bpf_version bpf_ver; 2818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct ifreq ifr; 2828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int sock; 2838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int i; 2848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* BSD only opens one socket for both Discovery and Session packets */ 2868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (fd >= 0) { 2878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return fd; 2888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 2898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 2908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Find a free BPF device */ 2918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project for (i = 0; i < 256; i++) { 2928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sprintf(bpfName, "/dev/bpf%d", i); 2938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (((fd = open(bpfName, O_RDWR, 0)) >= 0) || 2948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (errno != EBUSY)) { 2958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project break; 2968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 2978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 2988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (fd < 0) { 2998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project switch (errno) { 3008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project case EACCES: /* permission denied */ 3018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { 3028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char buffer[256]; 3038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sprintf(buffer, "Cannot open %.32s -- pppoe must be run as root.", bpfName); 3048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project rp_fatal(buffer); 3058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project break; 3078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project case EBUSY: 3088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project case ENOENT: /* no such file */ 3098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (i == 0) { 3108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project rp_fatal("No /dev/bpf* devices (check your kernel configuration for BPF support)"); 3118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } else { 3128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project rp_fatal("All /dev/bpf* devices are in use"); 3138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project break; 3158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fatalSys(bpfName); 3178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((sock = socket(AF_LOCAL, SOCK_DGRAM, 0)) < 0) { 3208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fatalSys("socket"); 3218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Check that the interface is up */ 3248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 3258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) { 3268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fatalSys("ioctl(SIOCGIFFLAGS)"); 3278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((ifr.ifr_flags & IFF_UP) == 0) { 3298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char buffer[256]; 3308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sprintf(buffer, "Interface %.16s is not up\n", ifname); 3318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project rp_fatal(buffer); 3328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Fill in hardware address and initialize the packet filter rules */ 3358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (hwaddr == NULL) { 3368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project rp_fatal("openInterface: no hwaddr arg."); 3378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project getHWaddr(sock, ifname, hwaddr); 3398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project initFilter(fd, type, hwaddr); 3408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Sanity check on MTU -- apparently does not work on OpenBSD */ 3428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if !defined(__OpenBSD__) 3438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 3448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (ioctl(sock, SIOCGIFMTU, &ifr) < 0) { 3458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fatalSys("ioctl(SIOCGIFMTU)"); 3468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (ifr.ifr_mtu < ETH_DATA_LEN) { 3488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char buffer[256]; 3498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sprintf(buffer, "Interface %.16s has MTU of %d -- should be %d. You may have serious connection problems.", 3508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ifname, ifr.ifr_mtu, ETH_DATA_LEN); 3518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project printErr(buffer); 3528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif 3548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* done with the socket */ 3568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (close(sock) < 0) { 3578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fatalSys("close"); 3588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Check the BPF version number */ 3618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (ioctl(fd, BIOCVERSION, &bpf_ver) < 0) { 3628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fatalSys("ioctl(BIOCVERSION)"); 3638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((bpf_ver.bv_major != BPF_MAJOR_VERSION) || 3658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (bpf_ver.bv_minor < BPF_MINOR_VERSION)) { 3668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char buffer[256]; 3678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sprintf(buffer, "Unsupported BPF version: %d.%d (kernel: %d.%d)", 3688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project BPF_MAJOR_VERSION, BPF_MINOR_VERSION, 3698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project bpf_ver.bv_major, bpf_ver.bv_minor); 3708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project rp_fatal(buffer); 3718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* allocate a receive packet buffer */ 3748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (ioctl(fd, BIOCGBLEN, &bpfLength) < 0) { 3758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fatalSys("ioctl(BIOCGBLEN)"); 3768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (!(bpfBuffer = (unsigned char *) malloc(bpfLength))) { 3788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project rp_fatal("malloc"); 3798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* reads should return as soon as there is a packet available */ 3828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project optval = 1; 3838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (ioctl(fd, BIOCIMMEDIATE, &optval) < 0) { 3848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fatalSys("ioctl(BIOCIMMEDIATE)"); 3858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Bind the interface to the filter */ 3888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 3898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (ioctl(fd, BIOCSETIF, &ifr) < 0) { 3908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char buffer[256]; 3918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sprintf(buffer, "ioctl(BIOCSETIF) can't select interface %.16s", 3928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ifname); 3938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project rp_fatal(buffer); 3948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 3958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 3968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project syslog(LOG_INFO, "Interface=%.16s HWaddr=%02X:%02X:%02X:%02X:%02X:%02X Device=%.32s Buffer size=%d", 3978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ifname, 3988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project hwaddr[0], hwaddr[1], hwaddr[2], 3998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project hwaddr[3], hwaddr[4], hwaddr[5], 4008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project bpfName, bpfLength); 4018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return fd; 4028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 4038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* USE_BPF */ 4058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef USE_LINUX_PACKET 4078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/********************************************************************** 4088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%FUNCTION: openInterface 4098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%ARGUMENTS: 4108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* ifname -- name of interface 4118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* type -- Ethernet frame type 4128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* hwaddr -- if non-NULL, set to the hardware address 4138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%RETURNS: 4148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* A raw socket for talking to the Ethernet card. Exits on error. 4158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%DESCRIPTION: 4168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* Opens a raw Ethernet socket 4178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project***********************************************************************/ 4188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint 4198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectopenInterface(char const *ifname, UINT16_t type, unsigned char *hwaddr) 4208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 4218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int optval=1; 4228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int fd; 4238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct ifreq ifr; 4248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int domain, stype; 4258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef HAVE_STRUCT_SOCKADDR_LL 4278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct sockaddr_ll sa; 4288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#else 4298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct sockaddr sa; 4308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif 4318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memset(&sa, 0, sizeof(sa)); 4338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef HAVE_STRUCT_SOCKADDR_LL 4358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project domain = PF_PACKET; 4368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project stype = SOCK_RAW; 4378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#else 4388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project domain = PF_INET; 4398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project stype = SOCK_PACKET; 4408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif 4418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((fd = socket(domain, stype, htons(type))) < 0) { 4438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Give a more helpful message for the common error case */ 4448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (errno == EPERM) { 4458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project rp_fatal("Cannot create raw socket -- pppoe must be run as root."); 4468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 4478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fatalSys("socket"); 4488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 4498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &optval, sizeof(optval)) < 0) { 4518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fatalSys("setsockopt"); 4528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 4538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Fill in hardware address */ 4558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (hwaddr) { 4568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 4578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) { 4588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fatalSys("ioctl(SIOCGIFHWADDR)"); 4598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 4608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memcpy(hwaddr, ifr.ifr_hwaddr.sa_data, ETH_ALEN); 4618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef ARPHRD_ETHER 4628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) { 4638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char buffer[256]; 4648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sprintf(buffer, "Interface %.16s is not Ethernet", ifname); 4658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project rp_fatal(buffer); 4668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 4678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif 4688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (NOT_UNICAST(hwaddr)) { 4698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char buffer[256]; 4708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sprintf(buffer, 4718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project "Interface %.16s has broadcast/multicast MAC address??", 4728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ifname); 4738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project rp_fatal(buffer); 4748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 4758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 4768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Sanity check on MTU */ 4788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 4798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (ioctl(fd, SIOCGIFMTU, &ifr) < 0) { 4808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fatalSys("ioctl(SIOCGIFMTU)"); 4818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 4828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (ifr.ifr_mtu < ETH_DATA_LEN) { 4838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char buffer[256]; 4848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sprintf(buffer, "Interface %.16s has MTU of %d -- should be %d. You may have serious connection problems.", 4858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ifname, ifr.ifr_mtu, ETH_DATA_LEN); 4868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project printErr(buffer); 4878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 4888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef HAVE_STRUCT_SOCKADDR_LL 4908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Get interface index */ 4918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sa.sll_family = AF_PACKET; 4928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sa.sll_protocol = htons(type); 4938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 4948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 4958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) { 4968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fatalSys("ioctl(SIOCFIGINDEX): Could not get interface index"); 4978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 4988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sa.sll_ifindex = ifr.ifr_ifindex; 4998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 5008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#else 5018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project strcpy(sa.sa_data, ifname); 5028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif 5038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 5048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* We're only interested in packets on specified interface */ 5058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (bind(fd, (struct sockaddr *) &sa, sizeof(sa)) < 0) { 5068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fatalSys("bind"); 5078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 5088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 5098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return fd; 5108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 5118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 5128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* USE_LINUX */ 5138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 5148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*********************************************************************** 5158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%FUNCTION: sendPacket 5168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%ARGUMENTS: 5178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* sock -- socket to send to 5188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* pkt -- the packet to transmit 5198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* size -- size of packet (in bytes) 5208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%RETURNS: 5218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* 0 on success; -1 on failure 5228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%DESCRIPTION: 5238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* Transmits a packet 5248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project***********************************************************************/ 5258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint 5268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectsendPacket(PPPoEConnection *conn, int sock, PPPoEPacket *pkt, int size) 5278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 5288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#if defined(USE_BPF) 5298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (write(sock, pkt, size) < 0) { 5308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sysErr("write (sendPacket)"); 5318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return -1; 5328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 5338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#elif defined(HAVE_STRUCT_SOCKADDR_LL) 5348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (send(sock, pkt, size, 0) < 0) { 5358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sysErr("send (sendPacket)"); 5368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return -1; 5378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 5388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#else 5398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef USE_DLPI 5408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 5418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define ABS(x) ((x) < 0 ? -(x) : (x)) 5428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 5438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project u_char addr[MAXDLADDR]; 5448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project u_char phys[MAXDLADDR]; 5458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project u_char sap[MAXDLADDR]; 5468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project u_char xmitbuf[MAXDLBUF]; 5478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int data_size; 5488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 5498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project short tmp_sap; 5508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 5518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project tmp_sap = htons(pkt->ethHdr.h_proto); 5528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project data_size = size - sizeof(struct ethhdr); 5538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 5548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memcpy((char *)phys, (char *)pkt->ethHdr.h_dest, ETHERADDRL); 5558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memcpy((char *)sap, (char *)&tmp_sap, sizeof(ushort_t)); 5568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memcpy((char *)xmitbuf, (char *)pkt + sizeof(struct ethhdr), data_size); 5578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 5588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (dl_saplen > 0) { /* order is sap+phys */ 5598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (void) memcpy((char*)addr, (char*)&sap, dl_abssaplen); 5608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (void) memcpy((char*)addr+dl_abssaplen, (char*)phys, ETHERADDRL); 5618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } else { /* order is phys+sap */ 5628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (void) memcpy((char*)addr, (char*)phys, ETHERADDRL); 5638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (void) memcpy((char*)addr+ETHERADDRL, (char*)&sap, dl_abssaplen); 5648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 5658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 5668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef DL_DEBUG 5678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project printf("%02x:%02x:%02x:%02x:%02x:%02x %02x:%02x\n", 5688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project addr[0],addr[1],addr[2],addr[3],addr[4],addr[5], 5698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project addr[6],addr[7]); 5708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif 5718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 5728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project dlunitdatareq(sock, addr, dl_addrlen, 0, 0, xmitbuf, data_size); 5738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 5748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 5758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 5768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#else 5778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct sockaddr sa; 5788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 5798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (!conn) { 5808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project rp_fatal("relay and server not supported on Linux 2.0 kernels"); 5818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 5828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project strcpy(sa.sa_data, conn->ifName); 5838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (sendto(sock, pkt, size, 0, &sa, sizeof(sa)) < 0) { 5848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sysErr("sendto (sendPacket)"); 5858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return -1; 5868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 5878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif 5888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif 5898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return 0; 5908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 5918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 5928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef USE_BPF 5938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*********************************************************************** 5948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%FUNCTION: clearPacketHeader 5958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%ARGUMENTS: 5968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* pkt -- packet that needs its head clearing 5978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%RETURNS: 5988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* nothing 5998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%DESCRIPTION: 6008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* Clears a PPPoE packet header after a truncated packet has been 6018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* received. Insures that the packet will fail any integrity tests 6028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* and will be discarded by upper level routines. Also resets the 6038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* bpfSize and bpfOffset variables to force a new read on the next 6048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* call to receivePacket(). 6058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project***********************************************************************/ 6068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid 6078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectclearPacketHeader(PPPoEPacket *pkt) 6088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 6098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project bpfSize = bpfOffset = 0; 6108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memset(pkt, 0, HDR_SIZE); 6118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 6128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif 6138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 6148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/*********************************************************************** 6158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%FUNCTION: receivePacket 6168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%ARGUMENTS: 6178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* sock -- socket to read from 6188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* pkt -- place to store the received packet 6198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* size -- set to size of packet in bytes 6208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%RETURNS: 6218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* >= 0 if all OK; < 0 if error 6228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%DESCRIPTION: 6238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* Receives a packet 6248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project***********************************************************************/ 6258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint 6268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectreceivePacket(int sock, PPPoEPacket *pkt, int *size) 6278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 6288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef USE_BPF 6298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct bpf_hdr hdr; 6308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int seglen, copylen; 6318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 6328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (bpfSize <= 0) { 6338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project bpfOffset = 0; 6348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((bpfSize = read(sock, bpfBuffer, bpfLength)) < 0) { 6358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sysErr("read (receivePacket)"); 6368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return -1; 6378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 6388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 6398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (bpfSize < sizeof(hdr)) { 6408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project syslog(LOG_ERR, "Truncated bpf packet header: len=%d", bpfSize); 6418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project clearPacketHeader(pkt); /* resets bpfSize and bpfOffset */ 6428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return 0; 6438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 6448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memcpy(&hdr, bpfBuffer + bpfOffset, sizeof(hdr)); 6458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (hdr.bh_caplen != hdr.bh_datalen) { 6468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project syslog(LOG_ERR, "Truncated bpf packet: caplen=%d, datalen=%d", 6478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project hdr.bh_caplen, hdr.bh_datalen); 6488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project clearPacketHeader(pkt); /* resets bpfSize and bpfOffset */ 6498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return 0; 6508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 6518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project seglen = hdr.bh_hdrlen + hdr.bh_caplen; 6528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (seglen > bpfSize) { 6538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project syslog(LOG_ERR, "Truncated bpf packet: seglen=%d, bpfSize=%d", 6548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project seglen, bpfSize); 6558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project clearPacketHeader(pkt); /* resets bpfSize and bpfOffset */ 6568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return 0; 6578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 6588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project seglen = BPF_WORDALIGN(seglen); 6598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *size = copylen = ((hdr.bh_caplen < sizeof(PPPoEPacket)) ? 6608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project hdr.bh_caplen : sizeof(PPPoEPacket)); 6618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memcpy(pkt, bpfBuffer + bpfOffset + hdr.bh_hdrlen, copylen); 6628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (seglen >= bpfSize) { 6638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project bpfSize = bpfOffset = 0; 6648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } else { 6658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project bpfSize -= seglen; 6668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project bpfOffset += seglen; 6678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 6688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#else 6698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef USE_DLPI 6708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct strbuf data; 6718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int flags = 0; 6728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int retval; 6738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 6748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project data.buf = (char *) pkt; 6758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project data.maxlen = MAXDLBUF; 6768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project data.len = 0; 6778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 6788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((retval = getmsg(sock, NULL, &data, &flags)) < 0) { 6798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sysErr("read (receivePacket)"); 6808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return -1; 6818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 6828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 6838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *size = data.len; 6848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 6858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#else 6868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((*size = recv(sock, pkt, sizeof(PPPoEPacket), 0)) < 0) { 6878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sysErr("recv (receivePacket)"); 6888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return -1; 6898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 6908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif 6918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif 6928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return 0; 6938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 6948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 6958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef USE_DLPI 6968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/********************************************************************** 6978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%FUNCTION: openInterface 6988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%ARGUMENTS: 6998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* ifname -- name of interface 7008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* type -- Ethernet frame type 7018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* hwaddr -- if non-NULL, set to the hardware address 7028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%RETURNS: 7038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* A raw socket for talking to the Ethernet card. Exits on error. 7048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*%DESCRIPTION: 7058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* Opens a raw Ethernet socket 7068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project***********************************************************************/ 7078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint 7088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source ProjectopenInterface(char const *ifname, UINT16_t type, unsigned char *hwaddr) 7098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 7108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int fd; 7118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project long buf[MAXDLBUF]; 7128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 7138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project union DL_primitives *dlp; 7148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 7158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char base_dev[PATH_MAX]; 7168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int ppa; 7178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 7188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if(strlen(ifname) > PATH_MAX) { 7198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project rp_fatal("socket: string to long"); 7208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 7218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 7228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ppa = atoi(&ifname[strlen(ifname)-1]); 7238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project strncpy(base_dev, ifname, PATH_MAX); 7248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project base_dev[strlen(base_dev)-1] = '\0'; 7258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 7268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* rearranged order of DLPI code - delphys 20010803 */ 7278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project dlp = (union DL_primitives*) buf; 7288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 7298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (( fd = open(base_dev, O_RDWR)) < 0) { 7308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* Give a more helpful message for the common error case */ 7318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (errno == EPERM) { 7328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project rp_fatal("Cannot create raw socket -- pppoe must be run as root."); 7338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 7348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fatalSys("socket"); 7358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 7368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 7378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* rearranged order of DLPI code - delphys 20010803 */ 7388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project dlattachreq(fd, ppa); 7398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project dlokack(fd, (char *)buf); 7408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 7418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project dlbindreq(fd, type, 0, DL_CLDLS, 0, 0); 7428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project dlbindack(fd, (char *)buf); 7438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 7448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project dlinforeq(fd); 7458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project dlinfoack(fd, (char *)buf); 7468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 7478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project dl_abssaplen = ABS(dlp->info_ack.dl_sap_length); 7488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project dl_saplen = dlp->info_ack.dl_sap_length; 7498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (ETHERADDRL != (dlp->info_ack.dl_addr_length - dl_abssaplen)) 7508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fatalSys("invalid destination physical address length"); 7518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project dl_addrlen = dl_abssaplen + ETHERADDRL; 7528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 7538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* ethernet address retrieved as part of DL_INFO_ACK - delphys 20010803 */ 7548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project memcpy(hwaddr, (u_char*)((char*)(dlp) + (int)(dlp->info_ack.dl_addr_offset)), ETHERADDRL); 7558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 7568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ( strioctl(fd, DLIOCRAW, -1, 0, NULL) < 0 ) { 7578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fatalSys("DLIOCRAW"); 7588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 7598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 7608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (ioctl(fd, I_FLUSH, FLUSHR) < 0) fatalSys("I_FLUSH"); 7618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 7628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return fd; 7638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 7648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 7658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* cloned from dlcommon.c */ 7668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 7678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid dlpromisconreq(int fd, u_long level) 7688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 7698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project dl_promiscon_req_t promiscon_req; 7708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct strbuf ctl; 7718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int flags; 7728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 7738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project promiscon_req.dl_primitive = DL_PROMISCON_REQ; 7748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project promiscon_req.dl_level = level; 7758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 7768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ctl.maxlen = 0; 7778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ctl.len = sizeof (promiscon_req); 7788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ctl.buf = (char *) &promiscon_req; 7798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 7808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project flags = 0; 7818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 7828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0) 7838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fatalSys("dlpromiscon: putmsg"); 7848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 7858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 7868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 7878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid dlinforeq(int fd) 7888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 7898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project dl_info_req_t info_req; 7908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct strbuf ctl; 7918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int flags; 7928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 7938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project info_req.dl_primitive = DL_INFO_REQ; 7948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 7958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ctl.maxlen = 0; 7968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ctl.len = sizeof (info_req); 7978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ctl.buf = (char *) &info_req; 7988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 7998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project flags = RS_HIPRI; 8008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 8018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0) 8028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fatalSys("dlinforeq: putmsg"); 8038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 8048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 8058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid dlunitdatareq(int fd, u_char *addrp, int addrlen, u_long minpri, u_long maxpri, u_char *datap, int datalen) 8068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 8078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project long buf[MAXDLBUF]; 8088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project union DL_primitives *dlp; 8098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct strbuf data, ctl; 8108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 8118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project dlp = (union DL_primitives*) buf; 8128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 8138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project dlp->unitdata_req.dl_primitive = DL_UNITDATA_REQ; 8148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project dlp->unitdata_req.dl_dest_addr_length = addrlen; 8158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project dlp->unitdata_req.dl_dest_addr_offset = sizeof (dl_unitdata_req_t); 8168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project dlp->unitdata_req.dl_priority.dl_min = minpri; 8178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project dlp->unitdata_req.dl_priority.dl_max = maxpri; 8188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 8198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (void) memcpy(OFFADDR(dlp, sizeof (dl_unitdata_req_t)), addrp, addrlen); 8208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 8218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ctl.maxlen = 0; 8228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ctl.len = sizeof (dl_unitdata_req_t) + addrlen; 8238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ctl.buf = (char *) buf; 8248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 8258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project data.maxlen = 0; 8268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project data.len = datalen; 8278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project data.buf = (char *) datap; 8288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 8298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (putmsg(fd, &ctl, &data, 0) < 0) 8308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fatalSys("dlunitdatareq: putmsg"); 8318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 8328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 8338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid dlinfoack(int fd, char *bufp) 8348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 8358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project union DL_primitives *dlp; 8368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct strbuf ctl; 8378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int flags; 8388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 8398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ctl.maxlen = MAXDLBUF; 8408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ctl.len = 0; 8418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ctl.buf = bufp; 8428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 8438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project strgetmsg(fd, &ctl, (struct strbuf*)NULL, &flags, "dlinfoack"); 8448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 8458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project dlp = (union DL_primitives *) ctl.buf; 8468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 8478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project expecting(DL_INFO_ACK, dlp); 8488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 8498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (ctl.len < sizeof (dl_info_ack_t)) { 8508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char buffer[256]; 8518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sprintf(buffer, "dlinfoack: response ctl.len too short: %d", ctl.len); 8528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project rp_fatal(buffer); 8538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 8548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 8558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (flags != RS_HIPRI) 8568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project rp_fatal("dlinfoack: DL_INFO_ACK was not M_PCPROTO"); 8578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 8588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (ctl.len < sizeof (dl_info_ack_t)) { 8598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char buffer[256]; 8608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sprintf(buffer, "dlinfoack: short response ctl.len: %d", ctl.len); 8618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project rp_fatal(buffer); 8628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 8638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 8648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 8658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid dlbindreq(int fd, u_long sap, u_long max_conind, u_long service_mode, u_long conn_mgmt, u_long xidtest) 8668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 8678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project dl_bind_req_t bind_req; 8688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct strbuf ctl; 8698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int flags; 8708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 8718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project bind_req.dl_primitive = DL_BIND_REQ; 8728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project bind_req.dl_sap = sap; 8738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project bind_req.dl_max_conind = max_conind; 8748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project bind_req.dl_service_mode = service_mode; 8758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project bind_req.dl_conn_mgmt = conn_mgmt; 8768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project bind_req.dl_xidtest_flg = xidtest; 8778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 8788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ctl.maxlen = 0; 8798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ctl.len = sizeof (bind_req); 8808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ctl.buf = (char *) &bind_req; 8818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 8828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project flags = 0; 8838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 8848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0) 8858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fatalSys("dlbindreq: putmsg"); 8868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 8878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 8888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid dlattachreq(int fd, u_long ppa) 8898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 8908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project dl_attach_req_t attach_req; 8918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct strbuf ctl; 8928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int flags; 8938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 8948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project attach_req.dl_primitive = DL_ATTACH_REQ; 8958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project attach_req.dl_ppa = ppa; 8968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 8978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ctl.maxlen = 0; 8988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ctl.len = sizeof (attach_req); 8998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ctl.buf = (char *) &attach_req; 9008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 9018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project flags = 0; 9028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 9038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0) 9048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fatalSys("dlattachreq: putmsg"); 9058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 9068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 9078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid dlokack(int fd, char *bufp) 9088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 9098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project union DL_primitives *dlp; 9108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct strbuf ctl; 9118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int flags; 9128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 9138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ctl.maxlen = MAXDLBUF; 9148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ctl.len = 0; 9158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ctl.buf = bufp; 9168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 9178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project strgetmsg(fd, &ctl, (struct strbuf*)NULL, &flags, "dlokack"); 9188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 9198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project dlp = (union DL_primitives *) ctl.buf; 9208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 9218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project expecting(DL_OK_ACK, dlp); 9228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 9238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (ctl.len < sizeof (dl_ok_ack_t)) { 9248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char buffer[256]; 9258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sprintf(buffer, "dlokack: response ctl.len too short: %d", ctl.len); 9268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project rp_fatal(buffer); 9278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 9288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 9298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (flags != RS_HIPRI) 9308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project rp_fatal("dlokack: DL_OK_ACK was not M_PCPROTO"); 9318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 9328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (ctl.len < sizeof (dl_ok_ack_t)) { 9338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char buffer[256]; 9348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sprintf(buffer, "dlokack: short response ctl.len: %d", ctl.len); 9358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project rp_fatal(buffer); 9368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 9378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 9388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 9398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid dlbindack(int fd, char *bufp) 9408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 9418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project union DL_primitives *dlp; 9428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct strbuf ctl; 9438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int flags; 9448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 9458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ctl.maxlen = MAXDLBUF; 9468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ctl.len = 0; 9478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project ctl.buf = bufp; 9488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 9498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project strgetmsg(fd, &ctl, (struct strbuf*)NULL, &flags, "dlbindack"); 9508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 9518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project dlp = (union DL_primitives *) ctl.buf; 9528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 9538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project expecting(DL_BIND_ACK, dlp); 9548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 9558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (flags != RS_HIPRI) 9568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project rp_fatal("dlbindack: DL_OK_ACK was not M_PCPROTO"); 9578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 9588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (ctl.len < sizeof (dl_bind_ack_t)) { 9598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char buffer[256]; 9608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sprintf(buffer, "dlbindack: short response ctl.len: %d", ctl.len); 9618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project rp_fatal(buffer); 9628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 9638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 9648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 9658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectint strioctl(int fd, int cmd, int timout, int len, char *dp) 9668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 9678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project struct strioctl sioc; 9688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int rc; 9698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 9708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sioc.ic_cmd = cmd; 9718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sioc.ic_timout = timout; 9728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sioc.ic_len = len; 9738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sioc.ic_dp = dp; 9748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project rc = ioctl(fd, I_STR, &sioc); 9758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 9768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (rc < 0) 9778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return (rc); 9788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project else 9798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return (sioc.ic_len); 9808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 9818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 9828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid strgetmsg(int fd, struct strbuf *ctlp, struct strbuf *datap, int *flagsp, char *caller) 9838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 9848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int rc; 9858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project static char errmsg[80]; 9868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 9878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* 9888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Start timer. 9898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 9908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (void) signal(SIGALRM, sigalrm); 9918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (alarm(MAXWAIT) < 0) { 9928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (void) sprintf(errmsg, "%s: alarm", caller); 9938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fatalSys(errmsg); 9948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 9958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 9968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* 9978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Set flags argument and issue getmsg(). 9988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 9998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *flagsp = 0; 10008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((rc = getmsg(fd, ctlp, datap, flagsp)) < 0) { 10018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (void) sprintf(errmsg, "%s: getmsg", caller); 10028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fatalSys(errmsg); 10038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 10048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 10058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* 10068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Stop timer. 10078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 10088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (alarm(0) < 0) { 10098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (void) sprintf(errmsg, "%s: alarm", caller); 10108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fatalSys(errmsg); 10118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 10128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 10138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* 10148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Check for MOREDATA and/or MORECTL. 10158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 10168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((rc & (MORECTL | MOREDATA)) == (MORECTL | MOREDATA)) { 10178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char buffer[256]; 10188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sprintf(buffer, "%s: MORECTL|MOREDATA", caller); 10198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project rp_fatal(buffer); 10208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 10218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 10228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (rc & MORECTL) { 10238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char buffer[256]; 10248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sprintf(buffer, "%s: MORECTL", caller); 10258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project rp_fatal(buffer); 10268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 10278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 10288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (rc & MOREDATA) { 10298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char buffer[256]; 10308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sprintf(buffer, "%s: MOREDATA", caller); 10318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project rp_fatal(buffer); 10328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 10338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 10348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project /* 10358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project * Check for at least sizeof (long) control data portion. 10368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project */ 10378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (ctlp->len < sizeof (long)) { 10388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char buffer[256]; 10398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sprintf(buffer, "getmsg: control portion length < sizeof (long): %d", ctlp->len); 10408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project rp_fatal(buffer); 10418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 10428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 10438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 10448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid sigalrm(int sig) 10458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 10468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (void) rp_fatal("sigalrm: TIMEOUT"); 10478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 10488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 10498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid expecting(int prim, union DL_primitives *dlp) 10508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 10518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (dlp->dl_primitive != (u_long)prim) { 10528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char buffer[256]; 10538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project sprintf(buffer, "expected %s got %s", dlprim(prim), dlprim(dlp->dl_primitive)); 10548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project rp_fatal(buffer); 10558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project exit(1); 10568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 10578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 10588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 10598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectchar *dlprim(u_long prim) 10608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 10618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project static char primbuf[80]; 10628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 10638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project switch ((int)prim) { 10648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project CASERET(DL_INFO_REQ); 10658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project CASERET(DL_INFO_ACK); 10668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project CASERET(DL_ATTACH_REQ); 10678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project CASERET(DL_DETACH_REQ); 10688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project CASERET(DL_BIND_REQ); 10698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project CASERET(DL_BIND_ACK); 10708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project CASERET(DL_UNBIND_REQ); 10718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project CASERET(DL_OK_ACK); 10728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project CASERET(DL_ERROR_ACK); 10738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project CASERET(DL_SUBS_BIND_REQ); 10748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project CASERET(DL_SUBS_BIND_ACK); 10758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project CASERET(DL_UNITDATA_REQ); 10768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project CASERET(DL_UNITDATA_IND); 10778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project CASERET(DL_UDERROR_IND); 10788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project CASERET(DL_UDQOS_REQ); 10798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project CASERET(DL_CONNECT_REQ); 10808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project CASERET(DL_CONNECT_IND); 10818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project CASERET(DL_CONNECT_RES); 10828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project CASERET(DL_CONNECT_CON); 10838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project CASERET(DL_TOKEN_REQ); 10848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project CASERET(DL_TOKEN_ACK); 10858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project CASERET(DL_DISCONNECT_REQ); 10868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project CASERET(DL_DISCONNECT_IND); 10878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project CASERET(DL_RESET_REQ); 10888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project CASERET(DL_RESET_IND); 10898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project CASERET(DL_RESET_RES); 10908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project CASERET(DL_RESET_CON); 10918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project default: 10928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (void) sprintf(primbuf, "unknown primitive 0x%lx", prim); 10938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return (primbuf); 10948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 10958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 10968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 10978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* USE_DLPI */ 1098