Loading common/moduleutils/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ filegroup { srcs: [ "src/android/net/ip/InterfaceController.java", "src/android/net/ip/IpNeighborMonitor.java", "src/android/net/ip/NetlinkMonitor.java", "src/android/net/netlink/*.java", "src/android/net/shared/NetdUtils.java", "src/android/net/shared/RouteUtils.java", Loading common/moduleutils/src/android/net/ip/IpNeighborMonitor.java +7 −80 Original line number Diff line number Diff line Loading @@ -19,35 +19,20 @@ package android.net.ip; import static android.net.netlink.NetlinkConstants.RTM_DELNEIGH; import static android.net.netlink.NetlinkConstants.hexify; import static android.net.netlink.NetlinkConstants.stringForNlMsgType; import static android.net.util.SocketUtils.makeNetlinkSocketAddress; import static android.system.OsConstants.AF_NETLINK; import static android.system.OsConstants.NETLINK_ROUTE; import static android.system.OsConstants.SOCK_DGRAM; import static android.system.OsConstants.SOCK_NONBLOCK; import android.net.MacAddress; import android.net.netlink.NetlinkErrorMessage; import android.net.netlink.NetlinkMessage; import android.net.netlink.NetlinkSocket; import android.net.netlink.RtNetlinkNeighborMessage; import android.net.netlink.StructNdMsg; import android.net.util.PacketReader; import android.net.util.SharedLog; import android.net.util.SocketUtils; import android.os.Handler; import android.os.SystemClock; import android.system.ErrnoException; import android.system.Os; import android.system.OsConstants; import android.util.Log; import java.io.FileDescriptor; import java.io.IOException; import java.net.InetAddress; import java.net.SocketAddress; import java.net.SocketException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.StringJoiner; Loading @@ -61,7 +46,7 @@ import java.util.StringJoiner; * * @hide */ public class IpNeighborMonitor extends PacketReader { public class IpNeighborMonitor extends NetlinkMonitor { private static final String TAG = IpNeighborMonitor.class.getSimpleName(); private static final boolean DBG = false; private static final boolean VDBG = false; Loading Loading @@ -129,85 +114,27 @@ public class IpNeighborMonitor extends PacketReader { } } // TODO: move NetworkStackUtils.closeSocketQuietly to somewhere accessible to this file. private void closeSocketQuietly(FileDescriptor fd) { try { SocketUtils.closeSocket(fd); } catch (IOException ignored) { } } public interface NeighborEventConsumer { // Every neighbor event received on the netlink socket is passed in // here. Subclasses should filter for events of interest. public void accept(NeighborEvent event); } private final SharedLog mLog; private final NeighborEventConsumer mConsumer; public IpNeighborMonitor(Handler h, SharedLog log, NeighborEventConsumer cb) { super(h, NetlinkSocket.DEFAULT_RECV_BUFSIZE); mLog = log.forSubComponent(TAG); super(h, log, TAG, NETLINK_ROUTE, OsConstants.RTMGRP_NEIGH); mConsumer = (cb != null) ? cb : (event) -> { /* discard */ }; } @Override protected FileDescriptor createFd() { FileDescriptor fd = null; try { fd = Os.socket(AF_NETLINK, SOCK_DGRAM | SOCK_NONBLOCK, NETLINK_ROUTE); Os.bind(fd, makeNetlinkSocketAddress(0, OsConstants.RTMGRP_NEIGH)); NetlinkSocket.connectToKernel(fd); if (VDBG) { final SocketAddress nlAddr = Os.getsockname(fd); Log.d(TAG, "bound to sockaddr_nl{" + nlAddr.toString() + "}"); } } catch (ErrnoException|SocketException e) { logError("Failed to create rtnetlink socket", e); closeSocketQuietly(fd); return null; } return fd; } @Override protected void handlePacket(byte[] recvbuf, int length) { final long whenMs = SystemClock.elapsedRealtime(); final ByteBuffer byteBuffer = ByteBuffer.wrap(recvbuf, 0, length); byteBuffer.order(ByteOrder.nativeOrder()); parseNetlinkMessageBuffer(byteBuffer, whenMs); } private void parseNetlinkMessageBuffer(ByteBuffer byteBuffer, long whenMs) { while (byteBuffer.remaining() > 0) { final int position = byteBuffer.position(); final NetlinkMessage nlMsg = NetlinkMessage.parse(byteBuffer); if (nlMsg == null || nlMsg.getHeader() == null) { byteBuffer.position(position); mLog.e("unparsable netlink msg: " + hexify(byteBuffer)); break; } if (nlMsg instanceof NetlinkErrorMessage) { mLog.e("netlink error: " + nlMsg); continue; } else if (!(nlMsg instanceof RtNetlinkNeighborMessage)) { mLog.i("non-rtnetlink neighbor msg: " + nlMsg); continue; } evaluateRtNetlinkNeighborMessage((RtNetlinkNeighborMessage) nlMsg, whenMs); } public void processNetlinkMessage(NetlinkMessage nlMsg, final long whenMs) { if (!(nlMsg instanceof RtNetlinkNeighborMessage)) { mLog.e("non-rtnetlink neighbor msg: " + nlMsg); return; } private void evaluateRtNetlinkNeighborMessage( RtNetlinkNeighborMessage neighMsg, long whenMs) { final RtNetlinkNeighborMessage neighMsg = (RtNetlinkNeighborMessage) nlMsg; final short msgType = neighMsg.getHeader().nlmsg_type; final StructNdMsg ndMsg = neighMsg.getNdHeader(); if (ndMsg == null) { Loading common/moduleutils/src/android/net/ip/NetlinkMonitor.java 0 → 100644 +141 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.net.ip; import static android.net.netlink.NetlinkConstants.hexify; import static android.net.util.SocketUtils.makeNetlinkSocketAddress; import static android.system.OsConstants.AF_NETLINK; import static android.system.OsConstants.SOCK_DGRAM; import static android.system.OsConstants.SOCK_NONBLOCK; import android.annotation.NonNull; import android.net.netlink.NetlinkErrorMessage; import android.net.netlink.NetlinkMessage; import android.net.netlink.NetlinkSocket; import android.net.util.PacketReader; import android.net.util.SharedLog; import android.net.util.SocketUtils; import android.os.Handler; import android.os.SystemClock; import android.system.ErrnoException; import android.system.Os; import android.util.Log; import java.io.FileDescriptor; import java.io.IOException; import java.net.SocketAddress; import java.net.SocketException; import java.nio.ByteBuffer; import java.nio.ByteOrder; /** * A simple base class to listen for netlink broadcasts. * * Opens a netlink socket of the given family and binds to the specified groups. Polls the socket * from the event loop of the passed-in {@link Handler}, and calls the subclass-defined * {@link #processNetlinkMessage} method on the handler thread for each netlink message that * arrives. Currently ignores all netlink errors. */ public class NetlinkMonitor extends PacketReader { protected final SharedLog mLog; protected final String mTag; private final int mFamily; private final int mBindGroups; private static final boolean DBG = false; /** * Constructs a new {@code NetlinkMonitor} instance. * * @param h The Handler on which to poll for messages and on which to call * {@link #processNetlinkMessage}. * @param log A SharedLog to log to. * @param tag The log tag to use for log messages. * @param family the Netlink socket family to, e.g., {@code NETLINK_ROUTE}. * @param bindGroups the netlink groups to bind to. */ public NetlinkMonitor(@NonNull Handler h, @NonNull SharedLog log, @NonNull String tag, int family, int bindGroups) { super(h, NetlinkSocket.DEFAULT_RECV_BUFSIZE); mLog = log.forSubComponent(tag); mTag = tag; mFamily = family; mBindGroups = bindGroups; } @Override protected FileDescriptor createFd() { FileDescriptor fd = null; try { fd = Os.socket(AF_NETLINK, SOCK_DGRAM | SOCK_NONBLOCK, mFamily); Os.bind(fd, makeNetlinkSocketAddress(0, mBindGroups)); NetlinkSocket.connectToKernel(fd); if (DBG) { final SocketAddress nlAddr = Os.getsockname(fd); Log.d(mTag, "bound to sockaddr_nl{" + nlAddr.toString() + "}"); } } catch (ErrnoException | SocketException e) { logError("Failed to create rtnetlink socket", e); closeSocketQuietly(fd); return null; } return fd; } @Override protected void handlePacket(byte[] recvbuf, int length) { final long whenMs = SystemClock.elapsedRealtime(); final ByteBuffer byteBuffer = ByteBuffer.wrap(recvbuf, 0, length); byteBuffer.order(ByteOrder.nativeOrder()); while (byteBuffer.remaining() > 0) { final int position = byteBuffer.position(); final NetlinkMessage nlMsg = NetlinkMessage.parse(byteBuffer); if (nlMsg == null || nlMsg.getHeader() == null) { byteBuffer.position(position); mLog.e("unparsable netlink msg: " + hexify(byteBuffer)); break; } if (nlMsg instanceof NetlinkErrorMessage) { mLog.e("netlink error: " + nlMsg); continue; } processNetlinkMessage(nlMsg, whenMs); } } // TODO: move NetworkStackUtils to frameworks/libs/net for NetworkStackUtils#closeSocketQuietly. private void closeSocketQuietly(FileDescriptor fd) { try { SocketUtils.closeSocket(fd); } catch (IOException ignored) { } } /** * Processes one netlink message. Must be overridden by subclasses. * @param nlMsg the message to process. * @param whenMs the timestamp, as measured by {@link SystemClock#elapsedRealtime}, when the * message was received. */ protected void processNetlinkMessage(NetlinkMessage nlMsg, long whenMs) { } } Loading
common/moduleutils/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ filegroup { srcs: [ "src/android/net/ip/InterfaceController.java", "src/android/net/ip/IpNeighborMonitor.java", "src/android/net/ip/NetlinkMonitor.java", "src/android/net/netlink/*.java", "src/android/net/shared/NetdUtils.java", "src/android/net/shared/RouteUtils.java", Loading
common/moduleutils/src/android/net/ip/IpNeighborMonitor.java +7 −80 Original line number Diff line number Diff line Loading @@ -19,35 +19,20 @@ package android.net.ip; import static android.net.netlink.NetlinkConstants.RTM_DELNEIGH; import static android.net.netlink.NetlinkConstants.hexify; import static android.net.netlink.NetlinkConstants.stringForNlMsgType; import static android.net.util.SocketUtils.makeNetlinkSocketAddress; import static android.system.OsConstants.AF_NETLINK; import static android.system.OsConstants.NETLINK_ROUTE; import static android.system.OsConstants.SOCK_DGRAM; import static android.system.OsConstants.SOCK_NONBLOCK; import android.net.MacAddress; import android.net.netlink.NetlinkErrorMessage; import android.net.netlink.NetlinkMessage; import android.net.netlink.NetlinkSocket; import android.net.netlink.RtNetlinkNeighborMessage; import android.net.netlink.StructNdMsg; import android.net.util.PacketReader; import android.net.util.SharedLog; import android.net.util.SocketUtils; import android.os.Handler; import android.os.SystemClock; import android.system.ErrnoException; import android.system.Os; import android.system.OsConstants; import android.util.Log; import java.io.FileDescriptor; import java.io.IOException; import java.net.InetAddress; import java.net.SocketAddress; import java.net.SocketException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.StringJoiner; Loading @@ -61,7 +46,7 @@ import java.util.StringJoiner; * * @hide */ public class IpNeighborMonitor extends PacketReader { public class IpNeighborMonitor extends NetlinkMonitor { private static final String TAG = IpNeighborMonitor.class.getSimpleName(); private static final boolean DBG = false; private static final boolean VDBG = false; Loading Loading @@ -129,85 +114,27 @@ public class IpNeighborMonitor extends PacketReader { } } // TODO: move NetworkStackUtils.closeSocketQuietly to somewhere accessible to this file. private void closeSocketQuietly(FileDescriptor fd) { try { SocketUtils.closeSocket(fd); } catch (IOException ignored) { } } public interface NeighborEventConsumer { // Every neighbor event received on the netlink socket is passed in // here. Subclasses should filter for events of interest. public void accept(NeighborEvent event); } private final SharedLog mLog; private final NeighborEventConsumer mConsumer; public IpNeighborMonitor(Handler h, SharedLog log, NeighborEventConsumer cb) { super(h, NetlinkSocket.DEFAULT_RECV_BUFSIZE); mLog = log.forSubComponent(TAG); super(h, log, TAG, NETLINK_ROUTE, OsConstants.RTMGRP_NEIGH); mConsumer = (cb != null) ? cb : (event) -> { /* discard */ }; } @Override protected FileDescriptor createFd() { FileDescriptor fd = null; try { fd = Os.socket(AF_NETLINK, SOCK_DGRAM | SOCK_NONBLOCK, NETLINK_ROUTE); Os.bind(fd, makeNetlinkSocketAddress(0, OsConstants.RTMGRP_NEIGH)); NetlinkSocket.connectToKernel(fd); if (VDBG) { final SocketAddress nlAddr = Os.getsockname(fd); Log.d(TAG, "bound to sockaddr_nl{" + nlAddr.toString() + "}"); } } catch (ErrnoException|SocketException e) { logError("Failed to create rtnetlink socket", e); closeSocketQuietly(fd); return null; } return fd; } @Override protected void handlePacket(byte[] recvbuf, int length) { final long whenMs = SystemClock.elapsedRealtime(); final ByteBuffer byteBuffer = ByteBuffer.wrap(recvbuf, 0, length); byteBuffer.order(ByteOrder.nativeOrder()); parseNetlinkMessageBuffer(byteBuffer, whenMs); } private void parseNetlinkMessageBuffer(ByteBuffer byteBuffer, long whenMs) { while (byteBuffer.remaining() > 0) { final int position = byteBuffer.position(); final NetlinkMessage nlMsg = NetlinkMessage.parse(byteBuffer); if (nlMsg == null || nlMsg.getHeader() == null) { byteBuffer.position(position); mLog.e("unparsable netlink msg: " + hexify(byteBuffer)); break; } if (nlMsg instanceof NetlinkErrorMessage) { mLog.e("netlink error: " + nlMsg); continue; } else if (!(nlMsg instanceof RtNetlinkNeighborMessage)) { mLog.i("non-rtnetlink neighbor msg: " + nlMsg); continue; } evaluateRtNetlinkNeighborMessage((RtNetlinkNeighborMessage) nlMsg, whenMs); } public void processNetlinkMessage(NetlinkMessage nlMsg, final long whenMs) { if (!(nlMsg instanceof RtNetlinkNeighborMessage)) { mLog.e("non-rtnetlink neighbor msg: " + nlMsg); return; } private void evaluateRtNetlinkNeighborMessage( RtNetlinkNeighborMessage neighMsg, long whenMs) { final RtNetlinkNeighborMessage neighMsg = (RtNetlinkNeighborMessage) nlMsg; final short msgType = neighMsg.getHeader().nlmsg_type; final StructNdMsg ndMsg = neighMsg.getNdHeader(); if (ndMsg == null) { Loading
common/moduleutils/src/android/net/ip/NetlinkMonitor.java 0 → 100644 +141 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.net.ip; import static android.net.netlink.NetlinkConstants.hexify; import static android.net.util.SocketUtils.makeNetlinkSocketAddress; import static android.system.OsConstants.AF_NETLINK; import static android.system.OsConstants.SOCK_DGRAM; import static android.system.OsConstants.SOCK_NONBLOCK; import android.annotation.NonNull; import android.net.netlink.NetlinkErrorMessage; import android.net.netlink.NetlinkMessage; import android.net.netlink.NetlinkSocket; import android.net.util.PacketReader; import android.net.util.SharedLog; import android.net.util.SocketUtils; import android.os.Handler; import android.os.SystemClock; import android.system.ErrnoException; import android.system.Os; import android.util.Log; import java.io.FileDescriptor; import java.io.IOException; import java.net.SocketAddress; import java.net.SocketException; import java.nio.ByteBuffer; import java.nio.ByteOrder; /** * A simple base class to listen for netlink broadcasts. * * Opens a netlink socket of the given family and binds to the specified groups. Polls the socket * from the event loop of the passed-in {@link Handler}, and calls the subclass-defined * {@link #processNetlinkMessage} method on the handler thread for each netlink message that * arrives. Currently ignores all netlink errors. */ public class NetlinkMonitor extends PacketReader { protected final SharedLog mLog; protected final String mTag; private final int mFamily; private final int mBindGroups; private static final boolean DBG = false; /** * Constructs a new {@code NetlinkMonitor} instance. * * @param h The Handler on which to poll for messages and on which to call * {@link #processNetlinkMessage}. * @param log A SharedLog to log to. * @param tag The log tag to use for log messages. * @param family the Netlink socket family to, e.g., {@code NETLINK_ROUTE}. * @param bindGroups the netlink groups to bind to. */ public NetlinkMonitor(@NonNull Handler h, @NonNull SharedLog log, @NonNull String tag, int family, int bindGroups) { super(h, NetlinkSocket.DEFAULT_RECV_BUFSIZE); mLog = log.forSubComponent(tag); mTag = tag; mFamily = family; mBindGroups = bindGroups; } @Override protected FileDescriptor createFd() { FileDescriptor fd = null; try { fd = Os.socket(AF_NETLINK, SOCK_DGRAM | SOCK_NONBLOCK, mFamily); Os.bind(fd, makeNetlinkSocketAddress(0, mBindGroups)); NetlinkSocket.connectToKernel(fd); if (DBG) { final SocketAddress nlAddr = Os.getsockname(fd); Log.d(mTag, "bound to sockaddr_nl{" + nlAddr.toString() + "}"); } } catch (ErrnoException | SocketException e) { logError("Failed to create rtnetlink socket", e); closeSocketQuietly(fd); return null; } return fd; } @Override protected void handlePacket(byte[] recvbuf, int length) { final long whenMs = SystemClock.elapsedRealtime(); final ByteBuffer byteBuffer = ByteBuffer.wrap(recvbuf, 0, length); byteBuffer.order(ByteOrder.nativeOrder()); while (byteBuffer.remaining() > 0) { final int position = byteBuffer.position(); final NetlinkMessage nlMsg = NetlinkMessage.parse(byteBuffer); if (nlMsg == null || nlMsg.getHeader() == null) { byteBuffer.position(position); mLog.e("unparsable netlink msg: " + hexify(byteBuffer)); break; } if (nlMsg instanceof NetlinkErrorMessage) { mLog.e("netlink error: " + nlMsg); continue; } processNetlinkMessage(nlMsg, whenMs); } } // TODO: move NetworkStackUtils to frameworks/libs/net for NetworkStackUtils#closeSocketQuietly. private void closeSocketQuietly(FileDescriptor fd) { try { SocketUtils.closeSocket(fd); } catch (IOException ignored) { } } /** * Processes one netlink message. Must be overridden by subclasses. * @param nlMsg the message to process. * @param whenMs the timestamp, as measured by {@link SystemClock#elapsedRealtime}, when the * message was received. */ protected void processNetlinkMessage(NetlinkMessage nlMsg, long whenMs) { } }