blob: 3f5460bf9727f179b34959b2c04c0cd4503aae60 [file] [log] [blame]
/*
* Copyright (C) 2020 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.
*/
@file:JvmName("NetlinkTestUtils")
package com.android.testutils
import com.android.net.module.util.netlink.NetlinkConstants.RTM_DELNEIGH
import com.android.net.module.util.netlink.NetlinkConstants.RTM_NEWNEIGH
import libcore.util.HexEncoding
import libcore.util.HexEncoding.encodeToString
import java.net.Inet6Address
import java.net.InetAddress
private const val VRRP_MAC_ADDR = "00005e000164"
/**
* Make a RTM_NEWNEIGH netlink message.
*/
@JvmOverloads
fun makeNewNeighMessage(
neighAddr: InetAddress,
nudState: Short,
linkLayerAddr: String = VRRP_MAC_ADDR
) = makeNeighborMessage(
neighAddr = neighAddr,
type = RTM_NEWNEIGH,
nudState = nudState,
linkLayerAddr = linkLayerAddr
)
/**
* Make a RTM_DELNEIGH netlink message.
*/
fun makeDelNeighMessage(
neighAddr: InetAddress,
nudState: Short
) = makeNeighborMessage(
neighAddr = neighAddr,
type = RTM_DELNEIGH,
nudState = nudState
)
private fun makeNeighborMessage(
neighAddr: InetAddress,
type: Short,
nudState: Short,
linkLayerAddr: String = VRRP_MAC_ADDR
) = HexEncoding.decode(
/* ktlint-disable indent */
// -- struct nlmsghdr --
// length = 88 or 76:
(if (neighAddr is Inet6Address) "58000000" else "4c000000") +
type.toLEHex() + // type
"0000" + // flags
"00000000" + // seqno
"00000000" + // pid (0 == kernel)
// struct ndmsg
// family (AF_INET6 or AF_INET)
(if (neighAddr is Inet6Address) "0a" else "02") +
"00" + // pad1
"0000" + // pad2
"15000000" + // interface index (21 == wlan0, on test device)
nudState.toLEHex() + // NUD state
"00" + // flags
"01" + // type
// -- struct nlattr: NDA_DST --
// length = 20 or 8:
(if (neighAddr is Inet6Address) "1400" else "0800") +
"0100" + // type (1 == NDA_DST, for neighbor messages)
// IP address:
encodeToString(neighAddr.address) +
// -- struct nlattr: NDA_LLADDR --
"0a00" + // length = 10
"0200" + // type (2 == NDA_LLADDR, for neighbor messages)
linkLayerAddr + // MAC Address(default == 00:00:5e:00:01:64)
"0000" + // padding, for 4 byte alignment
// -- struct nlattr: NDA_PROBES --
"0800" + // length = 8
"0400" + // type (4 == NDA_PROBES, for neighbor messages)
"01000000" + // number of probes
// -- struct nlattr: NDA_CACHEINFO --
"1400" + // length = 20
"0300" + // type (3 == NDA_CACHEINFO, for neighbor messages)
"05190000" + // ndm_used, as "clock ticks ago"
"05190000" + // ndm_confirmed, as "clock ticks ago"
"190d0000" + // ndm_updated, as "clock ticks ago"
"00000000", // ndm_refcnt
false /* allowSingleChar */)
/* ktlint-enable indent */
/**
* Convert a [Short] to a little-endian hex string.
*/
private fun Short.toLEHex() = String.format("%04x", java.lang.Short.reverseBytes(this))