1 /* 2 * Copyright (C) 2017 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.annotation.NonNull; 20 import android.annotation.Nullable; 21 22 import java.nio.ByteBuffer; 23 import java.nio.ByteOrder; 24 import java.util.Objects; 25 26 27 /** 28 * struct nfgenmsg 29 * 30 * see <linux_src>/include/uapi/linux/netfilter/nfnetlink.h 31 * 32 * @hide 33 */ 34 public class StructNfGenMsg { 35 public static final int STRUCT_SIZE = 2 + Short.BYTES; 36 37 public static final int NFNETLINK_V0 = 0; 38 39 final public byte nfgen_family; 40 final public byte version; 41 final public short res_id; // N.B.: this is big endian in the kernel 42 43 /** 44 * Parses a netfilter netlink header from a {@link ByteBuffer}. 45 * 46 * @param byteBuffer The buffer from which to parse the netfilter netlink header. 47 * @return the parsed netfilter netlink header, or {@code null} if the netfilter netlink header 48 * could not be parsed successfully (for example, if it was truncated). 49 */ 50 @Nullable parse(@onNull ByteBuffer byteBuffer)51 public static StructNfGenMsg parse(@NonNull ByteBuffer byteBuffer) { 52 Objects.requireNonNull(byteBuffer); 53 54 if (!hasAvailableSpace(byteBuffer)) return null; 55 56 final byte nfgen_family = byteBuffer.get(); 57 final byte version = byteBuffer.get(); 58 59 final ByteOrder originalOrder = byteBuffer.order(); 60 byteBuffer.order(ByteOrder.BIG_ENDIAN); 61 final short res_id = byteBuffer.getShort(); 62 byteBuffer.order(originalOrder); 63 64 return new StructNfGenMsg(nfgen_family, version, res_id); 65 } 66 StructNfGenMsg(byte family, byte ver, short id)67 public StructNfGenMsg(byte family, byte ver, short id) { 68 nfgen_family = family; 69 version = ver; 70 res_id = id; 71 } 72 StructNfGenMsg(byte family)73 public StructNfGenMsg(byte family) { 74 nfgen_family = family; 75 version = (byte) NFNETLINK_V0; 76 res_id = (short) 0; 77 } 78 pack(ByteBuffer byteBuffer)79 public void pack(ByteBuffer byteBuffer) { 80 byteBuffer.put(nfgen_family); 81 byteBuffer.put(version); 82 83 final ByteOrder originalOrder = byteBuffer.order(); 84 byteBuffer.order(ByteOrder.BIG_ENDIAN); 85 byteBuffer.putShort(res_id); 86 byteBuffer.order(originalOrder); 87 } 88 hasAvailableSpace(@onNull ByteBuffer byteBuffer)89 private static boolean hasAvailableSpace(@NonNull ByteBuffer byteBuffer) { 90 return byteBuffer.remaining() >= STRUCT_SIZE; 91 } 92 93 @Override toString()94 public String toString() { 95 final String familyStr = NetlinkConstants.stringForAddressFamily(nfgen_family); 96 97 return "NfGenMsg{ " 98 + "nfgen_family{" + familyStr + "}, " 99 + "version{" + Byte.toUnsignedInt(version) + "}, " 100 + "res_id{" + Short.toUnsignedInt(res_id) + "} " 101 + "}"; 102 } 103 } 104