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 196193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klineimport android.net.netlink.NetlinkConstants; 206193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klineimport android.net.netlink.NetlinkErrorMessage; 216193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klineimport android.net.netlink.RtNetlinkNeighborMessage; 226193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klineimport android.net.netlink.StructNlAttr; 236193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klineimport android.net.netlink.StructNlMsgHdr; 246193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klineimport android.util.Log; 256193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline 266193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klineimport java.nio.ByteBuffer; 276193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline 286193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline 296193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline/** 306193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline * NetlinkMessage base class for other, more specific netlink message types. 316193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline * 326193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline * Classes that extend NetlinkMessage should: 336193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline * - implement a public static parse(StructNlMsgHdr, ByteBuffer) method 346193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline * - returning either null (parse errors) or a new object of the subclass 356193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline * type (cast-able to NetlinkMessage) 366193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline * 376193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline * NetlinkMessage.parse() should be updated to know which nlmsg_type values 386193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline * correspond with which message subclasses. 396193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline * 406193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline * @hide 416193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline */ 426193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klinepublic class NetlinkMessage { 436193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline private final static String TAG = "NetlinkMessage"; 446193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline 456193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline public static NetlinkMessage parse(ByteBuffer byteBuffer) { 466193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline final int startPosition = (byteBuffer != null) ? byteBuffer.position() : -1; 476193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline final StructNlMsgHdr nlmsghdr = StructNlMsgHdr.parse(byteBuffer); 486193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline if (nlmsghdr == null) { 496193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline return null; 506193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline } 516193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline 526193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline int payloadLength = NetlinkConstants.alignedLengthOf(nlmsghdr.nlmsg_len); 536193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline payloadLength -= StructNlMsgHdr.STRUCT_SIZE; 546193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline if (payloadLength < 0 || payloadLength > byteBuffer.remaining()) { 556193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline // Malformed message or runt buffer. Pretend the buffer was consumed. 566193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline byteBuffer.position(byteBuffer.limit()); 576193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline return null; 586193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline } 596193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline 606193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline switch (nlmsghdr.nlmsg_type) { 616193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline //case NetlinkConstants.NLMSG_NOOP: 626193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline case NetlinkConstants.NLMSG_ERROR: 63cef7bc939fbc3baae5ccf78dcef63fc60e07ae21Erik Kline return (NetlinkMessage) NetlinkErrorMessage.parse(nlmsghdr, byteBuffer); 646193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline case NetlinkConstants.NLMSG_DONE: 656193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline byteBuffer.position(byteBuffer.position() + payloadLength); 666193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline return new NetlinkMessage(nlmsghdr); 676193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline //case NetlinkConstants.NLMSG_OVERRUN: 686193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline case NetlinkConstants.RTM_NEWNEIGH: 696193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline case NetlinkConstants.RTM_DELNEIGH: 706193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline case NetlinkConstants.RTM_GETNEIGH: 716193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline return (NetlinkMessage) RtNetlinkNeighborMessage.parse(nlmsghdr, byteBuffer); 726193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline default: 736193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline if (nlmsghdr.nlmsg_type <= NetlinkConstants.NLMSG_MAX_RESERVED) { 746193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline // Netlink control message. Just parse the header for now, 756193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline // pretending the whole message was consumed. 766193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline byteBuffer.position(byteBuffer.position() + payloadLength); 776193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline return new NetlinkMessage(nlmsghdr); 786193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline } 796193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline return null; 806193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline } 816193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline } 826193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline 836193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline protected StructNlMsgHdr mHeader; 846193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline 856193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline public NetlinkMessage(StructNlMsgHdr nlmsghdr) { 866193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline mHeader = nlmsghdr; 876193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline } 886193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline 896193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline public StructNlMsgHdr getHeader() { 906193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline return mHeader; 916193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline } 926193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline 936193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline @Override 946193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline public String toString() { 956193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline return "NetlinkMessage{" + (mHeader == null ? "" : mHeader.toString()) + "}"; 966193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline } 976193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline} 98