1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.net.netlink;
import android.system.OsConstants;
import java.nio.ByteBuffer;
/**
* Various constants and static helper methods for netlink communications.
*
* Values taken from:
*
* <linux_src>/include/uapi/linux/netlink.h
* <linux_src>/include/uapi/linux/rtnetlink.h
*
* @hide
*/
public class NetlinkConstants {
private NetlinkConstants() {}
public static final int NLA_ALIGNTO = 4;
/**
* Flag for dumping struct tcp_info.
* Corresponding to enum definition in external/strace/linux/inet_diag.h.
*/
public static final int INET_DIAG_MEMINFO = 1;
public static final int SOCKDIAG_MSG_HEADER_SIZE =
StructNlMsgHdr.STRUCT_SIZE + StructInetDiagMsg.STRUCT_SIZE;
public static final int alignedLengthOf(short length) {
final int intLength = (int) length & 0xffff;
return alignedLengthOf(intLength);
}
public static final int alignedLengthOf(int length) {
if (length <= 0) { return 0; }
return (((length + NLA_ALIGNTO - 1) / NLA_ALIGNTO) * NLA_ALIGNTO);
}
public static String stringForAddressFamily(int family) {
if (family == OsConstants.AF_INET) { return "AF_INET"; }
if (family == OsConstants.AF_INET6) { return "AF_INET6"; }
if (family == OsConstants.AF_NETLINK) { return "AF_NETLINK"; }
return String.valueOf(family);
}
public static String stringForProtocol(int protocol) {
if (protocol == OsConstants.IPPROTO_TCP) { return "IPPROTO_TCP"; }
if (protocol == OsConstants.IPPROTO_UDP) { return "IPPROTO_UDP"; }
return String.valueOf(protocol);
}
public static String hexify(byte[] bytes) {
if (bytes == null) { return "(null)"; }
return toHexString(bytes, 0, bytes.length);
}
public static String hexify(ByteBuffer buffer) {
if (buffer == null) { return "(null)"; }
return toHexString(
buffer.array(), buffer.position(), buffer.remaining());
}
// Known values for struct nlmsghdr nlm_type.
public static final short NLMSG_NOOP = 1; // Nothing
public static final short NLMSG_ERROR = 2; // Error
public static final short NLMSG_DONE = 3; // End of a dump
public static final short NLMSG_OVERRUN = 4; // Data lost
public static final short NLMSG_MAX_RESERVED = 15; // Max reserved value
public static final short RTM_NEWLINK = 16;
public static final short RTM_DELLINK = 17;
public static final short RTM_GETLINK = 18;
public static final short RTM_SETLINK = 19;
public static final short RTM_NEWADDR = 20;
public static final short RTM_DELADDR = 21;
public static final short RTM_GETADDR = 22;
public static final short RTM_NEWROUTE = 24;
public static final short RTM_DELROUTE = 25;
public static final short RTM_GETROUTE = 26;
public static final short RTM_NEWNEIGH = 28;
public static final short RTM_DELNEIGH = 29;
public static final short RTM_GETNEIGH = 30;
public static final short RTM_NEWRULE = 32;
public static final short RTM_DELRULE = 33;
public static final short RTM_GETRULE = 34;
public static final short RTM_NEWNDUSEROPT = 68;
/* see <linux_src>/include/uapi/linux/sock_diag.h */
public static final short SOCK_DIAG_BY_FAMILY = 20;
// Netlink groups.
public static final int RTNLGRP_ND_USEROPT = 20;
public static final int RTMGRP_ND_USEROPT = 1 << (RTNLGRP_ND_USEROPT - 1);
public static String stringForNlMsgType(short nlm_type) {
switch (nlm_type) {
case NLMSG_NOOP: return "NLMSG_NOOP";
case NLMSG_ERROR: return "NLMSG_ERROR";
case NLMSG_DONE: return "NLMSG_DONE";
case NLMSG_OVERRUN: return "NLMSG_OVERRUN";
case RTM_NEWLINK: return "RTM_NEWLINK";
case RTM_DELLINK: return "RTM_DELLINK";
case RTM_GETLINK: return "RTM_GETLINK";
case RTM_SETLINK: return "RTM_SETLINK";
case RTM_NEWADDR: return "RTM_NEWADDR";
case RTM_DELADDR: return "RTM_DELADDR";
case RTM_GETADDR: return "RTM_GETADDR";
case RTM_NEWROUTE: return "RTM_NEWROUTE";
case RTM_DELROUTE: return "RTM_DELROUTE";
case RTM_GETROUTE: return "RTM_GETROUTE";
case RTM_NEWNEIGH: return "RTM_NEWNEIGH";
case RTM_DELNEIGH: return "RTM_DELNEIGH";
case RTM_GETNEIGH: return "RTM_GETNEIGH";
case RTM_NEWRULE: return "RTM_NEWRULE";
case RTM_DELRULE: return "RTM_DELRULE";
case RTM_GETRULE: return "RTM_GETRULE";
case RTM_NEWNDUSEROPT: return "RTM_NEWNDUSEROPT";
default:
return "unknown RTM type: " + String.valueOf(nlm_type);
}
}
private static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F' };
/**
* Convert a byte array to a hexadecimal string.
*/
public static String toHexString(byte[] array, int offset, int length) {
char[] buf = new char[length * 2];
int bufIndex = 0;
for (int i = offset; i < offset + length; i++) {
byte b = array[i];
buf[bufIndex++] = HEX_DIGITS[(b >>> 4) & 0x0F];
buf[bufIndex++] = HEX_DIGITS[b & 0x0F];
}
return new String(buf);
}
}
|