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 java.nio.ByteBuffer; 21 22 23 /** 24 * struct nlmsghdr 25 * 26 * see <linux_src>/include/uapi/linux/netlink.h 27 * 28 * @hide 29 */ 30 public 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 // Flags for a NEW request. 43 public static final short NLM_F_REPLACE = 0x100; 44 public static final short NLM_F_EXCL = 0x200; 45 public static final short NLM_F_CREATE = 0x400; 46 public static final short NLM_F_APPEND = 0x800; 47 48 stringForNlMsgFlags(short flags)49 public static String stringForNlMsgFlags(short flags) { 50 final StringBuilder sb = new StringBuilder(); 51 if ((flags & NLM_F_REQUEST) != 0) { 52 sb.append("NLM_F_REQUEST"); 53 } 54 if ((flags & NLM_F_MULTI) != 0) { 55 if (sb.length() > 0) { sb.append("|"); } 56 sb.append("NLM_F_MULTI"); 57 } 58 if ((flags & NLM_F_ACK) != 0) { 59 if (sb.length() > 0) { sb.append("|"); } 60 sb.append("NLM_F_ACK"); 61 } 62 if ((flags & NLM_F_ECHO) != 0) { 63 if (sb.length() > 0) { sb.append("|"); } 64 sb.append("NLM_F_ECHO"); 65 } 66 if ((flags & NLM_F_ROOT) != 0) { 67 if (sb.length() > 0) { sb.append("|"); } 68 sb.append("NLM_F_ROOT"); 69 } 70 if ((flags & NLM_F_MATCH) != 0) { 71 if (sb.length() > 0) { sb.append("|"); } 72 sb.append("NLM_F_MATCH"); 73 } 74 return sb.toString(); 75 } 76 hasAvailableSpace(ByteBuffer byteBuffer)77 public static boolean hasAvailableSpace(ByteBuffer byteBuffer) { 78 return byteBuffer != null && byteBuffer.remaining() >= STRUCT_SIZE; 79 } 80 parse(ByteBuffer byteBuffer)81 public static StructNlMsgHdr parse(ByteBuffer byteBuffer) { 82 if (!hasAvailableSpace(byteBuffer)) { return null; } 83 84 // The ByteOrder must have already been set by the caller. In most 85 // cases ByteOrder.nativeOrder() is correct, with the exception 86 // of usage within unittests. 87 final StructNlMsgHdr struct = new StructNlMsgHdr(); 88 struct.nlmsg_len = byteBuffer.getInt(); 89 struct.nlmsg_type = byteBuffer.getShort(); 90 struct.nlmsg_flags = byteBuffer.getShort(); 91 struct.nlmsg_seq = byteBuffer.getInt(); 92 struct.nlmsg_pid = byteBuffer.getInt(); 93 94 if (struct.nlmsg_len < STRUCT_SIZE) { 95 // Malformed. 96 return null; 97 } 98 return struct; 99 } 100 101 public int nlmsg_len; 102 public short nlmsg_type; 103 public short nlmsg_flags; 104 public int nlmsg_seq; 105 public int nlmsg_pid; 106 StructNlMsgHdr()107 public StructNlMsgHdr() { 108 nlmsg_len = 0; 109 nlmsg_type = 0; 110 nlmsg_flags = 0; 111 nlmsg_seq = 0; 112 nlmsg_pid = 0; 113 } 114 pack(ByteBuffer byteBuffer)115 public void pack(ByteBuffer byteBuffer) { 116 // The ByteOrder must have already been set by the caller. In most 117 // cases ByteOrder.nativeOrder() is correct, with the possible 118 // exception of usage within unittests. 119 byteBuffer.putInt(nlmsg_len); 120 byteBuffer.putShort(nlmsg_type); 121 byteBuffer.putShort(nlmsg_flags); 122 byteBuffer.putInt(nlmsg_seq); 123 byteBuffer.putInt(nlmsg_pid); 124 } 125 126 @Override toString()127 public String toString() { 128 final String typeStr = "" + nlmsg_type 129 + "(" + NetlinkConstants.stringForNlMsgType(nlmsg_type) + ")"; 130 final String flagsStr = "" + nlmsg_flags 131 + "(" + stringForNlMsgFlags(nlmsg_flags) + ")"; 132 return "StructNlMsgHdr{ " 133 + "nlmsg_len{" + nlmsg_len + "}, " 134 + "nlmsg_type{" + typeStr + "}, " 135 + "nlmsg_flags{" + flagsStr + ")}, " 136 + "nlmsg_seq{" + nlmsg_seq + "}, " 137 + "nlmsg_pid{" + nlmsg_pid + "} " 138 + "}"; 139 } 140 } 141