1975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt/* 2975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt * Copyright 2010, The Android Open Source Project 3975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt * 4975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt * Licensed under the Apache License, Version 2.0 (the "License"); 5975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt * you may not use this file except in compliance with the License. 6975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt * You may obtain a copy of the License at 7975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt * 8975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt * http://www.apache.org/licenses/LICENSE-2.0 9975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt * 10975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt * Unless required by applicable law or agreed to in writing, software 11975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt * distributed under the License is distributed on an "AS IS" BASIS, 12975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt * See the License for the specific language governing permissions and 14975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt * limitations under the License. 15975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt */ 16975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt 17975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt#include "AsynchronousSocketCloseMonitor.h" 18975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt#include "JNIHelp.h" 19975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt#include "JniException.h" 20975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt#include "JniConstants.h" 21975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt#include "NetFd.h" 22975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt#include "NetworkUtilities.h" 23975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt#include "ScopedUtfChars.h" 24975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt#include "ScopedPrimitiveArray.h" 25975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt 26975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt#include "jni.h" 27975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt 28975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt#include <sys/types.h> 29975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt#include <sys/socket.h> 30975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt#include <linux/rtnetlink.h> 31975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt#include <net/if.h> 32975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt#include <linux/if_ether.h> 33975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt#include <linux/if_packet.h> 34975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt#include <arpa/inet.h> 35975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt#include <errno.h> 36975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt#include <fcntl.h> 37975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt#include <poll.h> 38975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt#include <netinet/ip.h> 39975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt#include <linux/udp.h> 40975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt 41da2fb9754a9ccfa954c1b554982f06e7cf7d680aElliott Hughesunion sockunion { 422f03ccad590827233fcba84a8b6eafcd414e5fe7Elliott Hughes sockaddr sa; 432f03ccad590827233fcba84a8b6eafcd414e5fe7Elliott Hughes sockaddr_ll sll; 44da2fb9754a9ccfa954c1b554982f06e7cf7d680aElliott Hughes}; 452f03ccad590827233fcba84a8b6eafcd414e5fe7Elliott Hughes 46975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt/* 47975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt * Creates a socket suitable for raw socket operations. The socket is 48975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt * bound to the interface specified by the supplied name. The socket 49975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt * value is placed into the supplied FileDescriptor instance. 50975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt * 51975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt * TODO(chesnutt): consider breaking this into pieces: create a 52975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt * variety of constructors for different socket types, then a generic 53975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt * setBlocking() method followed by polymorphic bind(). 54975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt */ 55975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnuttstatic void RawSocket_create(JNIEnv* env, jclass, jobject fileDescriptor, 565f0ed6ed5798a3e6ad642bcd5382b864796cdcb8Irfan Sheriff jshort protocolType, jstring interfaceName) 575f0ed6ed5798a3e6ad642bcd5382b864796cdcb8Irfan Sheriff{ 58975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt 59975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt ScopedUtfChars ifname(env, interfaceName); 60975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt if (ifname.c_str() == NULL) { 61975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt return; 62975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt } 63975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt 64da2fb9754a9ccfa954c1b554982f06e7cf7d680aElliott Hughes sockunion su; 65975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt memset(&su, 0, sizeof(su)); 66975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt su.sll.sll_family = PF_PACKET; 675f0ed6ed5798a3e6ad642bcd5382b864796cdcb8Irfan Sheriff su.sll.sll_protocol = htons(protocolType); 68975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt su.sll.sll_ifindex = if_nametoindex(ifname.c_str()); 695f0ed6ed5798a3e6ad642bcd5382b864796cdcb8Irfan Sheriff int sock = socket(PF_PACKET, SOCK_DGRAM, htons(protocolType)); 70975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt 71975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt if (sock == -1) { 72679cf68b607e9b4a3beb8bcdee06868ae583386fSteve Block ALOGE("Can't create socket %s", strerror(errno)); 73975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt jniThrowSocketException(env, errno); 74975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt return; 75975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt } 76975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt 77975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt jniSetFileDescriptorOfFD(env, fileDescriptor, sock); 78975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt if (!setBlocking(sock, false)) { 79679cf68b607e9b4a3beb8bcdee06868ae583386fSteve Block ALOGE("Can't set non-blocking mode on socket %s", strerror(errno)); 80975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt jniThrowSocketException(env, errno); 81975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt return; 82975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt } 83975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt 84975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt int err = bind(sock, &su.sa, sizeof(su)); 85975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt if (err != 0) { 86679cf68b607e9b4a3beb8bcdee06868ae583386fSteve Block ALOGE("Socket bind error %s", strerror(errno)); 87975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt jniThrowSocketException(env, errno); 88975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt return; 89975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt } 90975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt} 91975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt 92975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt/* 93975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt * Writes the L3 (IP) packet to the raw socket supplied in the 94975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt * FileDescriptor instance. 95975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt * 96975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt * Assumes that the caller has validated the offset & byteCount values. 97975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt */ 98975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnuttstatic int RawSocket_sendPacket(JNIEnv* env, jclass, jobject fileDescriptor, 995f0ed6ed5798a3e6ad642bcd5382b864796cdcb8Irfan Sheriff jstring interfaceName, jshort protocolType, jbyteArray destMac, 1005f0ed6ed5798a3e6ad642bcd5382b864796cdcb8Irfan Sheriff jbyteArray packet, jint offset, jint byteCount) 101975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt{ 102975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt NetFd fd(env, fileDescriptor); 103975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt 104975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt if (fd.isClosed()) { 105975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt return 0; 106975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt } 107975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt 108975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt ScopedUtfChars ifname(env, interfaceName); 109975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt if (ifname.c_str() == NULL) { 110975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt return 0; 111975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt } 112975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt 113975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt ScopedByteArrayRO byteArray(env, packet); 114975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt if (byteArray.get() == NULL) { 115975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt return 0; 116975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt } 117975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt 118975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt ScopedByteArrayRO mac(env, destMac); 119975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt if (mac.get() == NULL) { 120975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt return 0; 121975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt } 122975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt 123da2fb9754a9ccfa954c1b554982f06e7cf7d680aElliott Hughes sockunion su; 124975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt memset(&su, 0, sizeof(su)); 125975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt su.sll.sll_hatype = htons(1); // ARPHRD_ETHER 126975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt su.sll.sll_halen = mac.size(); 127975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt memcpy(&su.sll.sll_addr, mac.get(), mac.size()); 128975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt su.sll.sll_family = AF_PACKET; 1295f0ed6ed5798a3e6ad642bcd5382b864796cdcb8Irfan Sheriff su.sll.sll_protocol = htons(protocolType); 130975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt su.sll.sll_ifindex = if_nametoindex(ifname.c_str()); 131975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt 132975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt int err; 133975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt { 134975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt int intFd = fd.get(); 135975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt AsynchronousSocketCloseMonitor monitor(intFd); 136975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt err = NET_FAILURE_RETRY(fd, sendto(intFd, byteArray.get() + offset, 137975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt byteCount, 0, &su.sa, sizeof(su))); 138975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt } 139975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt 140975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt return err; 141975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt} 142975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt 143975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt/* 144975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt * Reads a network packet into the user-supplied buffer. Return the 145975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt * length of the packet, or a 0 if there was a timeout or an 146975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt * unacceptable packet was acquired. 147975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt * 148975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt * Assumes that the caller has validated the offset & byteCount values. 149975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt */ 150975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnuttstatic jint RawSocket_recvPacket(JNIEnv* env, jclass, jobject fileDescriptor, 151975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt jbyteArray packet, jint offset, jint byteCount, jint port, 152975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt jint timeout_millis) 153975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt{ 154975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt NetFd fd(env, fileDescriptor); 155975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt if (fd.isClosed()) { 156975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt return 0; 157975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt } 158975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt 159975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt ScopedByteArrayRW body(env, packet); 160975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt jbyte* packetData = body.get(); 161975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt if (packetData == NULL) { 162975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt return 0; 163975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt } 164975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt 165975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt packetData += offset; 166975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt 1672f03ccad590827233fcba84a8b6eafcd414e5fe7Elliott Hughes pollfd fds[1]; 168975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt fds[0].fd = fd.get(); 169975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt fds[0].events = POLLIN; 170975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt int retval = poll(fds, 1, timeout_millis); 171975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt if (retval <= 0) { 172975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt return 0; 173975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt } 174975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt 1752f03ccad590827233fcba84a8b6eafcd414e5fe7Elliott Hughes unsigned int size = 0; 176975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt { 1772f03ccad590827233fcba84a8b6eafcd414e5fe7Elliott Hughes int packetSize = byteCount; 178975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt int intFd = fd.get(); 179975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt AsynchronousSocketCloseMonitor monitor(intFd); 180975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt size = NET_FAILURE_RETRY(fd, read(intFd, packetData, packetSize)); 181975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt } 182975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt 183975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt if (env->ExceptionOccurred()) { 184975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt return 0; 185975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt } 186975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt 1875f0ed6ed5798a3e6ad642bcd5382b864796cdcb8Irfan Sheriff if (port != -1) { 1885f0ed6ed5798a3e6ad642bcd5382b864796cdcb8Irfan Sheriff // quick check for UDP type & UDP port 1895f0ed6ed5798a3e6ad642bcd5382b864796cdcb8Irfan Sheriff // the packet is an IP header, UDP header, and UDP payload 1905f0ed6ed5798a3e6ad642bcd5382b864796cdcb8Irfan Sheriff if ((size < (sizeof(struct iphdr) + sizeof(struct udphdr)))) { 1915f0ed6ed5798a3e6ad642bcd5382b864796cdcb8Irfan Sheriff return 0; // runt packet 1925f0ed6ed5798a3e6ad642bcd5382b864796cdcb8Irfan Sheriff } 193975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt 1945f0ed6ed5798a3e6ad642bcd5382b864796cdcb8Irfan Sheriff u_int8_t ip_proto = ((iphdr *) packetData)->protocol; 1955f0ed6ed5798a3e6ad642bcd5382b864796cdcb8Irfan Sheriff if (ip_proto != IPPROTO_UDP) { 1965f0ed6ed5798a3e6ad642bcd5382b864796cdcb8Irfan Sheriff return 0; // something other than UDP 1975f0ed6ed5798a3e6ad642bcd5382b864796cdcb8Irfan Sheriff } 198975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt 1995f0ed6ed5798a3e6ad642bcd5382b864796cdcb8Irfan Sheriff __be16 destPort = htons((reinterpret_cast<udphdr*>(packetData + sizeof(iphdr)))->dest); 2005f0ed6ed5798a3e6ad642bcd5382b864796cdcb8Irfan Sheriff if (destPort != port) { 2015f0ed6ed5798a3e6ad642bcd5382b864796cdcb8Irfan Sheriff return 0; // something other than requested port 2025f0ed6ed5798a3e6ad642bcd5382b864796cdcb8Irfan Sheriff } 203975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt } 204975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt 205975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt return size; 206975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt} 207975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt 208975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnuttstatic JNINativeMethod gRawMethods[] = { 2097cd6760f7045d771faae8080a8c6150bf678f679Elliott Hughes NATIVE_METHOD(RawSocket, create, "(Ljava/io/FileDescriptor;SLjava/lang/String;)V"), 2107cd6760f7045d771faae8080a8c6150bf678f679Elliott Hughes NATIVE_METHOD(RawSocket, sendPacket, "(Ljava/io/FileDescriptor;Ljava/lang/String;S[B[BII)I"), 2117cd6760f7045d771faae8080a8c6150bf678f679Elliott Hughes NATIVE_METHOD(RawSocket, recvPacket, "(Ljava/io/FileDescriptor;[BIIII)I"), 212975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt}; 213975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt 2147cd6760f7045d771faae8080a8c6150bf678f679Elliott Hughesvoid register_libcore_net_RawSocket(JNIEnv* env) { 2157cd6760f7045d771faae8080a8c6150bf678f679Elliott Hughes jniRegisterNativeMethods(env, "libcore/net/RawSocket", gRawMethods, NELEM(gRawMethods)); 216975dc421bdf9f207ed88b3fbedbba558f0f62c3cStan Chesnutt} 217