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 */ 31 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