1 /*
2  * Copyright (C) 2019 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 com.android.net.module.util.netlink;
18 
19 import androidx.annotation.NonNull;
20 import androidx.annotation.Nullable;
21 
22 import java.nio.ByteBuffer;
23 
24 /**
25  * struct inet_diag_msg
26  *
27  * see <linux_src>/include/uapi/linux/inet_diag.h
28  *
29  * struct inet_diag_msg {
30  *      __u8    idiag_family;
31  *      __u8    idiag_state;
32  *      __u8    idiag_timer;
33  *      __u8    idiag_retrans;
34  *      struct  inet_diag_sockid id;
35  *      __u32   idiag_expires;
36  *      __u32   idiag_rqueue;
37  *      __u32   idiag_wqueue;
38  *      __u32   idiag_uid;
39  *      __u32   idiag_inode;
40  * };
41  *
42  * @hide
43  */
44 public class StructInetDiagMsg {
45     public static final int STRUCT_SIZE = 4 + StructInetDiagSockId.STRUCT_SIZE + 20;
46     public short idiag_family;
47     public short idiag_state;
48     public short idiag_timer;
49     public short idiag_retrans;
50     @NonNull
51     public StructInetDiagSockId id;
52     public long idiag_expires;
53     public long idiag_rqueue;
54     public long idiag_wqueue;
55     // Use int for uid since other code use int for uid and uid fits to int
56     public int idiag_uid;
57     public long idiag_inode;
58 
unsignedByte(byte b)59     private static short unsignedByte(byte b) {
60         return (short) (b & 0xFF);
61     }
62 
63     /**
64      * Parse inet diag netlink message from buffer.
65      */
66     @Nullable
parse(@onNull ByteBuffer byteBuffer)67     public static StructInetDiagMsg parse(@NonNull ByteBuffer byteBuffer) {
68         if (byteBuffer.remaining() < STRUCT_SIZE) {
69             return null;
70         }
71         StructInetDiagMsg struct = new StructInetDiagMsg();
72         struct.idiag_family = unsignedByte(byteBuffer.get());
73         struct.idiag_state = unsignedByte(byteBuffer.get());
74         struct.idiag_timer = unsignedByte(byteBuffer.get());
75         struct.idiag_retrans = unsignedByte(byteBuffer.get());
76         struct.id = StructInetDiagSockId.parse(byteBuffer, struct.idiag_family);
77         if (struct.id == null) {
78             return null;
79         }
80         struct.idiag_expires = Integer.toUnsignedLong(byteBuffer.getInt());
81         struct.idiag_rqueue = Integer.toUnsignedLong(byteBuffer.getInt());
82         struct.idiag_wqueue = Integer.toUnsignedLong(byteBuffer.getInt());
83         struct.idiag_uid = byteBuffer.getInt();
84         struct.idiag_inode = Integer.toUnsignedLong(byteBuffer.getInt());
85         return struct;
86     }
87 
88     @Override
toString()89     public String toString() {
90         return "StructInetDiagMsg{ "
91                 + "idiag_family{" + idiag_family + "}, "
92                 + "idiag_state{" + idiag_state + "}, "
93                 + "idiag_timer{" + idiag_timer + "}, "
94                 + "idiag_retrans{" + idiag_retrans + "}, "
95                 + "id{" + id + "}, "
96                 + "idiag_expires{" + idiag_expires + "}, "
97                 + "idiag_rqueue{" + idiag_rqueue + "}, "
98                 + "idiag_wqueue{" + idiag_wqueue + "}, "
99                 + "idiag_uid{" + idiag_uid + "}, "
100                 + "idiag_inode{" + idiag_inode + "}, "
101                 + "}";
102     }
103 }
104