StructNlMsgHdr.java revision 6193aa3305bc2aa5b7f0a983f4b08c99065cfb82
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 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} 138