• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
parse(ByteBuffer byteBuffer)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:
63                 return (NetlinkMessage) NetlinkErrorMessage.parse(nlmsghdr, byteBuffer);
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 
NetlinkMessage(StructNlMsgHdr nlmsghdr)85     public NetlinkMessage(StructNlMsgHdr nlmsghdr) {
86         mHeader = nlmsghdr;
87     }
88 
getHeader()89     public StructNlMsgHdr getHeader() {
90         return mHeader;
91     }
92 
93     @Override
toString()94     public String toString() {
95         return "NetlinkMessage{" + (mHeader == null ? "" : mHeader.toString()) + "}";
96     }
97 }
98