github.com/nicocha30/gvisor-ligolo@v0.0.0-20230726075806-989fa2c0a413/pkg/tcpip/header/ndp_router_advert.go (about) 1 // Copyright 2019 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package header 16 17 import ( 18 "encoding/binary" 19 "fmt" 20 "time" 21 ) 22 23 var _ fmt.Stringer = NDPRoutePreference(0) 24 25 // NDPRoutePreference is the preference values for default routers or 26 // more-specific routes. 27 // 28 // As per RFC 4191 section 2.1, 29 // 30 // Default router preferences and preferences for more-specific routes 31 // are encoded the same way. 32 // 33 // Preference values are encoded as a two-bit signed integer, as 34 // follows: 35 // 36 // 01 High 37 // 00 Medium (default) 38 // 11 Low 39 // 10 Reserved - MUST NOT be sent 40 // 41 // Note that implementations can treat the value as a two-bit signed 42 // integer. 43 // 44 // Having just three values reinforces that they are not metrics and 45 // more values do not appear to be necessary for reasonable scenarios. 46 type NDPRoutePreference uint8 47 48 const ( 49 // HighRoutePreference indicates a high preference, as per 50 // RFC 4191 section 2.1. 51 HighRoutePreference NDPRoutePreference = 0b01 52 53 // MediumRoutePreference indicates a medium preference, as per 54 // RFC 4191 section 2.1. 55 // 56 // This is the default preference value. 57 MediumRoutePreference = 0b00 58 59 // LowRoutePreference indicates a low preference, as per 60 // RFC 4191 section 2.1. 61 LowRoutePreference = 0b11 62 63 // ReservedRoutePreference is a reserved preference value, as per 64 // RFC 4191 section 2.1. 65 // 66 // It MUST NOT be sent. 67 ReservedRoutePreference = 0b10 68 ) 69 70 // String implements fmt.Stringer. 71 func (p NDPRoutePreference) String() string { 72 switch p { 73 case HighRoutePreference: 74 return "HighRoutePreference" 75 case MediumRoutePreference: 76 return "MediumRoutePreference" 77 case LowRoutePreference: 78 return "LowRoutePreference" 79 case ReservedRoutePreference: 80 return "ReservedRoutePreference" 81 default: 82 return fmt.Sprintf("NDPRoutePreference(%d)", p) 83 } 84 } 85 86 // NDPRouterAdvert is an NDP Router Advertisement message. It will only contain 87 // the body of an ICMPv6 packet. 88 // 89 // See RFC 4861 section 4.2 and RFC 4191 section 2.2 for more details. 90 type NDPRouterAdvert []byte 91 92 // As per RFC 4191 section 2.2, 93 // 94 // 0 1 2 3 95 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 96 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 97 // | Type | Code | Checksum | 98 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 99 // | Cur Hop Limit |M|O|H|Prf|Resvd| Router Lifetime | 100 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 101 // | Reachable Time | 102 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 103 // | Retrans Timer | 104 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 105 // | Options ... 106 // +-+-+-+-+-+-+-+-+-+-+-+- 107 const ( 108 // NDPRAMinimumSize is the minimum size of a valid NDP Router 109 // Advertisement message (body of an ICMPv6 packet). 110 NDPRAMinimumSize = 12 111 112 // ndpRACurrHopLimitOffset is the byte of the Curr Hop Limit field 113 // within an NDPRouterAdvert. 114 ndpRACurrHopLimitOffset = 0 115 116 // ndpRAFlagsOffset is the byte with the NDP RA bit-fields/flags 117 // within an NDPRouterAdvert. 118 ndpRAFlagsOffset = 1 119 120 // ndpRAManagedAddrConfFlagMask is the mask of the Managed Address 121 // Configuration flag within the bit-field/flags byte of an 122 // NDPRouterAdvert. 123 ndpRAManagedAddrConfFlagMask = (1 << 7) 124 125 // ndpRAOtherConfFlagMask is the mask of the Other Configuration flag 126 // within the bit-field/flags byte of an NDPRouterAdvert. 127 ndpRAOtherConfFlagMask = (1 << 6) 128 129 // ndpDefaultRouterPreferenceShift is the shift of the Prf (Default Router 130 // Preference) field within the flags byte of an NDPRouterAdvert. 131 ndpDefaultRouterPreferenceShift = 3 132 133 // ndpDefaultRouterPreferenceMask is the mask of the Prf (Default Router 134 // Preference) field within the flags byte of an NDPRouterAdvert. 135 ndpDefaultRouterPreferenceMask = (0b11 << ndpDefaultRouterPreferenceShift) 136 137 // ndpRARouterLifetimeOffset is the start of the 2-byte Router Lifetime 138 // field within an NDPRouterAdvert. 139 ndpRARouterLifetimeOffset = 2 140 141 // ndpRAReachableTimeOffset is the start of the 4-byte Reachable Time 142 // field within an NDPRouterAdvert. 143 ndpRAReachableTimeOffset = 4 144 145 // ndpRARetransTimerOffset is the start of the 4-byte Retrans Timer 146 // field within an NDPRouterAdvert. 147 ndpRARetransTimerOffset = 8 148 149 // ndpRAOptionsOffset is the start of the NDP options in an 150 // NDPRouterAdvert. 151 ndpRAOptionsOffset = 12 152 ) 153 154 // CurrHopLimit returns the value of the Curr Hop Limit field. 155 func (b NDPRouterAdvert) CurrHopLimit() uint8 { 156 return b[ndpRACurrHopLimitOffset] 157 } 158 159 // ManagedAddrConfFlag returns the value of the Managed Address Configuration 160 // flag. 161 func (b NDPRouterAdvert) ManagedAddrConfFlag() bool { 162 return b[ndpRAFlagsOffset]&ndpRAManagedAddrConfFlagMask != 0 163 } 164 165 // OtherConfFlag returns the value of the Other Configuration flag. 166 func (b NDPRouterAdvert) OtherConfFlag() bool { 167 return b[ndpRAFlagsOffset]&ndpRAOtherConfFlagMask != 0 168 } 169 170 // DefaultRouterPreference returns the Default Router Preference field. 171 func (b NDPRouterAdvert) DefaultRouterPreference() NDPRoutePreference { 172 return NDPRoutePreference((b[ndpRAFlagsOffset] & ndpDefaultRouterPreferenceMask) >> ndpDefaultRouterPreferenceShift) 173 } 174 175 // RouterLifetime returns the lifetime associated with the default router. A 176 // value of 0 means the source of the Router Advertisement is not a default 177 // router and SHOULD NOT appear on the default router list. Note, a value of 0 178 // only means that the router should not be used as a default router, it does 179 // not apply to other information contained in the Router Advertisement. 180 func (b NDPRouterAdvert) RouterLifetime() time.Duration { 181 // The field is the time in seconds, as per RFC 4861 section 4.2. 182 return time.Second * time.Duration(binary.BigEndian.Uint16(b[ndpRARouterLifetimeOffset:])) 183 } 184 185 // ReachableTime returns the time that a node assumes a neighbor is reachable 186 // after having received a reachability confirmation. A value of 0 means 187 // that it is unspecified by the source of the Router Advertisement message. 188 func (b NDPRouterAdvert) ReachableTime() time.Duration { 189 // The field is the time in milliseconds, as per RFC 4861 section 4.2. 190 return time.Millisecond * time.Duration(binary.BigEndian.Uint32(b[ndpRAReachableTimeOffset:])) 191 } 192 193 // RetransTimer returns the time between retransmitted Neighbor Solicitation 194 // messages. A value of 0 means that it is unspecified by the source of the 195 // Router Advertisement message. 196 func (b NDPRouterAdvert) RetransTimer() time.Duration { 197 // The field is the time in milliseconds, as per RFC 4861 section 4.2. 198 return time.Millisecond * time.Duration(binary.BigEndian.Uint32(b[ndpRARetransTimerOffset:])) 199 } 200 201 // Options returns an NDPOptions of the the options body. 202 func (b NDPRouterAdvert) Options() NDPOptions { 203 return NDPOptions(b[ndpRAOptionsOffset:]) 204 }