blob: 67925acb2b2749a314b8dcbdbc1ba6daa3b21f54 [file] [log] [blame]
Erik Kline6193aa32015-01-20 12:28:26 +09001/*
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
17package android.net.netlink;
18
19import android.net.netlink.NetlinkConstants;
20import java.nio.ByteBuffer;
21
22
23/**
24 * struct nlmsghdr
25 *
26 * see <linux_src>/include/uapi/linux/netlink.h
27 *
28 * @hide
29 */
30public class StructNlMsgHdr {
31 // Already aligned.
32 public static final int STRUCT_SIZE = 16;
33
34 public static final short NLM_F_REQUEST = 0x0001;
35 public static final short NLM_F_MULTI = 0x0002;
36 public static final short NLM_F_ACK = 0x0004;
37 public static final short NLM_F_ECHO = 0x0008;
38 // Flags for a GET request.
39 public static final short NLM_F_ROOT = 0x0100;
40 public static final short NLM_F_MATCH = 0x0200;
41 public static final short NLM_F_DUMP = NLM_F_ROOT|NLM_F_MATCH;
42
43 public static String stringForNlMsgFlags(short flags) {
44 final StringBuilder sb = new StringBuilder();
45 if ((flags & NLM_F_REQUEST) != 0) {
46 sb.append("NLM_F_REQUEST");
47 }
48 if ((flags & NLM_F_MULTI) != 0) {
49 if (sb.length() > 0) { sb.append("|"); }
50 sb.append("NLM_F_MULTI");
51 }
52 if ((flags & NLM_F_ACK) != 0) {
53 if (sb.length() > 0) { sb.append("|"); }
54 sb.append("NLM_F_ACK");
55 }
56 if ((flags & NLM_F_ECHO) != 0) {
57 if (sb.length() > 0) { sb.append("|"); }
58 sb.append("NLM_F_ECHO");
59 }
60 if ((flags & NLM_F_ROOT) != 0) {
61 if (sb.length() > 0) { sb.append("|"); }
62 sb.append("NLM_F_ROOT");
63 }
64 if ((flags & NLM_F_MATCH) != 0) {
65 if (sb.length() > 0) { sb.append("|"); }
66 sb.append("NLM_F_MATCH");
67 }
68 return sb.toString();
69 }
70
71 public static boolean hasAvailableSpace(ByteBuffer byteBuffer) {
72 return byteBuffer != null && byteBuffer.remaining() >= STRUCT_SIZE;
73 }
74
75 public static StructNlMsgHdr parse(ByteBuffer byteBuffer) {
76 if (!hasAvailableSpace(byteBuffer)) { return null; }
77
78 // The ByteOrder must have already been set by the caller. In most
79 // cases ByteOrder.nativeOrder() is correct, with the exception
80 // of usage within unittests.
81 final StructNlMsgHdr struct = new StructNlMsgHdr();
82 struct.nlmsg_len = byteBuffer.getInt();
83 struct.nlmsg_type = byteBuffer.getShort();
84 struct.nlmsg_flags = byteBuffer.getShort();
85 struct.nlmsg_seq = byteBuffer.getInt();
86 struct.nlmsg_pid = byteBuffer.getInt();
87
88 if (struct.nlmsg_len < STRUCT_SIZE) {
89 // Malformed.
90 return null;
91 }
92 return struct;
93 }
94
95 public int nlmsg_len;
96 public short nlmsg_type;
97 public short nlmsg_flags;
98 public int nlmsg_seq;
99 public int nlmsg_pid;
100
101 public StructNlMsgHdr() {
102 nlmsg_len = 0;
103 nlmsg_type = 0;
104 nlmsg_flags = 0;
105 nlmsg_seq = 0;
106 nlmsg_pid = 0;
107 }
108
109 public boolean pack(ByteBuffer byteBuffer) {
110 if (!hasAvailableSpace(byteBuffer)) { return false; }
111
112 // The ByteOrder must have already been set by the caller. In most
113 // cases ByteOrder.nativeOrder() is correct, with the possible
114 // exception of usage within unittests.
115 byteBuffer.putInt(nlmsg_len);
116 byteBuffer.putShort(nlmsg_type);
117 byteBuffer.putShort(nlmsg_flags);
118 byteBuffer.putInt(nlmsg_seq);
119 byteBuffer.putInt(nlmsg_pid);
120 return true;
121 }
122
123 @Override
124 public String toString() {
125 final String typeStr = "" + nlmsg_type
126 + "(" + NetlinkConstants.stringForNlMsgType(nlmsg_type) + ")";
127 final String flagsStr = "" + nlmsg_flags
128 + "(" + stringForNlMsgFlags(nlmsg_flags) + ")";
129 return "StructNlMsgHdr{ "
130 + "nlmsg_len{" + nlmsg_len + "}, "
131 + "nlmsg_type{" + typeStr + "}, "
132 + "nlmsg_flags{" + flagsStr + ")}, "
133 + "nlmsg_seq{" + nlmsg_seq + "}, "
134 + "nlmsg_pid{" + nlmsg_pid + "} "
135 + "}";
136 }
137}