16193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline/* 26193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline * Copyright (C) 2015 The Android Open Source Project 36193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline * 46193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline * Licensed under the Apache License, Version 2.0 (the "License"); 56193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline * you may not use this file except in compliance with the License. 66193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline * You may obtain a copy of the License at 76193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline * 86193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline * http://www.apache.org/licenses/LICENSE-2.0 96193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline * 106193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline * Unless required by applicable law or agreed to in writing, software 116193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline * distributed under the License is distributed on an "AS IS" BASIS, 126193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline * See the License for the specific language governing permissions and 146193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline * limitations under the License. 156193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline */ 166193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline 176193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klinepackage android.net.netlink; 186193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline 19cef7bc939fbc3baae5ccf78dcef63fc60e07ae21Erik Klineimport static android.net.netlink.StructNlMsgHdr.NLM_F_ACK; 20cef7bc939fbc3baae5ccf78dcef63fc60e07ae21Erik Klineimport static android.net.netlink.StructNlMsgHdr.NLM_F_DUMP; 21cef7bc939fbc3baae5ccf78dcef63fc60e07ae21Erik Klineimport static android.net.netlink.StructNlMsgHdr.NLM_F_REPLACE; 22cef7bc939fbc3baae5ccf78dcef63fc60e07ae21Erik Klineimport static android.net.netlink.StructNlMsgHdr.NLM_F_REQUEST; 23cef7bc939fbc3baae5ccf78dcef63fc60e07ae21Erik Kline 246193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klineimport android.net.netlink.StructNdaCacheInfo; 256193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klineimport android.net.netlink.StructNdMsg; 266193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klineimport android.net.netlink.StructNlAttr; 276193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klineimport android.net.netlink.StructNlMsgHdr; 286193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klineimport android.net.netlink.NetlinkMessage; 299ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Klineimport android.system.OsConstants; 306193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klineimport android.util.Log; 316193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline 326193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klineimport java.net.InetAddress; 339ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Klineimport java.net.Inet6Address; 346193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klineimport java.nio.ByteBuffer; 356193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klineimport java.nio.ByteOrder; 366193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline 376193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline 386193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline/** 396193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline * A NetlinkMessage subclass for netlink error messages. 406193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline * 416193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline * see also: <linux_src>/include/uapi/linux/neighbour.h 426193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline * 436193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline * @hide 446193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline */ 456193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klinepublic class RtNetlinkNeighborMessage extends NetlinkMessage { 466193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline public static final short NDA_UNSPEC = 0; 476193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline public static final short NDA_DST = 1; 486193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline public static final short NDA_LLADDR = 2; 496193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline public static final short NDA_CACHEINFO = 3; 506193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline public static final short NDA_PROBES = 4; 516193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline public static final short NDA_VLAN = 5; 526193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline public static final short NDA_PORT = 6; 536193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline public static final short NDA_VNI = 7; 546193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline public static final short NDA_IFINDEX = 8; 556193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline public static final short NDA_MASTER = 9; 566193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline 576193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline private static StructNlAttr findNextAttrOfType(short attrType, ByteBuffer byteBuffer) { 586193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline while (byteBuffer != null && byteBuffer.remaining() > 0) { 596193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline final StructNlAttr nlAttr = StructNlAttr.peek(byteBuffer); 606193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline if (nlAttr == null) { 616193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline break; 626193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline } 636193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline if (nlAttr.nla_type == attrType) { 646193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline return StructNlAttr.parse(byteBuffer); 656193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline } 666193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline if (byteBuffer.remaining() < nlAttr.getAlignedLength()) { 676193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline break; 686193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline } 696193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline byteBuffer.position(byteBuffer.position() + nlAttr.getAlignedLength()); 706193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline } 716193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline return null; 726193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline } 736193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline 746193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline public static RtNetlinkNeighborMessage parse(StructNlMsgHdr header, ByteBuffer byteBuffer) { 756193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline final RtNetlinkNeighborMessage neighMsg = new RtNetlinkNeighborMessage(header); 766193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline 776193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline neighMsg.mNdmsg = StructNdMsg.parse(byteBuffer); 786193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline if (neighMsg.mNdmsg == null) { 796193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline return null; 806193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline } 816193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline 826193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline // Some of these are message-type dependent, and not always present. 836193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline final int baseOffset = byteBuffer.position(); 846193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline StructNlAttr nlAttr = findNextAttrOfType(NDA_DST, byteBuffer); 856193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline if (nlAttr != null) { 866193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline neighMsg.mDestination = nlAttr.getValueAsInetAddress(); 876193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline } 886193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline 896193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline byteBuffer.position(baseOffset); 906193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline nlAttr = findNextAttrOfType(NDA_LLADDR, byteBuffer); 916193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline if (nlAttr != null) { 926193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline neighMsg.mLinkLayerAddr = nlAttr.nla_value; 936193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline } 946193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline 956193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline byteBuffer.position(baseOffset); 966193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline nlAttr = findNextAttrOfType(NDA_PROBES, byteBuffer); 976193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline if (nlAttr != null) { 986193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline neighMsg.mNumProbes = nlAttr.getValueAsInt(0); 996193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline } 1006193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline 1016193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline byteBuffer.position(baseOffset); 1026193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline nlAttr = findNextAttrOfType(NDA_CACHEINFO, byteBuffer); 1036193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline if (nlAttr != null) { 1046193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline neighMsg.mCacheInfo = StructNdaCacheInfo.parse(nlAttr.getValueAsByteBuffer()); 1056193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline } 1066193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline 1076193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline final int kMinConsumed = StructNlMsgHdr.STRUCT_SIZE + StructNdMsg.STRUCT_SIZE; 1086193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline final int kAdditionalSpace = NetlinkConstants.alignedLengthOf( 1096193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline neighMsg.mHeader.nlmsg_len - kMinConsumed); 1106193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline if (byteBuffer.remaining() < kAdditionalSpace) { 1116193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline byteBuffer.position(byteBuffer.limit()); 1126193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline } else { 1136193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline byteBuffer.position(baseOffset + kAdditionalSpace); 1146193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline } 1156193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline 1166193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline return neighMsg; 1176193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline } 1186193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline 1196193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline /** 1206193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline * A convenience method to create an RTM_GETNEIGH request message. 1216193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline */ 1226193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline public static byte[] newGetNeighborsRequest(int seqNo) { 1236193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline final int length = StructNlMsgHdr.STRUCT_SIZE + StructNdMsg.STRUCT_SIZE; 1246193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline final byte[] bytes = new byte[length]; 1256193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline final ByteBuffer byteBuffer = ByteBuffer.wrap(bytes); 1266193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline byteBuffer.order(ByteOrder.nativeOrder()); 1276193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline 1286193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline final StructNlMsgHdr nlmsghdr = new StructNlMsgHdr(); 1296193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline nlmsghdr.nlmsg_len = length; 1306193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline nlmsghdr.nlmsg_type = NetlinkConstants.RTM_GETNEIGH; 131cef7bc939fbc3baae5ccf78dcef63fc60e07ae21Erik Kline nlmsghdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP; 1326193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline nlmsghdr.nlmsg_seq = seqNo; 1336193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline nlmsghdr.pack(byteBuffer); 1346193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline 1356193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline final StructNdMsg ndmsg = new StructNdMsg(); 1366193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline ndmsg.pack(byteBuffer); 1376193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline 1386193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline return bytes; 1396193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline } 1406193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline 1419ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline /** 1429ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline * A convenience method to create an RTM_NEWNEIGH message, to modify 1439ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline * the kernel's state information for a specific neighbor. 1449ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline */ 1459ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline public static byte[] newNewNeighborMessage( 1469ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline int seqNo, InetAddress ip, short nudState, int ifIndex, byte[] llAddr) { 1479ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline final StructNlMsgHdr nlmsghdr = new StructNlMsgHdr(); 1489ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline nlmsghdr.nlmsg_type = NetlinkConstants.RTM_NEWNEIGH; 149cef7bc939fbc3baae5ccf78dcef63fc60e07ae21Erik Kline nlmsghdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_REPLACE; 1509ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline nlmsghdr.nlmsg_seq = seqNo; 1519ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline 1529ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline final RtNetlinkNeighborMessage msg = new RtNetlinkNeighborMessage(nlmsghdr); 1539ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline msg.mNdmsg = new StructNdMsg(); 1549ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline msg.mNdmsg.ndm_family = 1559ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline (byte) ((ip instanceof Inet6Address) ? OsConstants.AF_INET6 : OsConstants.AF_INET); 1569ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline msg.mNdmsg.ndm_ifindex = ifIndex; 1579ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline msg.mNdmsg.ndm_state = nudState; 1589ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline msg.mDestination = ip; 1599ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline msg.mLinkLayerAddr = llAddr; // might be null 1609ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline 1619ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline final byte[] bytes = new byte[msg.getRequiredSpace()]; 1629ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline nlmsghdr.nlmsg_len = bytes.length; 1639ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline final ByteBuffer byteBuffer = ByteBuffer.wrap(bytes); 1649ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline byteBuffer.order(ByteOrder.nativeOrder()); 1659ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline msg.pack(byteBuffer); 1669ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline return bytes; 1679ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline } 1689ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline 1696193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline private StructNdMsg mNdmsg; 1706193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline private InetAddress mDestination; 1716193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline private byte[] mLinkLayerAddr; 1726193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline private int mNumProbes; 1736193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline private StructNdaCacheInfo mCacheInfo; 1746193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline 1756193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline private RtNetlinkNeighborMessage(StructNlMsgHdr header) { 1766193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline super(header); 1776193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline mNdmsg = null; 1786193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline mDestination = null; 1796193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline mLinkLayerAddr = null; 1806193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline mNumProbes = 0; 1816193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline mCacheInfo = null; 1826193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline } 1836193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline 1846193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline public StructNdMsg getNdHeader() { 1856193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline return mNdmsg; 1866193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline } 1876193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline 1886193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline public InetAddress getDestination() { 1896193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline return mDestination; 1906193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline } 1916193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline 1926193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline public byte[] getLinkLayerAddress() { 1936193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline return mLinkLayerAddr; 1946193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline } 1956193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline 1966193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline public int getProbes() { 1976193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline return mNumProbes; 1986193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline } 1996193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline 2006193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline public StructNdaCacheInfo getCacheInfo() { 2016193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline return mCacheInfo; 2026193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline } 2036193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline 2049ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline public int getRequiredSpace() { 2059ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline int spaceRequired = StructNlMsgHdr.STRUCT_SIZE + StructNdMsg.STRUCT_SIZE; 2069ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline if (mDestination != null) { 2079ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline spaceRequired += NetlinkConstants.alignedLengthOf( 2089ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline StructNlAttr.NLA_HEADERLEN + mDestination.getAddress().length); 2099ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline } 2109ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline if (mLinkLayerAddr != null) { 2119ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline spaceRequired += NetlinkConstants.alignedLengthOf( 2129ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline StructNlAttr.NLA_HEADERLEN + mLinkLayerAddr.length); 2139ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline } 2149ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline // Currently we don't write messages with NDA_PROBES nor NDA_CACHEINFO 2159ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline // attributes appended. Fix later, if necessary. 2169ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline return spaceRequired; 2179ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline } 2189ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline 2199ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline private static void packNlAttr(short nlType, byte[] nlValue, ByteBuffer byteBuffer) { 2209ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline final StructNlAttr nlAttr = new StructNlAttr(); 2219ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline nlAttr.nla_type = nlType; 2229ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline nlAttr.nla_value = nlValue; 2239ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline nlAttr.nla_len = (short) (StructNlAttr.NLA_HEADERLEN + nlAttr.nla_value.length); 2249ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline nlAttr.pack(byteBuffer); 2259ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline } 2269ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline 2279ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline public void pack(ByteBuffer byteBuffer) { 2289ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline getHeader().pack(byteBuffer) ; 2299ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline mNdmsg.pack(byteBuffer); 2309ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline 2319ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline if (mDestination != null) { 2329ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline packNlAttr(NDA_DST, mDestination.getAddress(), byteBuffer); 2339ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline } 2349ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline if (mLinkLayerAddr != null) { 2359ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline packNlAttr(NDA_LLADDR, mLinkLayerAddr, byteBuffer); 2369ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline } 2379ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline } 2389ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline 2396193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline @Override 2406193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline public String toString() { 2416193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline final String ipLiteral = (mDestination == null) ? "" : mDestination.getHostAddress(); 2426193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline return "RtNetlinkNeighborMessage{ " 2436193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline + "nlmsghdr{" + (mHeader == null ? "" : mHeader.toString()) + "}, " 2446193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline + "ndmsg{" + (mNdmsg == null ? "" : mNdmsg.toString()) + "}, " 2456193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline + "destination{" + ipLiteral + "} " 2466193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline + "linklayeraddr{" + NetlinkConstants.hexify(mLinkLayerAddr) + "} " 2476193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline + "probes{" + mNumProbes + "} " 2486193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline + "cacheinfo{" + (mCacheInfo == null ? "" : mCacheInfo.toString()) + "} " 2496193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline + "}"; 2506193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline } 2516193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline} 252