1 /*
2 * Copyright (C) 2020 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 @file:JvmName("NetlinkTestUtils")
18
19 package android.net.netlink
20
21 import android.net.netlink.NetlinkConstants.RTM_DELNEIGH
22 import android.net.netlink.NetlinkConstants.RTM_NEWNEIGH
23 import libcore.util.HexEncoding
24 import libcore.util.HexEncoding.encodeToString
25 import java.net.Inet6Address
26 import java.net.InetAddress
27
28 /**
29 * Make a RTM_NEWNEIGH netlink message.
30 */
makeNewNeighMessagenull31 fun makeNewNeighMessage(
32 neighAddr: InetAddress,
33 nudState: Short
34 ) = makeNeighborMessage(
35 neighAddr = neighAddr,
36 type = RTM_NEWNEIGH,
37 nudState = nudState
38 )
39
40 /**
41 * Make a RTM_DELNEIGH netlink message.
42 */
43 fun makeDelNeighMessage(
44 neighAddr: InetAddress,
45 nudState: Short
46 ) = makeNeighborMessage(
47 neighAddr = neighAddr,
48 type = RTM_DELNEIGH,
49 nudState = nudState
50 )
51
52 private fun makeNeighborMessage(
53 neighAddr: InetAddress,
54 type: Short,
55 nudState: Short
56 ) = HexEncoding.decode(
57 /* ktlint-disable indent */
58 // -- struct nlmsghdr --
59 // length = 88 or 76:
60 (if (neighAddr is Inet6Address) "58000000" else "4c000000") +
61 type.toLEHex() + // type
62 "0000" + // flags
63 "00000000" + // seqno
64 "00000000" + // pid (0 == kernel)
65 // struct ndmsg
66 // family (AF_INET6 or AF_INET)
67 (if (neighAddr is Inet6Address) "0a" else "02") +
68 "00" + // pad1
69 "0000" + // pad2
70 "15000000" + // interface index (21 == wlan0, on test device)
71 nudState.toLEHex() + // NUD state
72 "00" + // flags
73 "01" + // type
74 // -- struct nlattr: NDA_DST --
75 // length = 20 or 8:
76 (if (neighAddr is Inet6Address) "1400" else "0800") +
77 "0100" + // type (1 == NDA_DST, for neighbor messages)
78 // IP address:
79 encodeToString(neighAddr.address) +
80 // -- struct nlattr: NDA_LLADDR --
81 "0a00" + // length = 10
82 "0200" + // type (2 == NDA_LLADDR, for neighbor messages)
83 "00005e000164" + // MAC Address (== 00:00:5e:00:01:64)
84 "0000" + // padding, for 4 byte alignment
85 // -- struct nlattr: NDA_PROBES --
86 "0800" + // length = 8
87 "0400" + // type (4 == NDA_PROBES, for neighbor messages)
88 "01000000" + // number of probes
89 // -- struct nlattr: NDA_CACHEINFO --
90 "1400" + // length = 20
91 "0300" + // type (3 == NDA_CACHEINFO, for neighbor messages)
92 "05190000" + // ndm_used, as "clock ticks ago"
93 "05190000" + // ndm_confirmed, as "clock ticks ago"
94 "190d0000" + // ndm_updated, as "clock ticks ago"
95 "00000000", // ndm_refcnt
96 false /* allowSingleChar */)
97 /* ktlint-enable indent */
98
99 /**
100 * Convert a [Short] to a little-endian hex string.
101 */
102 private fun Short.toLEHex() = String.format("%04x", java.lang.Short.reverseBytes(this))
103