Erik Kline | 6193aa3 | 2015-01-20 12:28:26 +0900 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2015 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | package android.net.netlink; |
| 18 | |
| 19 | import android.net.netlink.NetlinkConstants; |
| 20 | import android.net.netlink.NetlinkErrorMessage; |
| 21 | import android.net.netlink.RtNetlinkNeighborMessage; |
| 22 | import android.net.netlink.StructNlAttr; |
| 23 | import android.net.netlink.StructNlMsgHdr; |
| 24 | import android.util.Log; |
| 25 | |
| 26 | import java.nio.ByteBuffer; |
| 27 | |
| 28 | |
| 29 | /** |
| 30 | * NetlinkMessage base class for other, more specific netlink message types. |
| 31 | * |
| 32 | * Classes that extend NetlinkMessage should: |
| 33 | * - implement a public static parse(StructNlMsgHdr, ByteBuffer) method |
| 34 | * - returning either null (parse errors) or a new object of the subclass |
| 35 | * type (cast-able to NetlinkMessage) |
| 36 | * |
| 37 | * NetlinkMessage.parse() should be updated to know which nlmsg_type values |
| 38 | * correspond with which message subclasses. |
| 39 | * |
| 40 | * @hide |
| 41 | */ |
| 42 | public class NetlinkMessage { |
| 43 | private final static String TAG = "NetlinkMessage"; |
| 44 | |
| 45 | public static NetlinkMessage parse(ByteBuffer byteBuffer) { |
| 46 | final int startPosition = (byteBuffer != null) ? byteBuffer.position() : -1; |
| 47 | final StructNlMsgHdr nlmsghdr = StructNlMsgHdr.parse(byteBuffer); |
| 48 | if (nlmsghdr == null) { |
| 49 | return null; |
| 50 | } |
| 51 | |
| 52 | int payloadLength = NetlinkConstants.alignedLengthOf(nlmsghdr.nlmsg_len); |
| 53 | payloadLength -= StructNlMsgHdr.STRUCT_SIZE; |
| 54 | if (payloadLength < 0 || payloadLength > byteBuffer.remaining()) { |
| 55 | // Malformed message or runt buffer. Pretend the buffer was consumed. |
| 56 | byteBuffer.position(byteBuffer.limit()); |
| 57 | return null; |
| 58 | } |
| 59 | |
| 60 | switch (nlmsghdr.nlmsg_type) { |
| 61 | //case NetlinkConstants.NLMSG_NOOP: |
| 62 | case NetlinkConstants.NLMSG_ERROR: |
Erik Kline | cef7bc9 | 2015-05-19 14:17:11 +0900 | [diff] [blame^] | 63 | return (NetlinkMessage) NetlinkErrorMessage.parse(nlmsghdr, byteBuffer); |
Erik Kline | 6193aa3 | 2015-01-20 12:28:26 +0900 | [diff] [blame] | 64 | case NetlinkConstants.NLMSG_DONE: |
| 65 | byteBuffer.position(byteBuffer.position() + payloadLength); |
| 66 | return new NetlinkMessage(nlmsghdr); |
| 67 | //case NetlinkConstants.NLMSG_OVERRUN: |
| 68 | case NetlinkConstants.RTM_NEWNEIGH: |
| 69 | case NetlinkConstants.RTM_DELNEIGH: |
| 70 | case NetlinkConstants.RTM_GETNEIGH: |
| 71 | return (NetlinkMessage) RtNetlinkNeighborMessage.parse(nlmsghdr, byteBuffer); |
| 72 | default: |
| 73 | if (nlmsghdr.nlmsg_type <= NetlinkConstants.NLMSG_MAX_RESERVED) { |
| 74 | // Netlink control message. Just parse the header for now, |
| 75 | // pretending the whole message was consumed. |
| 76 | byteBuffer.position(byteBuffer.position() + payloadLength); |
| 77 | return new NetlinkMessage(nlmsghdr); |
| 78 | } |
| 79 | return null; |
| 80 | } |
| 81 | } |
| 82 | |
| 83 | protected StructNlMsgHdr mHeader; |
| 84 | |
| 85 | public NetlinkMessage(StructNlMsgHdr nlmsghdr) { |
| 86 | mHeader = nlmsghdr; |
| 87 | } |
| 88 | |
| 89 | public StructNlMsgHdr getHeader() { |
| 90 | return mHeader; |
| 91 | } |
| 92 | |
| 93 | @Override |
| 94 | public String toString() { |
| 95 | return "NetlinkMessage{" + (mHeader == null ? "" : mHeader.toString()) + "}"; |
| 96 | } |
| 97 | } |