interface.rs 140 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779
  1. // Heads up! Before working on this file you should read the parts
  2. // of RFC 1122 that discuss Ethernet, ARP and IP for any IPv4 work
  3. // and RFCs 8200 and 4861 for any IPv6 and NDISC work.
  4. use core::cmp;
  5. use managed::{ManagedMap, ManagedSlice};
  6. #[allow(unused)]
  7. #[cfg(feature = "proto-sixlowpan")]
  8. use super::fragmentation::PacketAssemblerSet;
  9. use super::socket_set::SocketSet;
  10. use crate::iface::Routes;
  11. #[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
  12. use crate::iface::{NeighborAnswer, NeighborCache};
  13. use crate::phy::{ChecksumCapabilities, Device, DeviceCapabilities, Medium, RxToken, TxToken};
  14. use crate::rand::Rand;
  15. #[cfg(feature = "socket-dhcpv4")]
  16. use crate::socket::dhcpv4;
  17. #[cfg(feature = "socket-dns")]
  18. use crate::socket::dns;
  19. use crate::socket::*;
  20. use crate::time::{Duration, Instant};
  21. use crate::wire::*;
  22. use crate::{Error, Result};
  23. macro_rules! check {
  24. ($e:expr) => {
  25. match $e {
  26. Ok(x) => x,
  27. Err(_) => {
  28. // concat!/stringify! doesn't work with defmt macros
  29. #[cfg(not(feature = "defmt"))]
  30. net_trace!(concat!("iface: malformed ", stringify!($e)));
  31. #[cfg(feature = "defmt")]
  32. net_trace!("iface: malformed");
  33. return Default::default();
  34. }
  35. }
  36. };
  37. }
  38. /// A network interface.
  39. ///
  40. /// The network interface logically owns a number of other data structures; to avoid
  41. /// a dependency on heap allocation, it instead owns a `BorrowMut<[T]>`, which can be
  42. /// a `&mut [T]`, or `Vec<T>` if a heap is available.
  43. pub struct Interface<'a> {
  44. caps: DeviceCapabilities,
  45. now: Instant,
  46. #[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
  47. neighbor_cache: Option<NeighborCache<'a>>,
  48. #[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
  49. hardware_addr: Option<HardwareAddress>,
  50. #[cfg(feature = "medium-ieee802154")]
  51. sequence_no: u8,
  52. #[cfg(feature = "medium-ieee802154")]
  53. pan_id: Option<Ieee802154Pan>,
  54. ip_addrs: ManagedSlice<'a, IpCidr>,
  55. #[cfg(feature = "proto-ipv4")]
  56. any_ip: bool,
  57. routes: Routes<'a>,
  58. #[cfg(feature = "proto-igmp")]
  59. ipv4_multicast_groups: ManagedMap<'a, Ipv4Address, ()>,
  60. /// When to report for (all or) the next multicast group membership via IGMP
  61. #[cfg(feature = "proto-igmp")]
  62. igmp_report_state: IgmpReportState,
  63. rand: Rand,
  64. }
  65. /// A builder structure used for creating a network interface.
  66. pub struct InterfaceBuilder<'a> {
  67. #[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
  68. hardware_addr: Option<HardwareAddress>,
  69. #[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
  70. neighbor_cache: Option<NeighborCache<'a>>,
  71. #[cfg(feature = "medium-ieee802154")]
  72. pan_id: Option<Ieee802154Pan>,
  73. ip_addrs: ManagedSlice<'a, IpCidr>,
  74. #[cfg(feature = "proto-ipv4")]
  75. any_ip: bool,
  76. routes: Routes<'a>,
  77. /// Does not share storage with `ipv6_multicast_groups` to avoid IPv6 size overhead.
  78. #[cfg(feature = "proto-igmp")]
  79. ipv4_multicast_groups: ManagedMap<'a, Ipv4Address, ()>,
  80. random_seed: u64,
  81. }
  82. impl<'a> InterfaceBuilder<'a> {
  83. /// Create a builder used for creating a network interface using the
  84. /// given device and address.
  85. #[cfg_attr(
  86. feature = "medium-ethernet",
  87. doc = r##"
  88. # Examples
  89. ```
  90. # use std::collections::BTreeMap;
  91. use smoltcp::iface::{InterfaceBuilder, NeighborCache};
  92. # use smoltcp::phy::{Loopback, Medium};
  93. use smoltcp::wire::{EthernetAddress, IpCidr, IpAddress};
  94. let mut device = // ...
  95. # Loopback::new(Medium::Ethernet);
  96. let hw_addr = // ...
  97. # EthernetAddress::default();
  98. let neighbor_cache = // ...
  99. # NeighborCache::new(BTreeMap::new());
  100. let ip_addrs = // ...
  101. # [];
  102. let iface = InterfaceBuilder::new()
  103. .hardware_addr(hw_addr.into())
  104. .neighbor_cache(neighbor_cache)
  105. .ip_addrs(ip_addrs)
  106. .finalize(&mut device);
  107. ```
  108. "##
  109. )]
  110. #[allow(clippy::new_without_default)]
  111. pub fn new() -> Self {
  112. InterfaceBuilder {
  113. #[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
  114. hardware_addr: None,
  115. #[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
  116. neighbor_cache: None,
  117. #[cfg(feature = "medium-ieee802154")]
  118. pan_id: None,
  119. ip_addrs: ManagedSlice::Borrowed(&mut []),
  120. #[cfg(feature = "proto-ipv4")]
  121. any_ip: false,
  122. routes: Routes::new(ManagedMap::Borrowed(&mut [])),
  123. #[cfg(feature = "proto-igmp")]
  124. ipv4_multicast_groups: ManagedMap::Borrowed(&mut []),
  125. random_seed: 0,
  126. }
  127. }
  128. /// Set the random seed for this interface.
  129. ///
  130. /// It is strongly recommended that the random seed is different on each boot,
  131. /// to avoid problems with TCP port/sequence collisions.
  132. ///
  133. /// The seed doesn't have to be cryptographically secure.
  134. pub fn random_seed(mut self, random_seed: u64) -> Self {
  135. self.random_seed = random_seed;
  136. self
  137. }
  138. /// Set the Hardware address the interface will use. See also
  139. /// [hardware_addr].
  140. ///
  141. /// # Panics
  142. /// This function panics if the address is not unicast.
  143. ///
  144. /// [hardware_addr]: struct.Interface.html#method.hardware_addr
  145. #[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
  146. pub fn hardware_addr(mut self, addr: HardwareAddress) -> Self {
  147. Interface::check_hardware_addr(&addr);
  148. self.hardware_addr = Some(addr);
  149. self
  150. }
  151. /// Set the IEEE802.15.4 PAN ID the interface will use.
  152. ///
  153. /// **NOTE**: we use the same PAN ID for destination and source.
  154. #[cfg(feature = "medium-ieee802154")]
  155. pub fn pan_id(mut self, pan_id: Ieee802154Pan) -> Self {
  156. self.pan_id = Some(pan_id);
  157. self
  158. }
  159. /// Set the IP addresses the interface will use. See also
  160. /// [ip_addrs].
  161. ///
  162. /// # Panics
  163. /// This function panics if any of the addresses are not unicast.
  164. ///
  165. /// [ip_addrs]: struct.Interface.html#method.ip_addrs
  166. pub fn ip_addrs<T>(mut self, ip_addrs: T) -> Self
  167. where
  168. T: Into<ManagedSlice<'a, IpCidr>>,
  169. {
  170. let ip_addrs = ip_addrs.into();
  171. Interface::check_ip_addrs(&ip_addrs);
  172. self.ip_addrs = ip_addrs;
  173. self
  174. }
  175. /// Enable or disable the AnyIP capability, allowing packets to be received
  176. /// locally on IPv4 addresses other than the interface's configured [ip_addrs].
  177. /// When AnyIP is enabled and a route prefix in [routes] specifies one of
  178. /// the interface's [ip_addrs] as its gateway, the interface will accept
  179. /// packets addressed to that prefix.
  180. ///
  181. /// # IPv6
  182. ///
  183. /// This option is not available or required for IPv6 as packets sent to
  184. /// the interface are not filtered by IPv6 address.
  185. ///
  186. /// [routes]: struct.Interface.html#method.routes
  187. /// [ip_addrs]: struct.Interface.html#method.ip_addrs
  188. #[cfg(feature = "proto-ipv4")]
  189. pub fn any_ip(mut self, enabled: bool) -> Self {
  190. self.any_ip = enabled;
  191. self
  192. }
  193. /// Set the IP routes the interface will use. See also
  194. /// [routes].
  195. ///
  196. /// [routes]: struct.Interface.html#method.routes
  197. pub fn routes<T>(mut self, routes: T) -> InterfaceBuilder<'a>
  198. where
  199. T: Into<Routes<'a>>,
  200. {
  201. self.routes = routes.into();
  202. self
  203. }
  204. /// Provide storage for multicast groups.
  205. ///
  206. /// Join multicast groups by calling [`join_multicast_group()`] on an `Interface`.
  207. /// Using [`join_multicast_group()`] will send initial membership reports.
  208. ///
  209. /// A previously destroyed interface can be recreated by reusing the multicast group
  210. /// storage, i.e. providing a non-empty storage to `ipv4_multicast_groups()`.
  211. /// Note that this way initial membership reports are **not** sent.
  212. ///
  213. /// [`join_multicast_group()`]: struct.Interface.html#method.join_multicast_group
  214. #[cfg(feature = "proto-igmp")]
  215. pub fn ipv4_multicast_groups<T>(mut self, ipv4_multicast_groups: T) -> Self
  216. where
  217. T: Into<ManagedMap<'a, Ipv4Address, ()>>,
  218. {
  219. self.ipv4_multicast_groups = ipv4_multicast_groups.into();
  220. self
  221. }
  222. /// Set the Neighbor Cache the interface will use.
  223. #[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
  224. pub fn neighbor_cache(mut self, neighbor_cache: NeighborCache<'a>) -> Self {
  225. self.neighbor_cache = Some(neighbor_cache);
  226. self
  227. }
  228. /// Create a network interface using the previously provided configuration.
  229. ///
  230. /// # Panics
  231. /// If a required option is not provided, this function will panic. Required
  232. /// options are:
  233. ///
  234. /// - [ethernet_addr]
  235. /// - [neighbor_cache]
  236. ///
  237. /// [ethernet_addr]: #method.ethernet_addr
  238. /// [neighbor_cache]: #method.neighbor_cache
  239. pub fn finalize<D>(self, device: &mut D) -> Interface<'a>
  240. where
  241. D: for<'d> Device<'d>,
  242. {
  243. let caps = device.capabilities();
  244. #[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
  245. let (hardware_addr, neighbor_cache) = match caps.medium {
  246. #[cfg(feature = "medium-ethernet")]
  247. Medium::Ethernet => (
  248. Some(
  249. self.hardware_addr
  250. .expect("hardware_addr required option was not set"),
  251. ),
  252. Some(
  253. self.neighbor_cache
  254. .expect("neighbor_cache required option was not set"),
  255. ),
  256. ),
  257. #[cfg(feature = "medium-ip")]
  258. Medium::Ip => {
  259. assert!(
  260. self.hardware_addr.is_none(),
  261. "hardware_addr is set, but device medium is IP"
  262. );
  263. assert!(
  264. self.neighbor_cache.is_none(),
  265. "neighbor_cache is set, but device medium is IP"
  266. );
  267. (None, None)
  268. }
  269. #[cfg(feature = "medium-ieee802154")]
  270. Medium::Ieee802154 => (
  271. Some(
  272. self.hardware_addr
  273. .expect("hardware_addr required option was not set"),
  274. ),
  275. Some(
  276. self.neighbor_cache
  277. .expect("neighbor_cache required option was not set"),
  278. ),
  279. ),
  280. };
  281. #[cfg(feature = "medium-ieee802154")]
  282. let mut rand = Rand::new(self.random_seed);
  283. #[cfg(not(feature = "medium-ieee802154"))]
  284. let rand = Rand::new(self.random_seed);
  285. #[cfg(feature = "medium-ieee802154")]
  286. let mut sequence_no;
  287. #[cfg(feature = "medium-ieee802154")]
  288. loop {
  289. sequence_no = (rand.rand_u32() & 0xff) as u8;
  290. if sequence_no != 0 {
  291. break;
  292. }
  293. }
  294. Interface {
  295. now: Instant::from_secs(0),
  296. caps,
  297. #[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
  298. hardware_addr,
  299. ip_addrs: self.ip_addrs,
  300. #[cfg(feature = "proto-ipv4")]
  301. any_ip: self.any_ip,
  302. routes: self.routes,
  303. #[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
  304. neighbor_cache,
  305. #[cfg(feature = "proto-igmp")]
  306. ipv4_multicast_groups: self.ipv4_multicast_groups,
  307. #[cfg(feature = "proto-igmp")]
  308. igmp_report_state: IgmpReportState::Inactive,
  309. #[cfg(feature = "medium-ieee802154")]
  310. sequence_no,
  311. #[cfg(feature = "medium-ieee802154")]
  312. pan_id: self.pan_id,
  313. rand,
  314. }
  315. }
  316. }
  317. #[derive(Debug, PartialEq)]
  318. #[cfg_attr(feature = "defmt", derive(defmt::Format))]
  319. #[cfg(feature = "medium-ethernet")]
  320. enum EthernetPacket<'a> {
  321. #[cfg(feature = "proto-ipv4")]
  322. Arp(ArpRepr),
  323. Ip(IpPacket<'a>),
  324. }
  325. #[derive(Debug, PartialEq)]
  326. #[cfg_attr(feature = "defmt", derive(defmt::Format))]
  327. pub(crate) enum IpPacket<'a> {
  328. #[cfg(feature = "proto-ipv4")]
  329. Icmpv4((Ipv4Repr, Icmpv4Repr<'a>)),
  330. #[cfg(feature = "proto-igmp")]
  331. Igmp((Ipv4Repr, IgmpRepr)),
  332. #[cfg(feature = "proto-ipv6")]
  333. Icmpv6((Ipv6Repr, Icmpv6Repr<'a>)),
  334. #[cfg(feature = "socket-raw")]
  335. Raw((IpRepr, &'a [u8])),
  336. #[cfg(any(feature = "socket-udp", feature = "socket-dns"))]
  337. Udp((IpRepr, UdpRepr, &'a [u8])),
  338. #[cfg(feature = "socket-tcp")]
  339. Tcp((IpRepr, TcpRepr<'a>)),
  340. #[cfg(feature = "socket-dhcpv4")]
  341. Dhcpv4((Ipv4Repr, UdpRepr, DhcpRepr<'a>)),
  342. }
  343. impl<'a> IpPacket<'a> {
  344. pub(crate) fn ip_repr(&self) -> IpRepr {
  345. match self {
  346. #[cfg(feature = "proto-ipv4")]
  347. IpPacket::Icmpv4((ipv4_repr, _)) => IpRepr::Ipv4(*ipv4_repr),
  348. #[cfg(feature = "proto-igmp")]
  349. IpPacket::Igmp((ipv4_repr, _)) => IpRepr::Ipv4(*ipv4_repr),
  350. #[cfg(feature = "proto-ipv6")]
  351. IpPacket::Icmpv6((ipv6_repr, _)) => IpRepr::Ipv6(*ipv6_repr),
  352. #[cfg(feature = "socket-raw")]
  353. IpPacket::Raw((ip_repr, _)) => ip_repr.clone(),
  354. #[cfg(any(feature = "socket-udp", feature = "socket-dns"))]
  355. IpPacket::Udp((ip_repr, _, _)) => ip_repr.clone(),
  356. #[cfg(feature = "socket-tcp")]
  357. IpPacket::Tcp((ip_repr, _)) => ip_repr.clone(),
  358. #[cfg(feature = "socket-dhcpv4")]
  359. IpPacket::Dhcpv4((ipv4_repr, _, _)) => IpRepr::Ipv4(*ipv4_repr),
  360. }
  361. }
  362. pub(crate) fn emit_payload(
  363. &self,
  364. _ip_repr: IpRepr,
  365. payload: &mut [u8],
  366. caps: &DeviceCapabilities,
  367. ) {
  368. match self {
  369. #[cfg(feature = "proto-ipv4")]
  370. IpPacket::Icmpv4((_, icmpv4_repr)) => {
  371. icmpv4_repr.emit(&mut Icmpv4Packet::new_unchecked(payload), &caps.checksum)
  372. }
  373. #[cfg(feature = "proto-igmp")]
  374. IpPacket::Igmp((_, igmp_repr)) => {
  375. igmp_repr.emit(&mut IgmpPacket::new_unchecked(payload))
  376. }
  377. #[cfg(feature = "proto-ipv6")]
  378. IpPacket::Icmpv6((_, icmpv6_repr)) => icmpv6_repr.emit(
  379. &_ip_repr.src_addr(),
  380. &_ip_repr.dst_addr(),
  381. &mut Icmpv6Packet::new_unchecked(payload),
  382. &caps.checksum,
  383. ),
  384. #[cfg(feature = "socket-raw")]
  385. IpPacket::Raw((_, raw_packet)) => payload.copy_from_slice(raw_packet),
  386. #[cfg(any(feature = "socket-udp", feature = "socket-dns"))]
  387. IpPacket::Udp((_, udp_repr, iface_payload)) => udp_repr.emit(
  388. &mut UdpPacket::new_unchecked(payload),
  389. &_ip_repr.src_addr(),
  390. &_ip_repr.dst_addr(),
  391. iface_payload.len(),
  392. |buf| buf.copy_from_slice(iface_payload),
  393. &caps.checksum,
  394. ),
  395. #[cfg(feature = "socket-tcp")]
  396. IpPacket::Tcp((_, mut tcp_repr)) => {
  397. // This is a terrible hack to make TCP performance more acceptable on systems
  398. // where the TCP buffers are significantly larger than network buffers,
  399. // e.g. a 64 kB TCP receive buffer (and so, when empty, a 64k window)
  400. // together with four 1500 B Ethernet receive buffers. If left untreated,
  401. // this would result in our peer pushing our window and sever packet loss.
  402. //
  403. // I'm really not happy about this "solution" but I don't know what else to do.
  404. if let Some(max_burst_size) = caps.max_burst_size {
  405. let mut max_segment_size = caps.max_transmission_unit;
  406. max_segment_size -= _ip_repr.buffer_len();
  407. max_segment_size -= tcp_repr.header_len();
  408. let max_window_size = max_burst_size * max_segment_size;
  409. if tcp_repr.window_len as usize > max_window_size {
  410. tcp_repr.window_len = max_window_size as u16;
  411. }
  412. }
  413. tcp_repr.emit(
  414. &mut TcpPacket::new_unchecked(payload),
  415. &_ip_repr.src_addr(),
  416. &_ip_repr.dst_addr(),
  417. &caps.checksum,
  418. );
  419. }
  420. #[cfg(feature = "socket-dhcpv4")]
  421. IpPacket::Dhcpv4((_, udp_repr, dhcp_repr)) => udp_repr.emit(
  422. &mut UdpPacket::new_unchecked(payload),
  423. &_ip_repr.src_addr(),
  424. &_ip_repr.dst_addr(),
  425. dhcp_repr.buffer_len(),
  426. |buf| dhcp_repr.emit(&mut DhcpPacket::new_unchecked(buf)).unwrap(),
  427. &caps.checksum,
  428. ),
  429. }
  430. }
  431. }
  432. #[cfg(any(feature = "proto-ipv4", feature = "proto-ipv6"))]
  433. fn icmp_reply_payload_len(len: usize, mtu: usize, header_len: usize) -> usize {
  434. // Send back as much of the original payload as will fit within
  435. // the minimum MTU required by IPv4. See RFC 1812 § 4.3.2.3 for
  436. // more details.
  437. //
  438. // Since the entire network layer packet must fit within the minimum
  439. // MTU supported, the payload must not exceed the following:
  440. //
  441. // <min mtu> - IP Header Size * 2 - ICMPv4 DstUnreachable hdr size
  442. cmp::min(len, mtu - header_len * 2 - 8)
  443. }
  444. #[cfg(feature = "proto-igmp")]
  445. enum IgmpReportState {
  446. Inactive,
  447. ToGeneralQuery {
  448. version: IgmpVersion,
  449. timeout: Instant,
  450. interval: Duration,
  451. next_index: usize,
  452. },
  453. ToSpecificQuery {
  454. version: IgmpVersion,
  455. timeout: Instant,
  456. group: Ipv4Address,
  457. },
  458. }
  459. impl<'a> Interface<'a> {
  460. /// Get the HardwareAddress address of the interface.
  461. ///
  462. /// # Panics
  463. /// This function panics if the medium is not Ethernet or Ieee802154.
  464. #[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
  465. pub fn hardware_addr(&self) -> HardwareAddress {
  466. #[cfg(all(feature = "medium-ethernet", not(feature = "medium-ieee802154")))]
  467. assert!(self.caps.medium == Medium::Ethernet);
  468. #[cfg(all(feature = "medium-ieee802154", not(feature = "medium-ethernet")))]
  469. assert!(self.caps.medium == Medium::Ieee802154);
  470. #[cfg(all(feature = "medium-ieee802154", feature = "medium-ethernet"))]
  471. assert!(self.caps.medium == Medium::Ethernet || self.caps.medium == Medium::Ieee802154);
  472. self.hardware_addr.unwrap()
  473. }
  474. /// Set the HardwareAddress address of the interface.
  475. ///
  476. /// # Panics
  477. /// This function panics if the address is not unicast, and if the medium is not Ethernet or
  478. /// Ieee802154.
  479. #[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
  480. pub fn set_hardware_addr(&mut self, addr: HardwareAddress) {
  481. #[cfg(all(feature = "medium-ethernet", not(feature = "medium-ieee802154")))]
  482. assert!(self.caps.medium == Medium::Ethernet);
  483. #[cfg(all(feature = "medium-ieee802154", not(feature = "medium-ethernet")))]
  484. assert!(self.caps.medium == Medium::Ieee802154);
  485. #[cfg(all(feature = "medium-ieee802154", feature = "medium-ethernet"))]
  486. assert!(self.caps.medium == Medium::Ethernet || self.caps.medium == Medium::Ieee802154);
  487. Self::check_hardware_addr(&addr);
  488. self.hardware_addr = Some(addr);
  489. }
  490. /// Add an address to a list of subscribed multicast IP addresses.
  491. ///
  492. /// Returns `Ok(announce_sent)` if the address was added successfully, where `annouce_sent`
  493. /// indicates whether an initial immediate announcement has been sent.
  494. pub fn join_multicast_group<D, T: Into<IpAddress>>(
  495. &mut self,
  496. device: &mut D,
  497. addr: T,
  498. timestamp: Instant,
  499. ) -> Result<bool>
  500. where
  501. D: for<'d> Device<'d>,
  502. {
  503. self.now = timestamp;
  504. match addr.into() {
  505. #[cfg(feature = "proto-igmp")]
  506. IpAddress::Ipv4(addr) => {
  507. let is_not_new = self
  508. .ipv4_multicast_groups
  509. .insert(addr, ())
  510. .map_err(|_| Error::Exhausted)?
  511. .is_some();
  512. if is_not_new {
  513. Ok(false)
  514. } else if let Some(pkt) = self.igmp_report_packet(IgmpVersion::Version2, addr) {
  515. // Send initial membership report
  516. let tx_token = device.transmit().ok_or(Error::Exhausted)?;
  517. self.dispatch_ip(tx_token, pkt)?;
  518. Ok(true)
  519. } else {
  520. Ok(false)
  521. }
  522. }
  523. // Multicast is not yet implemented for other address families
  524. #[allow(unreachable_patterns)]
  525. _ => Err(Error::Unaddressable),
  526. }
  527. }
  528. /// Remove an address from the subscribed multicast IP addresses.
  529. ///
  530. /// Returns `Ok(leave_sent)` if the address was removed successfully, where `leave_sent`
  531. /// indicates whether an immediate leave packet has been sent.
  532. pub fn leave_multicast_group<D, T: Into<IpAddress>>(
  533. &mut self,
  534. device: &mut D,
  535. addr: T,
  536. timestamp: Instant,
  537. ) -> Result<bool>
  538. where
  539. D: for<'d> Device<'d>,
  540. {
  541. self.now = timestamp;
  542. match addr.into() {
  543. #[cfg(feature = "proto-igmp")]
  544. IpAddress::Ipv4(addr) => {
  545. let was_not_present = self.ipv4_multicast_groups.remove(&addr).is_none();
  546. if was_not_present {
  547. Ok(false)
  548. } else if let Some(pkt) = self.igmp_leave_packet(addr) {
  549. // Send group leave packet
  550. let tx_token = device.transmit().ok_or(Error::Exhausted)?;
  551. self.dispatch_ip(tx_token, pkt)?;
  552. Ok(true)
  553. } else {
  554. Ok(false)
  555. }
  556. }
  557. // Multicast is not yet implemented for other address families
  558. #[allow(unreachable_patterns)]
  559. _ => Err(Error::Unaddressable),
  560. }
  561. }
  562. /// Get the IP addresses of the interface.
  563. pub fn ip_addrs(&self) -> &[IpCidr] {
  564. self.ip_addrs.as_ref()
  565. }
  566. /// Get the first IPv4 address if present.
  567. #[cfg(feature = "proto-ipv4")]
  568. pub fn ipv4_addr(&self) -> Option<Ipv4Address> {
  569. self.ip_addrs()
  570. .iter()
  571. .filter_map(|cidr| match cidr.address() {
  572. IpAddress::Ipv4(addr) => Some(addr),
  573. #[allow(unreachable_patterns)]
  574. _ => None,
  575. })
  576. .next()
  577. }
  578. /// Update the IP addresses of the interface.
  579. ///
  580. /// # Panics
  581. /// This function panics if any of the addresses are not unicast.
  582. pub fn update_ip_addrs<F: FnOnce(&mut ManagedSlice<'a, IpCidr>)>(&mut self, f: F) {
  583. f(&mut self.ip_addrs);
  584. self.flush_cache();
  585. Self::check_ip_addrs(&self.ip_addrs)
  586. }
  587. pub fn routes(&self) -> &Routes<'a> {
  588. &self.routes
  589. }
  590. pub fn routes_mut(&mut self) -> &mut Routes<'a> {
  591. &mut self.routes
  592. }
  593. /// Transmit packets queued in the given sockets, and receive packets queued
  594. /// in the device.
  595. ///
  596. /// This function returns a boolean value indicating whether any packets were
  597. /// processed or emitted, and thus, whether the readiness of any socket might
  598. /// have changed.
  599. ///
  600. /// # Errors
  601. /// This method will routinely return errors in response to normal network
  602. /// activity as well as certain boundary conditions such as buffer exhaustion.
  603. /// These errors are provided as an aid for troubleshooting, and are meant
  604. /// to be logged and ignored.
  605. ///
  606. /// As a special case, `Err(Error::Unrecognized)` is returned in response to
  607. /// packets containing any unsupported protocol, option, or form, which is
  608. /// a very common occurrence and on a production system it should not even
  609. /// be logged.
  610. pub fn poll<D>(
  611. &mut self,
  612. timestamp: Instant,
  613. device: &mut D,
  614. sockets: &mut SocketSet<'_>,
  615. ) -> Result<bool>
  616. where
  617. D: for<'d> Device<'d>,
  618. {
  619. self.now = timestamp;
  620. let mut readiness_may_have_changed = false;
  621. loop {
  622. let processed_any = self.socket_ingress(device, sockets);
  623. let emitted_any = self.socket_egress(device, sockets);
  624. #[cfg(feature = "proto-igmp")]
  625. self.igmp_egress(device)?;
  626. if processed_any || emitted_any {
  627. readiness_may_have_changed = true;
  628. } else {
  629. break;
  630. }
  631. }
  632. Ok(readiness_may_have_changed)
  633. }
  634. /// Return a _soft deadline_ for calling [poll] the next time.
  635. /// The [Instant] returned is the time at which you should call [poll] next.
  636. /// It is harmless (but wastes energy) to call it before the [Instant], and
  637. /// potentially harmful (impacting quality of service) to call it after the
  638. /// [Instant]
  639. ///
  640. /// [poll]: #method.poll
  641. /// [Instant]: struct.Instant.html
  642. pub fn poll_at(&mut self, timestamp: Instant, sockets: &SocketSet<'_>) -> Option<Instant> {
  643. self.now = timestamp;
  644. sockets
  645. .items()
  646. .filter_map(move |item| {
  647. let socket_poll_at = item.socket.poll_at(self);
  648. match item
  649. .meta
  650. .poll_at(socket_poll_at, |ip_addr| self.has_neighbor(&ip_addr))
  651. {
  652. PollAt::Ingress => None,
  653. PollAt::Time(instant) => Some(instant),
  654. PollAt::Now => Some(Instant::from_millis(0)),
  655. }
  656. })
  657. .min()
  658. }
  659. /// Return an _advisory wait time_ for calling [poll] the next time.
  660. /// The [Duration] returned is the time left to wait before calling [poll] next.
  661. /// It is harmless (but wastes energy) to call it before the [Duration] has passed,
  662. /// and potentially harmful (impacting quality of service) to call it after the
  663. /// [Duration] has passed.
  664. ///
  665. /// [poll]: #method.poll
  666. /// [Duration]: struct.Duration.html
  667. pub fn poll_delay(&mut self, timestamp: Instant, sockets: &SocketSet<'_>) -> Option<Duration> {
  668. match self.poll_at(timestamp, sockets) {
  669. Some(poll_at) if timestamp < poll_at => Some(poll_at - timestamp),
  670. Some(_) => Some(Duration::from_millis(0)),
  671. _ => None,
  672. }
  673. }
  674. fn socket_ingress<D>(&mut self, device: &mut D, sockets: &mut SocketSet<'_>) -> bool
  675. where
  676. D: for<'d> Device<'d>,
  677. {
  678. let mut processed_any = false;
  679. while let Some((rx_token, tx_token)) = device.receive() {
  680. let res = rx_token.consume(self.now, |frame| {
  681. match self.caps.medium {
  682. #[cfg(feature = "medium-ethernet")]
  683. Medium::Ethernet => {
  684. if let Some(packet) = self.process_ethernet(sockets, &frame) {
  685. if let Err(err) = self.dispatch(tx_token, packet) {
  686. net_debug!("Failed to send response: {}", err);
  687. }
  688. }
  689. }
  690. #[cfg(feature = "medium-ip")]
  691. Medium::Ip => {
  692. if let Some(packet) = self.process_ip(sockets, &frame) {
  693. if let Err(err) = self.dispatch_ip(tx_token, packet) {
  694. net_debug!("Failed to send response: {}", err);
  695. }
  696. }
  697. }
  698. #[cfg(feature = "medium-ieee802154")]
  699. Medium::Ieee802154 => {
  700. if let Some(packet) = self.process_ieee802154(sockets, &frame) {
  701. if let Err(err) = self.dispatch_ieee802154(tx_token, packet) {
  702. net_debug!("Failed to send response: {}", err);
  703. }
  704. }
  705. }
  706. }
  707. processed_any = true;
  708. Ok(())
  709. });
  710. if let Err(err) = res {
  711. net_debug!("Failed to consume RX token: {}", err);
  712. }
  713. }
  714. processed_any
  715. }
  716. fn socket_egress<D>(&mut self, device: &mut D, sockets: &mut SocketSet<'_>) -> bool
  717. where
  718. D: for<'d> Device<'d>,
  719. {
  720. let mut emitted_any = false;
  721. for item in sockets.items_mut() {
  722. if !item
  723. .meta
  724. .egress_permitted(self.now, |ip_addr| self.has_neighbor(&ip_addr))
  725. {
  726. continue;
  727. }
  728. let mut neighbor_addr = None;
  729. let mut respond = |iface: &mut Interface, response: IpPacket| {
  730. neighbor_addr = Some(response.ip_repr().dst_addr());
  731. let tx_token = device.transmit().ok_or(Error::Exhausted)?;
  732. iface.dispatch_ip(tx_token, response)?;
  733. emitted_any = true;
  734. Ok(())
  735. };
  736. let result = match &mut item.socket {
  737. #[cfg(feature = "socket-raw")]
  738. Socket::Raw(socket) => socket.dispatch(self, |iface, response| {
  739. respond(iface, IpPacket::Raw(response))
  740. }),
  741. #[cfg(feature = "socket-icmp")]
  742. Socket::Icmp(socket) => socket.dispatch(self, |iface, response| match response {
  743. #[cfg(feature = "proto-ipv4")]
  744. (IpRepr::Ipv4(ipv4_repr), IcmpRepr::Ipv4(icmpv4_repr)) => {
  745. respond(iface, IpPacket::Icmpv4((ipv4_repr, icmpv4_repr)))
  746. }
  747. #[cfg(feature = "proto-ipv6")]
  748. (IpRepr::Ipv6(ipv6_repr), IcmpRepr::Ipv6(icmpv6_repr)) => {
  749. respond(iface, IpPacket::Icmpv6((ipv6_repr, icmpv6_repr)))
  750. }
  751. #[allow(unreachable_patterns)]
  752. _ => unreachable!(),
  753. }),
  754. #[cfg(feature = "socket-udp")]
  755. Socket::Udp(socket) => socket.dispatch(self, |iface, response| {
  756. respond(iface, IpPacket::Udp(response))
  757. }),
  758. #[cfg(feature = "socket-tcp")]
  759. Socket::Tcp(socket) => socket.dispatch(self, |iface, response| {
  760. respond(iface, IpPacket::Tcp(response))
  761. }),
  762. #[cfg(feature = "socket-dhcpv4")]
  763. Socket::Dhcpv4(socket) => socket.dispatch(self, |iface, response| {
  764. respond(iface, IpPacket::Dhcpv4(response))
  765. }),
  766. #[cfg(feature = "socket-dns")]
  767. Socket::Dns(ref mut socket) => socket.dispatch(self, |iface, response| {
  768. respond(iface, IpPacket::Udp(response))
  769. }),
  770. };
  771. match result {
  772. Err(Error::Exhausted) => break, // Device buffer full.
  773. Err(Error::Unaddressable) => {
  774. // `NeighborCache` already takes care of rate limiting the neighbor discovery
  775. // requests from the socket. However, without an additional rate limiting
  776. // mechanism, we would spin on every socket that has yet to discover its
  777. // neighbor.
  778. item.meta
  779. .neighbor_missing(self.now, neighbor_addr.expect("non-IP response packet"));
  780. break;
  781. }
  782. Err(err) => {
  783. net_debug!(
  784. "{}: cannot dispatch egress packet: {}",
  785. item.meta.handle,
  786. err
  787. );
  788. }
  789. Ok(()) => {}
  790. }
  791. }
  792. emitted_any
  793. }
  794. /// Depending on `igmp_report_state` and the therein contained
  795. /// timeouts, send IGMP membership reports.
  796. #[cfg(feature = "proto-igmp")]
  797. fn igmp_egress<D>(&mut self, device: &mut D) -> Result<bool>
  798. where
  799. D: for<'d> Device<'d>,
  800. {
  801. match self.igmp_report_state {
  802. IgmpReportState::ToSpecificQuery {
  803. version,
  804. timeout,
  805. group,
  806. } if self.now >= timeout => {
  807. if let Some(pkt) = self.igmp_report_packet(version, group) {
  808. // Send initial membership report
  809. let tx_token = device.transmit().ok_or(Error::Exhausted)?;
  810. self.dispatch_ip(tx_token, pkt)?;
  811. }
  812. self.igmp_report_state = IgmpReportState::Inactive;
  813. Ok(true)
  814. }
  815. IgmpReportState::ToGeneralQuery {
  816. version,
  817. timeout,
  818. interval,
  819. next_index,
  820. } if self.now >= timeout => {
  821. let addr = self
  822. .ipv4_multicast_groups
  823. .iter()
  824. .nth(next_index)
  825. .map(|(addr, ())| *addr);
  826. match addr {
  827. Some(addr) => {
  828. if let Some(pkt) = self.igmp_report_packet(version, addr) {
  829. // Send initial membership report
  830. let tx_token = device.transmit().ok_or(Error::Exhausted)?;
  831. self.dispatch_ip(tx_token, pkt)?;
  832. }
  833. let next_timeout = (timeout + interval).max(self.now);
  834. self.igmp_report_state = IgmpReportState::ToGeneralQuery {
  835. version,
  836. timeout: next_timeout,
  837. interval,
  838. next_index: next_index + 1,
  839. };
  840. Ok(true)
  841. }
  842. None => {
  843. self.igmp_report_state = IgmpReportState::Inactive;
  844. Ok(false)
  845. }
  846. }
  847. }
  848. _ => Ok(false),
  849. }
  850. }
  851. #[allow(unused)] // unused depending on which sockets are enabled
  852. pub(crate) fn now(&self) -> Instant {
  853. self.now
  854. }
  855. #[allow(unused)] // unused depending on which sockets are enabled
  856. pub(crate) fn checksum_caps(&self) -> ChecksumCapabilities {
  857. self.caps.checksum.clone()
  858. }
  859. #[allow(unused)] // unused depending on which sockets are enabled
  860. pub(crate) fn ip_mtu(&self) -> usize {
  861. self.caps.ip_mtu()
  862. }
  863. #[allow(unused)] // unused depending on which sockets are enabled, and in tests
  864. pub(crate) fn rand(&mut self) -> &mut Rand {
  865. &mut self.rand
  866. }
  867. #[allow(unused)] // unused depending on which sockets are enabled
  868. pub(crate) fn get_source_address(&mut self, dst_addr: IpAddress) -> Option<IpAddress> {
  869. let v = dst_addr.version();
  870. for cidr in self.ip_addrs.iter() {
  871. let addr = cidr.address();
  872. if addr.version() == v {
  873. return Some(addr);
  874. }
  875. }
  876. None
  877. }
  878. #[cfg(feature = "proto-ipv4")]
  879. #[allow(unused)]
  880. pub(crate) fn get_source_address_ipv4(
  881. &mut self,
  882. _dst_addr: Ipv4Address,
  883. ) -> Option<Ipv4Address> {
  884. for cidr in self.ip_addrs.iter() {
  885. #[allow(irrefutable_let_patterns)] // if only ipv4 is enabled
  886. if let IpCidr::Ipv4(cidr) = cidr {
  887. return Some(cidr.address());
  888. }
  889. }
  890. None
  891. }
  892. #[cfg(feature = "proto-ipv6")]
  893. #[allow(unused)]
  894. pub(crate) fn get_source_address_ipv6(
  895. &mut self,
  896. _dst_addr: Ipv6Address,
  897. ) -> Option<Ipv6Address> {
  898. for cidr in self.ip_addrs.iter() {
  899. #[allow(irrefutable_let_patterns)] // if only ipv6 is enabled
  900. if let IpCidr::Ipv6(cidr) = cidr {
  901. return Some(cidr.address());
  902. }
  903. }
  904. None
  905. }
  906. #[cfg(test)]
  907. pub(crate) fn mock() -> Self {
  908. Self {
  909. caps: DeviceCapabilities {
  910. #[cfg(feature = "medium-ethernet")]
  911. medium: crate::phy::Medium::Ethernet,
  912. #[cfg(not(feature = "medium-ethernet"))]
  913. medium: crate::phy::Medium::Ip,
  914. checksum: crate::phy::ChecksumCapabilities {
  915. #[cfg(feature = "proto-ipv4")]
  916. icmpv4: crate::phy::Checksum::Both,
  917. #[cfg(feature = "proto-ipv6")]
  918. icmpv6: crate::phy::Checksum::Both,
  919. ipv4: crate::phy::Checksum::Both,
  920. tcp: crate::phy::Checksum::Both,
  921. udp: crate::phy::Checksum::Both,
  922. },
  923. max_burst_size: None,
  924. #[cfg(feature = "medium-ethernet")]
  925. max_transmission_unit: 1514,
  926. #[cfg(not(feature = "medium-ethernet"))]
  927. max_transmission_unit: 1500,
  928. },
  929. now: Instant::from_millis_const(0),
  930. ip_addrs: ManagedSlice::Owned(vec![
  931. #[cfg(feature = "proto-ipv4")]
  932. IpCidr::Ipv4(Ipv4Cidr::new(Ipv4Address::new(192, 168, 1, 1), 24)),
  933. #[cfg(feature = "proto-ipv6")]
  934. IpCidr::Ipv6(Ipv6Cidr::new(
  935. Ipv6Address([0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]),
  936. 64,
  937. )),
  938. ]),
  939. rand: Rand::new(1234),
  940. routes: Routes::new(&mut [][..]),
  941. #[cfg(feature = "proto-ipv4")]
  942. any_ip: false,
  943. #[cfg(feature = "medium-ieee802154")]
  944. pan_id: Some(crate::wire::Ieee802154Pan(0xabcd)),
  945. #[cfg(feature = "medium-ieee802154")]
  946. sequence_no: 0,
  947. #[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
  948. hardware_addr: Some(crate::wire::HardwareAddress::Ethernet(
  949. crate::wire::EthernetAddress([0x02, 0x02, 0x02, 0x02, 0x02, 0x02]),
  950. )),
  951. #[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
  952. neighbor_cache: None,
  953. #[cfg(feature = "proto-igmp")]
  954. igmp_report_state: IgmpReportState::Inactive,
  955. #[cfg(feature = "proto-igmp")]
  956. ipv4_multicast_groups: ManagedMap::Borrowed(&mut []),
  957. }
  958. }
  959. #[cfg(test)]
  960. #[allow(unused)] // unused depending on which sockets are enabled
  961. pub(crate) fn set_now(&mut self, now: Instant) {
  962. self.now = now
  963. }
  964. #[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
  965. fn check_hardware_addr(addr: &HardwareAddress) {
  966. if !addr.is_unicast() {
  967. panic!("Ethernet address {} is not unicast", addr)
  968. }
  969. }
  970. fn check_ip_addrs(addrs: &[IpCidr]) {
  971. for cidr in addrs {
  972. if !cidr.address().is_unicast() && !cidr.address().is_unspecified() {
  973. panic!("IP address {} is not unicast", cidr.address())
  974. }
  975. }
  976. }
  977. #[cfg(feature = "medium-ieee802154")]
  978. fn get_sequence_number(&mut self) -> u8 {
  979. let no = self.sequence_no;
  980. self.sequence_no = self.sequence_no.wrapping_add(1);
  981. no
  982. }
  983. /// Determine if the given `Ipv6Address` is the solicited node
  984. /// multicast address for a IPv6 addresses assigned to the interface.
  985. /// See [RFC 4291 § 2.7.1] for more details.
  986. ///
  987. /// [RFC 4291 § 2.7.1]: https://tools.ietf.org/html/rfc4291#section-2.7.1
  988. #[cfg(feature = "proto-ipv6")]
  989. pub fn has_solicited_node(&self, addr: Ipv6Address) -> bool {
  990. self.ip_addrs.iter().any(|cidr| {
  991. match *cidr {
  992. IpCidr::Ipv6(cidr) if cidr.address() != Ipv6Address::LOOPBACK => {
  993. // Take the lower order 24 bits of the IPv6 address and
  994. // append those bits to FF02:0:0:0:0:1:FF00::/104.
  995. addr.as_bytes()[14..] == cidr.address().as_bytes()[14..]
  996. }
  997. _ => false,
  998. }
  999. })
  1000. }
  1001. /// Check whether the interface has the given IP address assigned.
  1002. fn has_ip_addr<T: Into<IpAddress>>(&self, addr: T) -> bool {
  1003. let addr = addr.into();
  1004. self.ip_addrs.iter().any(|probe| probe.address() == addr)
  1005. }
  1006. /// Get the first IPv4 address of the interface.
  1007. #[cfg(feature = "proto-ipv4")]
  1008. pub fn ipv4_address(&self) -> Option<Ipv4Address> {
  1009. self.ip_addrs
  1010. .iter()
  1011. .filter_map(|addr| match *addr {
  1012. IpCidr::Ipv4(cidr) => Some(cidr.address()),
  1013. #[cfg(feature = "proto-ipv6")]
  1014. IpCidr::Ipv6(_) => None,
  1015. })
  1016. .next()
  1017. }
  1018. /// Check whether the interface listens to given destination multicast IP address.
  1019. ///
  1020. /// If built without feature `proto-igmp` this function will
  1021. /// always return `false`.
  1022. pub fn has_multicast_group<T: Into<IpAddress>>(&self, addr: T) -> bool {
  1023. match addr.into() {
  1024. #[cfg(feature = "proto-igmp")]
  1025. IpAddress::Ipv4(key) => {
  1026. key == Ipv4Address::MULTICAST_ALL_SYSTEMS
  1027. || self.ipv4_multicast_groups.get(&key).is_some()
  1028. }
  1029. #[allow(unreachable_patterns)]
  1030. _ => false,
  1031. }
  1032. }
  1033. #[cfg(feature = "medium-ethernet")]
  1034. fn process_ethernet<'frame, T: AsRef<[u8]>>(
  1035. &mut self,
  1036. sockets: &mut SocketSet,
  1037. frame: &'frame T,
  1038. ) -> Option<EthernetPacket<'frame>> {
  1039. let eth_frame = check!(EthernetFrame::new_checked(frame));
  1040. // Ignore any packets not directed to our hardware address or any of the multicast groups.
  1041. if !eth_frame.dst_addr().is_broadcast()
  1042. && !eth_frame.dst_addr().is_multicast()
  1043. && HardwareAddress::Ethernet(eth_frame.dst_addr()) != self.hardware_addr.unwrap()
  1044. {
  1045. return None;
  1046. }
  1047. match eth_frame.ethertype() {
  1048. #[cfg(feature = "proto-ipv4")]
  1049. EthernetProtocol::Arp => self.process_arp(self.now, &eth_frame),
  1050. #[cfg(feature = "proto-ipv4")]
  1051. EthernetProtocol::Ipv4 => {
  1052. let ipv4_packet = check!(Ipv4Packet::new_checked(eth_frame.payload()));
  1053. self.process_ipv4(sockets, &ipv4_packet)
  1054. .map(EthernetPacket::Ip)
  1055. }
  1056. #[cfg(feature = "proto-ipv6")]
  1057. EthernetProtocol::Ipv6 => {
  1058. let ipv6_packet = check!(Ipv6Packet::new_checked(eth_frame.payload()));
  1059. self.process_ipv6(sockets, &ipv6_packet)
  1060. .map(EthernetPacket::Ip)
  1061. }
  1062. // Drop all other traffic.
  1063. _ => None,
  1064. }
  1065. }
  1066. #[cfg(feature = "medium-ip")]
  1067. fn process_ip<'frame, T: AsRef<[u8]>>(
  1068. &mut self,
  1069. sockets: &mut SocketSet,
  1070. ip_payload: &'frame T,
  1071. ) -> Option<IpPacket<'frame>> {
  1072. match IpVersion::of_packet(ip_payload.as_ref()) {
  1073. #[cfg(feature = "proto-ipv4")]
  1074. Ok(IpVersion::Ipv4) => {
  1075. let ipv4_packet = check!(Ipv4Packet::new_checked(ip_payload));
  1076. self.process_ipv4(sockets, &ipv4_packet)
  1077. }
  1078. #[cfg(feature = "proto-ipv6")]
  1079. Ok(IpVersion::Ipv6) => {
  1080. let ipv6_packet = check!(Ipv6Packet::new_checked(ip_payload));
  1081. self.process_ipv6(sockets, &ipv6_packet)
  1082. }
  1083. // Drop all other traffic.
  1084. _ => None,
  1085. }
  1086. }
  1087. #[cfg(feature = "medium-ieee802154")]
  1088. fn process_ieee802154<'frame, T: AsRef<[u8]> + ?Sized>(
  1089. &mut self,
  1090. sockets: &mut SocketSet,
  1091. sixlowpan_payload: &'frame T,
  1092. ) -> Option<IpPacket<'frame>> {
  1093. let ieee802154_frame = check!(Ieee802154Frame::new_checked(sixlowpan_payload));
  1094. let ieee802154_repr = check!(Ieee802154Repr::parse(&ieee802154_frame));
  1095. if ieee802154_repr.frame_type != Ieee802154FrameType::Data {
  1096. return None;
  1097. }
  1098. // Drop frames when the user has set a PAN id and the PAN id from frame is not equal to this
  1099. // When the user didn't set a PAN id (so it is None), then we accept all PAN id's.
  1100. // We always accept the broadcast PAN id.
  1101. if self.pan_id.is_some()
  1102. && ieee802154_repr.dst_pan_id != self.pan_id
  1103. && ieee802154_repr.dst_pan_id != Some(Ieee802154Pan::BROADCAST)
  1104. {
  1105. net_debug!(
  1106. "dropping {:?} because not our PAN id (or not broadcast)",
  1107. ieee802154_repr
  1108. );
  1109. return None;
  1110. }
  1111. match ieee802154_frame.payload() {
  1112. Some(payload) => self.process_sixlowpan(sockets, &ieee802154_repr, payload),
  1113. None => None,
  1114. }
  1115. }
  1116. #[cfg(feature = "proto-sixlowpan")]
  1117. fn process_sixlowpan<'frame, T: AsRef<[u8]> + ?Sized>(
  1118. &mut self,
  1119. sockets: &mut SocketSet,
  1120. ieee802154_repr: &Ieee802154Repr,
  1121. payload: &'frame T,
  1122. ) -> Option<IpPacket<'frame>> {
  1123. // The first header needs to be an IPHC header.
  1124. let iphc_packet = check!(SixlowpanIphcPacket::new_checked(payload));
  1125. let iphc_repr = check!(SixlowpanIphcRepr::parse(
  1126. &iphc_packet,
  1127. ieee802154_repr.src_addr,
  1128. ieee802154_repr.dst_addr,
  1129. ));
  1130. let payload = iphc_packet.payload();
  1131. let mut ipv6_repr = Ipv6Repr {
  1132. src_addr: iphc_repr.src_addr,
  1133. dst_addr: iphc_repr.dst_addr,
  1134. hop_limit: iphc_repr.hop_limit,
  1135. next_header: IpProtocol::Unknown(0),
  1136. payload_len: iphc_repr.buffer_len(),
  1137. };
  1138. // Currently we assume the next header is a UDP, so we ignore everything else.
  1139. match iphc_repr.next_header {
  1140. SixlowpanNextHeader::Compressed => {
  1141. match check!(SixlowpanNhcPacket::dispatch(payload)) {
  1142. SixlowpanNhcPacket::ExtensionHeader(_) => {
  1143. net_debug!("Extension headers are currently not supported for 6LoWPAN");
  1144. None
  1145. }
  1146. #[cfg(not(feature = "socket-udp"))]
  1147. SixlowpanNhcPacket::UdpHeader(_) => {
  1148. net_debug!("UDP support is disabled, enable cargo feature `socket-udp`.");
  1149. None
  1150. }
  1151. #[cfg(feature = "socket-udp")]
  1152. SixlowpanNhcPacket::UdpHeader(udp_packet) => {
  1153. ipv6_repr.next_header = IpProtocol::Udp;
  1154. // Handle the UDP
  1155. let udp_repr = check!(SixlowpanUdpRepr::parse(
  1156. &udp_packet,
  1157. &iphc_repr.src_addr,
  1158. &iphc_repr.dst_addr,
  1159. udp_packet.checksum(),
  1160. ));
  1161. // Look for UDP sockets that will accept the UDP packet.
  1162. // If it does not accept the packet, then send an ICMP message.
  1163. for udp_socket in sockets
  1164. .items_mut()
  1165. .filter_map(|i| udp::Socket::downcast_mut(&mut i.socket))
  1166. {
  1167. if udp_socket.accepts(self, &IpRepr::Ipv6(ipv6_repr), &udp_repr) {
  1168. udp_socket.process(
  1169. self,
  1170. &IpRepr::Ipv6(ipv6_repr),
  1171. &udp_repr,
  1172. udp_packet.payload(),
  1173. );
  1174. return None;
  1175. }
  1176. }
  1177. let payload_len = icmp_reply_payload_len(
  1178. payload.len(),
  1179. IPV6_MIN_MTU,
  1180. ipv6_repr.buffer_len(),
  1181. );
  1182. let icmpv6_reply_repr = Icmpv6Repr::DstUnreachable {
  1183. reason: Icmpv6DstUnreachable::PortUnreachable,
  1184. header: ipv6_repr,
  1185. data: &payload[0..payload_len],
  1186. };
  1187. self.icmpv6_reply(ipv6_repr, icmpv6_reply_repr)
  1188. }
  1189. }
  1190. }
  1191. SixlowpanNextHeader::Uncompressed(nxt_hdr) => match nxt_hdr {
  1192. IpProtocol::Icmpv6 => {
  1193. ipv6_repr.next_header = IpProtocol::Icmpv6;
  1194. self.process_icmpv6(sockets, IpRepr::Ipv6(ipv6_repr), iphc_packet.payload())
  1195. }
  1196. _ => {
  1197. net_debug!("Headers other than ICMPv6 and compressed headers are currently not supported for 6LoWPAN");
  1198. None
  1199. }
  1200. },
  1201. }
  1202. }
  1203. #[cfg(all(feature = "medium-ethernet", feature = "proto-ipv4"))]
  1204. fn process_arp<'frame, T: AsRef<[u8]>>(
  1205. &mut self,
  1206. timestamp: Instant,
  1207. eth_frame: &EthernetFrame<&'frame T>,
  1208. ) -> Option<EthernetPacket<'frame>> {
  1209. let arp_packet = check!(ArpPacket::new_checked(eth_frame.payload()));
  1210. let arp_repr = check!(ArpRepr::parse(&arp_packet));
  1211. match arp_repr {
  1212. ArpRepr::EthernetIpv4 {
  1213. operation,
  1214. source_hardware_addr,
  1215. source_protocol_addr,
  1216. target_protocol_addr,
  1217. ..
  1218. } => {
  1219. // Only process ARP packets for us.
  1220. if !self.has_ip_addr(target_protocol_addr) {
  1221. return None;
  1222. }
  1223. // Only process REQUEST and RESPONSE.
  1224. if let ArpOperation::Unknown(_) = operation {
  1225. net_debug!("arp: unknown operation code");
  1226. return None;
  1227. }
  1228. // Discard packets with non-unicast source addresses.
  1229. if !source_protocol_addr.is_unicast() || !source_hardware_addr.is_unicast() {
  1230. net_debug!("arp: non-unicast source address");
  1231. return None;
  1232. }
  1233. if !self.in_same_network(&IpAddress::Ipv4(source_protocol_addr)) {
  1234. net_debug!("arp: source IP address not in same network as us");
  1235. return None;
  1236. }
  1237. // Fill the ARP cache from any ARP packet aimed at us (both request or response).
  1238. // We fill from requests too because if someone is requesting our address they
  1239. // are probably going to talk to us, so we avoid having to request their address
  1240. // when we later reply to them.
  1241. self.neighbor_cache.as_mut().unwrap().fill(
  1242. source_protocol_addr.into(),
  1243. source_hardware_addr.into(),
  1244. timestamp,
  1245. );
  1246. if operation == ArpOperation::Request {
  1247. let src_hardware_addr = match self.hardware_addr {
  1248. Some(HardwareAddress::Ethernet(addr)) => addr,
  1249. _ => unreachable!(),
  1250. };
  1251. Some(EthernetPacket::Arp(ArpRepr::EthernetIpv4 {
  1252. operation: ArpOperation::Reply,
  1253. source_hardware_addr: src_hardware_addr,
  1254. source_protocol_addr: target_protocol_addr,
  1255. target_hardware_addr: source_hardware_addr,
  1256. target_protocol_addr: source_protocol_addr,
  1257. }))
  1258. } else {
  1259. None
  1260. }
  1261. }
  1262. }
  1263. }
  1264. #[cfg(feature = "socket-raw")]
  1265. fn raw_socket_filter<'frame>(
  1266. &mut self,
  1267. sockets: &mut SocketSet,
  1268. ip_repr: &IpRepr,
  1269. ip_payload: &'frame [u8],
  1270. ) -> bool {
  1271. let mut handled_by_raw_socket = false;
  1272. // Pass every IP packet to all raw sockets we have registered.
  1273. for raw_socket in sockets
  1274. .items_mut()
  1275. .filter_map(|i| raw::Socket::downcast_mut(&mut i.socket))
  1276. {
  1277. if raw_socket.accepts(ip_repr) {
  1278. raw_socket.process(self, ip_repr, ip_payload);
  1279. handled_by_raw_socket = true;
  1280. }
  1281. }
  1282. handled_by_raw_socket
  1283. }
  1284. #[cfg(feature = "proto-ipv6")]
  1285. fn process_ipv6<'frame, T: AsRef<[u8]> + ?Sized>(
  1286. &mut self,
  1287. sockets: &mut SocketSet,
  1288. ipv6_packet: &Ipv6Packet<&'frame T>,
  1289. ) -> Option<IpPacket<'frame>> {
  1290. let ipv6_repr = check!(Ipv6Repr::parse(ipv6_packet));
  1291. if !ipv6_repr.src_addr.is_unicast() {
  1292. // Discard packets with non-unicast source addresses.
  1293. net_debug!("non-unicast source address");
  1294. return None;
  1295. }
  1296. let ip_payload = ipv6_packet.payload();
  1297. #[cfg(feature = "socket-raw")]
  1298. let handled_by_raw_socket = self.raw_socket_filter(sockets, &ipv6_repr.into(), ip_payload);
  1299. #[cfg(not(feature = "socket-raw"))]
  1300. let handled_by_raw_socket = false;
  1301. self.process_nxt_hdr(
  1302. sockets,
  1303. ipv6_repr,
  1304. ipv6_repr.next_header,
  1305. handled_by_raw_socket,
  1306. ip_payload,
  1307. )
  1308. }
  1309. /// Given the next header value forward the payload onto the correct process
  1310. /// function.
  1311. #[cfg(feature = "proto-ipv6")]
  1312. fn process_nxt_hdr<'frame>(
  1313. &mut self,
  1314. sockets: &mut SocketSet,
  1315. ipv6_repr: Ipv6Repr,
  1316. nxt_hdr: IpProtocol,
  1317. handled_by_raw_socket: bool,
  1318. ip_payload: &'frame [u8],
  1319. ) -> Option<IpPacket<'frame>> {
  1320. match nxt_hdr {
  1321. IpProtocol::Icmpv6 => self.process_icmpv6(sockets, ipv6_repr.into(), ip_payload),
  1322. #[cfg(any(feature = "socket-udp", feature = "socket-dns"))]
  1323. IpProtocol::Udp => {
  1324. self.process_udp(sockets, ipv6_repr.into(), handled_by_raw_socket, ip_payload)
  1325. }
  1326. #[cfg(feature = "socket-tcp")]
  1327. IpProtocol::Tcp => self.process_tcp(sockets, ipv6_repr.into(), ip_payload),
  1328. IpProtocol::HopByHop => {
  1329. self.process_hopbyhop(sockets, ipv6_repr, handled_by_raw_socket, ip_payload)
  1330. }
  1331. #[cfg(feature = "socket-raw")]
  1332. _ if handled_by_raw_socket => None,
  1333. _ => {
  1334. // Send back as much of the original payload as we can.
  1335. let payload_len =
  1336. icmp_reply_payload_len(ip_payload.len(), IPV6_MIN_MTU, ipv6_repr.buffer_len());
  1337. let icmp_reply_repr = Icmpv6Repr::ParamProblem {
  1338. reason: Icmpv6ParamProblem::UnrecognizedNxtHdr,
  1339. // The offending packet is after the IPv6 header.
  1340. pointer: ipv6_repr.buffer_len() as u32,
  1341. header: ipv6_repr,
  1342. data: &ip_payload[0..payload_len],
  1343. };
  1344. self.icmpv6_reply(ipv6_repr, icmp_reply_repr)
  1345. }
  1346. }
  1347. }
  1348. #[cfg(feature = "proto-ipv4")]
  1349. fn process_ipv4<'frame, T: AsRef<[u8]> + ?Sized>(
  1350. &mut self,
  1351. sockets: &mut SocketSet,
  1352. ipv4_packet: &Ipv4Packet<&'frame T>,
  1353. ) -> Option<IpPacket<'frame>> {
  1354. let ipv4_repr = check!(Ipv4Repr::parse(ipv4_packet, &self.caps.checksum));
  1355. if !self.is_unicast_v4(ipv4_repr.src_addr) {
  1356. // Discard packets with non-unicast source addresses.
  1357. net_debug!("non-unicast source address");
  1358. return None;
  1359. }
  1360. let ip_repr = IpRepr::Ipv4(ipv4_repr);
  1361. let ip_payload = ipv4_packet.payload();
  1362. #[cfg(feature = "socket-raw")]
  1363. let handled_by_raw_socket = self.raw_socket_filter(sockets, &ip_repr, ip_payload);
  1364. #[cfg(not(feature = "socket-raw"))]
  1365. let handled_by_raw_socket = false;
  1366. #[cfg(feature = "socket-dhcpv4")]
  1367. {
  1368. if ipv4_repr.next_header == IpProtocol::Udp && self.hardware_addr.is_some() {
  1369. // First check for source and dest ports, then do `UdpRepr::parse` if they match.
  1370. // This way we avoid validating the UDP checksum twice for all non-DHCP UDP packets (one here, one in `process_udp`)
  1371. let udp_packet = check!(UdpPacket::new_checked(ip_payload));
  1372. if udp_packet.src_port() == DHCP_SERVER_PORT
  1373. && udp_packet.dst_port() == DHCP_CLIENT_PORT
  1374. {
  1375. if let Some(dhcp_socket) = sockets
  1376. .items_mut()
  1377. .filter_map(|i| dhcpv4::Socket::downcast_mut(&mut i.socket))
  1378. .next()
  1379. {
  1380. let (src_addr, dst_addr) = (ip_repr.src_addr(), ip_repr.dst_addr());
  1381. let udp_repr = check!(UdpRepr::parse(
  1382. &udp_packet,
  1383. &src_addr,
  1384. &dst_addr,
  1385. &self.caps.checksum
  1386. ));
  1387. let udp_payload = udp_packet.payload();
  1388. dhcp_socket.process(self, &ipv4_repr, &udp_repr, udp_payload);
  1389. return None;
  1390. }
  1391. }
  1392. }
  1393. }
  1394. if !self.has_ip_addr(ipv4_repr.dst_addr)
  1395. && !self.has_multicast_group(ipv4_repr.dst_addr)
  1396. && !self.is_broadcast_v4(ipv4_repr.dst_addr)
  1397. {
  1398. // Ignore IP packets not directed at us, or broadcast, or any of the multicast groups.
  1399. // If AnyIP is enabled, also check if the packet is routed locally.
  1400. if !self.any_ip
  1401. || !ipv4_repr.dst_addr.is_unicast()
  1402. || self
  1403. .routes
  1404. .lookup(&IpAddress::Ipv4(ipv4_repr.dst_addr), self.now)
  1405. .map_or(true, |router_addr| !self.has_ip_addr(router_addr))
  1406. {
  1407. return None;
  1408. }
  1409. }
  1410. match ipv4_repr.next_header {
  1411. IpProtocol::Icmp => self.process_icmpv4(sockets, ip_repr, ip_payload),
  1412. #[cfg(feature = "proto-igmp")]
  1413. IpProtocol::Igmp => self.process_igmp(ipv4_repr, ip_payload),
  1414. #[cfg(any(feature = "socket-udp", feature = "socket-dns"))]
  1415. IpProtocol::Udp => {
  1416. self.process_udp(sockets, ip_repr, handled_by_raw_socket, ip_payload)
  1417. }
  1418. #[cfg(feature = "socket-tcp")]
  1419. IpProtocol::Tcp => self.process_tcp(sockets, ip_repr, ip_payload),
  1420. _ if handled_by_raw_socket => None,
  1421. _ => {
  1422. // Send back as much of the original payload as we can.
  1423. let payload_len =
  1424. icmp_reply_payload_len(ip_payload.len(), IPV4_MIN_MTU, ipv4_repr.buffer_len());
  1425. let icmp_reply_repr = Icmpv4Repr::DstUnreachable {
  1426. reason: Icmpv4DstUnreachable::ProtoUnreachable,
  1427. header: ipv4_repr,
  1428. data: &ip_payload[0..payload_len],
  1429. };
  1430. self.icmpv4_reply(ipv4_repr, icmp_reply_repr)
  1431. }
  1432. }
  1433. }
  1434. /// Checks if an incoming packet has a broadcast address for the interfaces
  1435. /// associated ipv4 addresses.
  1436. #[cfg(feature = "proto-ipv4")]
  1437. fn is_subnet_broadcast(&self, address: Ipv4Address) -> bool {
  1438. self.ip_addrs
  1439. .iter()
  1440. .filter_map(|own_cidr| match own_cidr {
  1441. IpCidr::Ipv4(own_ip) => Some(own_ip.broadcast()?),
  1442. #[cfg(feature = "proto-ipv6")]
  1443. IpCidr::Ipv6(_) => None,
  1444. })
  1445. .any(|broadcast_address| address == broadcast_address)
  1446. }
  1447. /// Checks if an ipv4 address is broadcast, taking into account subnet broadcast addresses
  1448. #[cfg(feature = "proto-ipv4")]
  1449. fn is_broadcast_v4(&self, address: Ipv4Address) -> bool {
  1450. address.is_broadcast() || self.is_subnet_broadcast(address)
  1451. }
  1452. /// Checks if an ipv4 address is unicast, taking into account subnet broadcast addresses
  1453. #[cfg(feature = "proto-ipv4")]
  1454. fn is_unicast_v4(&self, address: Ipv4Address) -> bool {
  1455. address.is_unicast() && !self.is_subnet_broadcast(address)
  1456. }
  1457. /// Host duties of the **IGMPv2** protocol.
  1458. ///
  1459. /// Sets up `igmp_report_state` for responding to IGMP general/specific membership queries.
  1460. /// Membership must not be reported immediately in order to avoid flooding the network
  1461. /// after a query is broadcasted by a router; this is not currently done.
  1462. #[cfg(feature = "proto-igmp")]
  1463. fn process_igmp<'frame>(
  1464. &mut self,
  1465. ipv4_repr: Ipv4Repr,
  1466. ip_payload: &'frame [u8],
  1467. ) -> Option<IpPacket<'frame>> {
  1468. let igmp_packet = check!(IgmpPacket::new_checked(ip_payload));
  1469. let igmp_repr = check!(IgmpRepr::parse(&igmp_packet));
  1470. // FIXME: report membership after a delay
  1471. match igmp_repr {
  1472. IgmpRepr::MembershipQuery {
  1473. group_addr,
  1474. version,
  1475. max_resp_time,
  1476. } => {
  1477. // General query
  1478. if group_addr.is_unspecified()
  1479. && ipv4_repr.dst_addr == Ipv4Address::MULTICAST_ALL_SYSTEMS
  1480. {
  1481. // Are we member in any groups?
  1482. if self.ipv4_multicast_groups.iter().next().is_some() {
  1483. let interval = match version {
  1484. IgmpVersion::Version1 => Duration::from_millis(100),
  1485. IgmpVersion::Version2 => {
  1486. // No dependence on a random generator
  1487. // (see [#24](https://github.com/m-labs/smoltcp/issues/24))
  1488. // but at least spread reports evenly across max_resp_time.
  1489. let intervals = self.ipv4_multicast_groups.len() as u32 + 1;
  1490. max_resp_time / intervals
  1491. }
  1492. };
  1493. self.igmp_report_state = IgmpReportState::ToGeneralQuery {
  1494. version,
  1495. timeout: self.now + interval,
  1496. interval,
  1497. next_index: 0,
  1498. };
  1499. }
  1500. } else {
  1501. // Group-specific query
  1502. if self.has_multicast_group(group_addr) && ipv4_repr.dst_addr == group_addr {
  1503. // Don't respond immediately
  1504. let timeout = max_resp_time / 4;
  1505. self.igmp_report_state = IgmpReportState::ToSpecificQuery {
  1506. version,
  1507. timeout: self.now + timeout,
  1508. group: group_addr,
  1509. };
  1510. }
  1511. }
  1512. }
  1513. // Ignore membership reports
  1514. IgmpRepr::MembershipReport { .. } => (),
  1515. // Ignore hosts leaving groups
  1516. IgmpRepr::LeaveGroup { .. } => (),
  1517. }
  1518. None
  1519. }
  1520. #[cfg(feature = "proto-ipv6")]
  1521. fn process_icmpv6<'frame>(
  1522. &mut self,
  1523. _sockets: &mut SocketSet,
  1524. ip_repr: IpRepr,
  1525. ip_payload: &'frame [u8],
  1526. ) -> Option<IpPacket<'frame>> {
  1527. let icmp_packet = check!(Icmpv6Packet::new_checked(ip_payload));
  1528. let icmp_repr = check!(Icmpv6Repr::parse(
  1529. &ip_repr.src_addr(),
  1530. &ip_repr.dst_addr(),
  1531. &icmp_packet,
  1532. &self.caps.checksum,
  1533. ));
  1534. #[cfg(feature = "socket-icmp")]
  1535. let mut handled_by_icmp_socket = false;
  1536. #[cfg(all(feature = "socket-icmp", feature = "proto-ipv6"))]
  1537. for icmp_socket in _sockets
  1538. .items_mut()
  1539. .filter_map(|i| icmp::Socket::downcast_mut(&mut i.socket))
  1540. {
  1541. if icmp_socket.accepts(self, &ip_repr, &icmp_repr.into()) {
  1542. icmp_socket.process(self, &ip_repr, &icmp_repr.into());
  1543. handled_by_icmp_socket = true;
  1544. }
  1545. }
  1546. match icmp_repr {
  1547. // Respond to echo requests.
  1548. Icmpv6Repr::EchoRequest {
  1549. ident,
  1550. seq_no,
  1551. data,
  1552. } => match ip_repr {
  1553. IpRepr::Ipv6(ipv6_repr) => {
  1554. let icmp_reply_repr = Icmpv6Repr::EchoReply {
  1555. ident,
  1556. seq_no,
  1557. data,
  1558. };
  1559. self.icmpv6_reply(ipv6_repr, icmp_reply_repr)
  1560. }
  1561. #[allow(unreachable_patterns)]
  1562. _ => unreachable!(),
  1563. },
  1564. // Ignore any echo replies.
  1565. Icmpv6Repr::EchoReply { .. } => None,
  1566. // Forward any NDISC packets to the ndisc packet handler
  1567. #[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
  1568. Icmpv6Repr::Ndisc(repr) if ip_repr.hop_limit() == 0xff => match ip_repr {
  1569. IpRepr::Ipv6(ipv6_repr) => self.process_ndisc(ipv6_repr, repr),
  1570. #[allow(unreachable_patterns)]
  1571. _ => unreachable!(),
  1572. },
  1573. // Don't report an error if a packet with unknown type
  1574. // has been handled by an ICMP socket
  1575. #[cfg(feature = "socket-icmp")]
  1576. _ if handled_by_icmp_socket => None,
  1577. // FIXME: do something correct here?
  1578. _ => None,
  1579. }
  1580. }
  1581. #[cfg(all(
  1582. any(feature = "medium-ethernet", feature = "medium-ieee802154"),
  1583. feature = "proto-ipv6"
  1584. ))]
  1585. fn process_ndisc<'frame>(
  1586. &mut self,
  1587. ip_repr: Ipv6Repr,
  1588. repr: NdiscRepr<'frame>,
  1589. ) -> Option<IpPacket<'frame>> {
  1590. match repr {
  1591. NdiscRepr::NeighborAdvert {
  1592. lladdr,
  1593. target_addr,
  1594. flags,
  1595. } => {
  1596. let ip_addr = ip_repr.src_addr.into();
  1597. if let Some(lladdr) = lladdr {
  1598. let lladdr = check!(lladdr.parse(self.caps.medium));
  1599. if !lladdr.is_unicast() || !target_addr.is_unicast() {
  1600. return None;
  1601. }
  1602. if flags.contains(NdiscNeighborFlags::OVERRIDE)
  1603. || !self
  1604. .neighbor_cache
  1605. .as_mut()
  1606. .unwrap()
  1607. .lookup(&ip_addr, self.now)
  1608. .found()
  1609. {
  1610. self.neighbor_cache
  1611. .as_mut()
  1612. .unwrap()
  1613. .fill(ip_addr, lladdr, self.now)
  1614. }
  1615. }
  1616. None
  1617. }
  1618. NdiscRepr::NeighborSolicit {
  1619. target_addr,
  1620. lladdr,
  1621. ..
  1622. } => {
  1623. if let Some(lladdr) = lladdr {
  1624. let lladdr = check!(lladdr.parse(self.caps.medium));
  1625. if !lladdr.is_unicast() || !target_addr.is_unicast() {
  1626. return None;
  1627. }
  1628. self.neighbor_cache.as_mut().unwrap().fill(
  1629. ip_repr.src_addr.into(),
  1630. lladdr,
  1631. self.now,
  1632. );
  1633. }
  1634. if self.has_solicited_node(ip_repr.dst_addr) && self.has_ip_addr(target_addr) {
  1635. let advert = Icmpv6Repr::Ndisc(NdiscRepr::NeighborAdvert {
  1636. flags: NdiscNeighborFlags::SOLICITED,
  1637. target_addr,
  1638. #[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
  1639. lladdr: Some(self.hardware_addr.unwrap().into()),
  1640. });
  1641. let ip_repr = Ipv6Repr {
  1642. src_addr: target_addr,
  1643. dst_addr: ip_repr.src_addr,
  1644. next_header: IpProtocol::Icmpv6,
  1645. hop_limit: 0xff,
  1646. payload_len: advert.buffer_len(),
  1647. };
  1648. Some(IpPacket::Icmpv6((ip_repr, advert)))
  1649. } else {
  1650. None
  1651. }
  1652. }
  1653. _ => None,
  1654. }
  1655. }
  1656. #[cfg(feature = "proto-ipv6")]
  1657. fn process_hopbyhop<'frame>(
  1658. &mut self,
  1659. sockets: &mut SocketSet,
  1660. ipv6_repr: Ipv6Repr,
  1661. handled_by_raw_socket: bool,
  1662. ip_payload: &'frame [u8],
  1663. ) -> Option<IpPacket<'frame>> {
  1664. let hbh_pkt = check!(Ipv6HopByHopHeader::new_checked(ip_payload));
  1665. let hbh_repr = check!(Ipv6HopByHopRepr::parse(&hbh_pkt));
  1666. for opt_repr in hbh_repr.options() {
  1667. let opt_repr = check!(opt_repr);
  1668. match opt_repr {
  1669. Ipv6OptionRepr::Pad1 | Ipv6OptionRepr::PadN(_) => (),
  1670. Ipv6OptionRepr::Unknown { type_, .. } => {
  1671. match Ipv6OptionFailureType::from(type_) {
  1672. Ipv6OptionFailureType::Skip => (),
  1673. Ipv6OptionFailureType::Discard => {
  1674. return None;
  1675. }
  1676. _ => {
  1677. // FIXME(dlrobertson): Send an ICMPv6 parameter problem message
  1678. // here.
  1679. return None;
  1680. }
  1681. }
  1682. }
  1683. }
  1684. }
  1685. self.process_nxt_hdr(
  1686. sockets,
  1687. ipv6_repr,
  1688. hbh_repr.next_header,
  1689. handled_by_raw_socket,
  1690. &ip_payload[hbh_repr.buffer_len()..],
  1691. )
  1692. }
  1693. #[cfg(feature = "proto-ipv4")]
  1694. fn process_icmpv4<'frame>(
  1695. &mut self,
  1696. _sockets: &mut SocketSet,
  1697. ip_repr: IpRepr,
  1698. ip_payload: &'frame [u8],
  1699. ) -> Option<IpPacket<'frame>> {
  1700. let icmp_packet = check!(Icmpv4Packet::new_checked(ip_payload));
  1701. let icmp_repr = check!(Icmpv4Repr::parse(&icmp_packet, &self.caps.checksum));
  1702. #[cfg(feature = "socket-icmp")]
  1703. let mut handled_by_icmp_socket = false;
  1704. #[cfg(all(feature = "socket-icmp", feature = "proto-ipv4"))]
  1705. for icmp_socket in _sockets
  1706. .items_mut()
  1707. .filter_map(|i| icmp::Socket::downcast_mut(&mut i.socket))
  1708. {
  1709. if icmp_socket.accepts(self, &ip_repr, &icmp_repr.into()) {
  1710. icmp_socket.process(self, &ip_repr, &icmp_repr.into());
  1711. handled_by_icmp_socket = true;
  1712. }
  1713. }
  1714. match icmp_repr {
  1715. // Respond to echo requests.
  1716. #[cfg(feature = "proto-ipv4")]
  1717. Icmpv4Repr::EchoRequest {
  1718. ident,
  1719. seq_no,
  1720. data,
  1721. } => {
  1722. let icmp_reply_repr = Icmpv4Repr::EchoReply {
  1723. ident,
  1724. seq_no,
  1725. data,
  1726. };
  1727. match ip_repr {
  1728. IpRepr::Ipv4(ipv4_repr) => self.icmpv4_reply(ipv4_repr, icmp_reply_repr),
  1729. #[allow(unreachable_patterns)]
  1730. _ => unreachable!(),
  1731. }
  1732. }
  1733. // Ignore any echo replies.
  1734. Icmpv4Repr::EchoReply { .. } => None,
  1735. // Don't report an error if a packet with unknown type
  1736. // has been handled by an ICMP socket
  1737. #[cfg(feature = "socket-icmp")]
  1738. _ if handled_by_icmp_socket => None,
  1739. // FIXME: do something correct here?
  1740. _ => None,
  1741. }
  1742. }
  1743. #[cfg(feature = "proto-ipv4")]
  1744. fn icmpv4_reply<'frame, 'icmp: 'frame>(
  1745. &self,
  1746. ipv4_repr: Ipv4Repr,
  1747. icmp_repr: Icmpv4Repr<'icmp>,
  1748. ) -> Option<IpPacket<'frame>> {
  1749. if !self.is_unicast_v4(ipv4_repr.src_addr) {
  1750. // Do not send ICMP replies to non-unicast sources
  1751. None
  1752. } else if self.is_unicast_v4(ipv4_repr.dst_addr) {
  1753. // Reply as normal when src_addr and dst_addr are both unicast
  1754. let ipv4_reply_repr = Ipv4Repr {
  1755. src_addr: ipv4_repr.dst_addr,
  1756. dst_addr: ipv4_repr.src_addr,
  1757. next_header: IpProtocol::Icmp,
  1758. payload_len: icmp_repr.buffer_len(),
  1759. hop_limit: 64,
  1760. };
  1761. Some(IpPacket::Icmpv4((ipv4_reply_repr, icmp_repr)))
  1762. } else if self.is_broadcast_v4(ipv4_repr.dst_addr) {
  1763. // Only reply to broadcasts for echo replies and not other ICMP messages
  1764. match icmp_repr {
  1765. Icmpv4Repr::EchoReply { .. } => match self.ipv4_address() {
  1766. Some(src_addr) => {
  1767. let ipv4_reply_repr = Ipv4Repr {
  1768. src_addr: src_addr,
  1769. dst_addr: ipv4_repr.src_addr,
  1770. next_header: IpProtocol::Icmp,
  1771. payload_len: icmp_repr.buffer_len(),
  1772. hop_limit: 64,
  1773. };
  1774. Some(IpPacket::Icmpv4((ipv4_reply_repr, icmp_repr)))
  1775. }
  1776. None => None,
  1777. },
  1778. _ => None,
  1779. }
  1780. } else {
  1781. None
  1782. }
  1783. }
  1784. #[cfg(feature = "proto-ipv6")]
  1785. fn icmpv6_reply<'frame, 'icmp: 'frame>(
  1786. &self,
  1787. ipv6_repr: Ipv6Repr,
  1788. icmp_repr: Icmpv6Repr<'icmp>,
  1789. ) -> Option<IpPacket<'frame>> {
  1790. if ipv6_repr.dst_addr.is_unicast() {
  1791. let ipv6_reply_repr = Ipv6Repr {
  1792. src_addr: ipv6_repr.dst_addr,
  1793. dst_addr: ipv6_repr.src_addr,
  1794. next_header: IpProtocol::Icmpv6,
  1795. payload_len: icmp_repr.buffer_len(),
  1796. hop_limit: 64,
  1797. };
  1798. Some(IpPacket::Icmpv6((ipv6_reply_repr, icmp_repr)))
  1799. } else {
  1800. // Do not send any ICMP replies to a broadcast destination address.
  1801. None
  1802. }
  1803. }
  1804. #[cfg(any(feature = "socket-udp", feature = "socket-dns"))]
  1805. fn process_udp<'frame>(
  1806. &mut self,
  1807. sockets: &mut SocketSet,
  1808. ip_repr: IpRepr,
  1809. handled_by_raw_socket: bool,
  1810. ip_payload: &'frame [u8],
  1811. ) -> Option<IpPacket<'frame>> {
  1812. let (src_addr, dst_addr) = (ip_repr.src_addr(), ip_repr.dst_addr());
  1813. let udp_packet = check!(UdpPacket::new_checked(ip_payload));
  1814. let udp_repr = check!(UdpRepr::parse(
  1815. &udp_packet,
  1816. &src_addr,
  1817. &dst_addr,
  1818. &self.caps.checksum
  1819. ));
  1820. let udp_payload = udp_packet.payload();
  1821. #[cfg(feature = "socket-udp")]
  1822. for udp_socket in sockets
  1823. .items_mut()
  1824. .filter_map(|i| udp::Socket::downcast_mut(&mut i.socket))
  1825. {
  1826. if udp_socket.accepts(self, &ip_repr, &udp_repr) {
  1827. udp_socket.process(self, &ip_repr, &udp_repr, udp_payload);
  1828. return None;
  1829. }
  1830. }
  1831. #[cfg(feature = "socket-dns")]
  1832. for dns_socket in sockets
  1833. .items_mut()
  1834. .filter_map(|i| dns::Socket::downcast_mut(&mut i.socket))
  1835. {
  1836. if dns_socket.accepts(&ip_repr, &udp_repr) {
  1837. dns_socket.process(self, &ip_repr, &udp_repr, udp_payload);
  1838. return None;
  1839. }
  1840. }
  1841. // The packet wasn't handled by a socket, send an ICMP port unreachable packet.
  1842. match ip_repr {
  1843. #[cfg(feature = "proto-ipv4")]
  1844. IpRepr::Ipv4(_) if handled_by_raw_socket => None,
  1845. #[cfg(feature = "proto-ipv6")]
  1846. IpRepr::Ipv6(_) if handled_by_raw_socket => None,
  1847. #[cfg(feature = "proto-ipv4")]
  1848. IpRepr::Ipv4(ipv4_repr) => {
  1849. let payload_len =
  1850. icmp_reply_payload_len(ip_payload.len(), IPV4_MIN_MTU, ipv4_repr.buffer_len());
  1851. let icmpv4_reply_repr = Icmpv4Repr::DstUnreachable {
  1852. reason: Icmpv4DstUnreachable::PortUnreachable,
  1853. header: ipv4_repr,
  1854. data: &ip_payload[0..payload_len],
  1855. };
  1856. self.icmpv4_reply(ipv4_repr, icmpv4_reply_repr)
  1857. }
  1858. #[cfg(feature = "proto-ipv6")]
  1859. IpRepr::Ipv6(ipv6_repr) => {
  1860. let payload_len =
  1861. icmp_reply_payload_len(ip_payload.len(), IPV6_MIN_MTU, ipv6_repr.buffer_len());
  1862. let icmpv6_reply_repr = Icmpv6Repr::DstUnreachable {
  1863. reason: Icmpv6DstUnreachable::PortUnreachable,
  1864. header: ipv6_repr,
  1865. data: &ip_payload[0..payload_len],
  1866. };
  1867. self.icmpv6_reply(ipv6_repr, icmpv6_reply_repr)
  1868. }
  1869. }
  1870. }
  1871. #[cfg(feature = "socket-tcp")]
  1872. fn process_tcp<'frame>(
  1873. &mut self,
  1874. sockets: &mut SocketSet,
  1875. ip_repr: IpRepr,
  1876. ip_payload: &'frame [u8],
  1877. ) -> Option<IpPacket<'frame>> {
  1878. let (src_addr, dst_addr) = (ip_repr.src_addr(), ip_repr.dst_addr());
  1879. let tcp_packet = check!(TcpPacket::new_checked(ip_payload));
  1880. let tcp_repr = check!(TcpRepr::parse(
  1881. &tcp_packet,
  1882. &src_addr,
  1883. &dst_addr,
  1884. &self.caps.checksum
  1885. ));
  1886. for tcp_socket in sockets
  1887. .items_mut()
  1888. .filter_map(|i| tcp::Socket::downcast_mut(&mut i.socket))
  1889. {
  1890. if tcp_socket.accepts(self, &ip_repr, &tcp_repr) {
  1891. return tcp_socket
  1892. .process(self, &ip_repr, &tcp_repr)
  1893. .map(IpPacket::Tcp);
  1894. }
  1895. }
  1896. if tcp_repr.control == TcpControl::Rst {
  1897. // Never reply to a TCP RST packet with another TCP RST packet.
  1898. None
  1899. } else {
  1900. // The packet wasn't handled by a socket, send a TCP RST packet.
  1901. Some(IpPacket::Tcp(tcp::Socket::rst_reply(&ip_repr, &tcp_repr)))
  1902. }
  1903. }
  1904. #[cfg(feature = "medium-ethernet")]
  1905. fn dispatch<Tx>(&mut self, tx_token: Tx, packet: EthernetPacket) -> Result<()>
  1906. where
  1907. Tx: TxToken,
  1908. {
  1909. match packet {
  1910. #[cfg(feature = "proto-ipv4")]
  1911. EthernetPacket::Arp(arp_repr) => {
  1912. let dst_hardware_addr = match arp_repr {
  1913. ArpRepr::EthernetIpv4 {
  1914. target_hardware_addr,
  1915. ..
  1916. } => target_hardware_addr,
  1917. };
  1918. self.dispatch_ethernet(tx_token, arp_repr.buffer_len(), |mut frame| {
  1919. frame.set_dst_addr(dst_hardware_addr);
  1920. frame.set_ethertype(EthernetProtocol::Arp);
  1921. let mut packet = ArpPacket::new_unchecked(frame.payload_mut());
  1922. arp_repr.emit(&mut packet);
  1923. })
  1924. }
  1925. EthernetPacket::Ip(packet) => self.dispatch_ip(tx_token, packet),
  1926. }
  1927. }
  1928. #[cfg(feature = "medium-ethernet")]
  1929. fn dispatch_ethernet<Tx, F>(&mut self, tx_token: Tx, buffer_len: usize, f: F) -> Result<()>
  1930. where
  1931. Tx: TxToken,
  1932. F: FnOnce(EthernetFrame<&mut [u8]>),
  1933. {
  1934. let tx_len = EthernetFrame::<&[u8]>::buffer_len(buffer_len);
  1935. tx_token.consume(self.now, tx_len, |tx_buffer| {
  1936. debug_assert!(tx_buffer.as_ref().len() == tx_len);
  1937. let mut frame = EthernetFrame::new_unchecked(tx_buffer);
  1938. let src_addr = if let Some(HardwareAddress::Ethernet(addr)) = self.hardware_addr {
  1939. addr
  1940. } else {
  1941. return Err(Error::Malformed);
  1942. };
  1943. frame.set_src_addr(src_addr);
  1944. f(frame);
  1945. Ok(())
  1946. })
  1947. }
  1948. fn in_same_network(&self, addr: &IpAddress) -> bool {
  1949. self.ip_addrs.iter().any(|cidr| cidr.contains_addr(addr))
  1950. }
  1951. fn route(&self, addr: &IpAddress, timestamp: Instant) -> Result<IpAddress> {
  1952. // Send directly.
  1953. if self.in_same_network(addr) || addr.is_broadcast() {
  1954. return Ok(*addr);
  1955. }
  1956. // Route via a router.
  1957. match self.routes.lookup(addr, timestamp) {
  1958. Some(router_addr) => Ok(router_addr),
  1959. None => Err(Error::Unaddressable),
  1960. }
  1961. }
  1962. fn has_neighbor(&self, addr: &IpAddress) -> bool {
  1963. match self.route(addr, self.now) {
  1964. Ok(_routed_addr) => match self.caps.medium {
  1965. #[cfg(feature = "medium-ethernet")]
  1966. Medium::Ethernet => self
  1967. .neighbor_cache
  1968. .as_ref()
  1969. .unwrap()
  1970. .lookup(&_routed_addr, self.now)
  1971. .found(),
  1972. #[cfg(feature = "medium-ieee802154")]
  1973. Medium::Ieee802154 => self
  1974. .neighbor_cache
  1975. .as_ref()
  1976. .unwrap()
  1977. .lookup(&_routed_addr, self.now)
  1978. .found(),
  1979. #[cfg(feature = "medium-ip")]
  1980. Medium::Ip => true,
  1981. },
  1982. Err(_) => false,
  1983. }
  1984. }
  1985. #[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
  1986. fn lookup_hardware_addr<Tx>(
  1987. &mut self,
  1988. tx_token: Tx,
  1989. src_addr: &IpAddress,
  1990. dst_addr: &IpAddress,
  1991. ) -> Result<(HardwareAddress, Tx)>
  1992. where
  1993. Tx: TxToken,
  1994. {
  1995. if dst_addr.is_broadcast() {
  1996. let hardware_addr = match self.caps.medium {
  1997. #[cfg(feature = "medium-ethernet")]
  1998. Medium::Ethernet => HardwareAddress::Ethernet(EthernetAddress::BROADCAST),
  1999. #[cfg(feature = "medium-ieee802154")]
  2000. Medium::Ieee802154 => HardwareAddress::Ieee802154(Ieee802154Address::BROADCAST),
  2001. #[cfg(feature = "medium-ip")]
  2002. Medium::Ip => unreachable!(),
  2003. };
  2004. return Ok((hardware_addr, tx_token));
  2005. }
  2006. if dst_addr.is_multicast() {
  2007. let b = dst_addr.as_bytes();
  2008. let hardware_addr = match *dst_addr {
  2009. #[cfg(feature = "proto-ipv4")]
  2010. IpAddress::Ipv4(_addr) => {
  2011. HardwareAddress::Ethernet(EthernetAddress::from_bytes(&[
  2012. 0x01,
  2013. 0x00,
  2014. 0x5e,
  2015. b[1] & 0x7F,
  2016. b[2],
  2017. b[3],
  2018. ]))
  2019. }
  2020. #[cfg(feature = "proto-ipv6")]
  2021. IpAddress::Ipv6(_addr) => match self.caps.medium {
  2022. #[cfg(feature = "medium-ethernet")]
  2023. Medium::Ethernet => HardwareAddress::Ethernet(EthernetAddress::from_bytes(&[
  2024. 0x33, 0x33, b[12], b[13], b[14], b[15],
  2025. ])),
  2026. #[cfg(feature = "medium-ieee802154")]
  2027. Medium::Ieee802154 => {
  2028. // Not sure if this is correct
  2029. HardwareAddress::Ieee802154(Ieee802154Address::BROADCAST)
  2030. }
  2031. #[cfg(feature = "medium-ip")]
  2032. Medium::Ip => unreachable!(),
  2033. },
  2034. };
  2035. return Ok((hardware_addr, tx_token));
  2036. }
  2037. let dst_addr = self.route(dst_addr, self.now)?;
  2038. match self
  2039. .neighbor_cache
  2040. .as_mut()
  2041. .unwrap()
  2042. .lookup(&dst_addr, self.now)
  2043. {
  2044. NeighborAnswer::Found(hardware_addr) => return Ok((hardware_addr, tx_token)),
  2045. NeighborAnswer::RateLimited => return Err(Error::Unaddressable),
  2046. _ => (), // XXX
  2047. }
  2048. match (src_addr, dst_addr) {
  2049. #[cfg(feature = "proto-ipv4")]
  2050. (&IpAddress::Ipv4(src_addr), IpAddress::Ipv4(dst_addr)) => {
  2051. net_debug!(
  2052. "address {} not in neighbor cache, sending ARP request",
  2053. dst_addr
  2054. );
  2055. let src_hardware_addr =
  2056. if let Some(HardwareAddress::Ethernet(addr)) = self.hardware_addr {
  2057. addr
  2058. } else {
  2059. return Err(Error::Malformed);
  2060. };
  2061. let arp_repr = ArpRepr::EthernetIpv4 {
  2062. operation: ArpOperation::Request,
  2063. source_hardware_addr: src_hardware_addr,
  2064. source_protocol_addr: src_addr,
  2065. target_hardware_addr: EthernetAddress::BROADCAST,
  2066. target_protocol_addr: dst_addr,
  2067. };
  2068. self.dispatch_ethernet(tx_token, arp_repr.buffer_len(), |mut frame| {
  2069. frame.set_dst_addr(EthernetAddress::BROADCAST);
  2070. frame.set_ethertype(EthernetProtocol::Arp);
  2071. arp_repr.emit(&mut ArpPacket::new_unchecked(frame.payload_mut()))
  2072. })?;
  2073. }
  2074. #[cfg(feature = "proto-ipv6")]
  2075. (&IpAddress::Ipv6(src_addr), IpAddress::Ipv6(dst_addr)) => {
  2076. net_debug!(
  2077. "address {} not in neighbor cache, sending Neighbor Solicitation",
  2078. dst_addr
  2079. );
  2080. let solicit = Icmpv6Repr::Ndisc(NdiscRepr::NeighborSolicit {
  2081. target_addr: dst_addr,
  2082. lladdr: Some(self.hardware_addr.unwrap().into()),
  2083. });
  2084. let packet = IpPacket::Icmpv6((
  2085. Ipv6Repr {
  2086. src_addr,
  2087. dst_addr: dst_addr.solicited_node(),
  2088. next_header: IpProtocol::Icmpv6,
  2089. payload_len: solicit.buffer_len(),
  2090. hop_limit: 0xff,
  2091. },
  2092. solicit,
  2093. ));
  2094. self.dispatch_ip(tx_token, packet)?;
  2095. }
  2096. #[allow(unreachable_patterns)]
  2097. _ => (),
  2098. }
  2099. // The request got dispatched, limit the rate on the cache.
  2100. self.neighbor_cache.as_mut().unwrap().limit_rate(self.now);
  2101. Err(Error::Unaddressable)
  2102. }
  2103. fn flush_cache(&mut self) {
  2104. #[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
  2105. if let Some(cache) = self.neighbor_cache.as_mut() {
  2106. cache.flush()
  2107. }
  2108. }
  2109. fn dispatch_ip<Tx: TxToken>(&mut self, tx_token: Tx, packet: IpPacket) -> Result<()> {
  2110. let ip_repr = packet.ip_repr();
  2111. assert!(!ip_repr.dst_addr().is_unspecified());
  2112. match self.caps.medium {
  2113. #[cfg(feature = "medium-ethernet")]
  2114. Medium::Ethernet => {
  2115. let (dst_hardware_addr, tx_token) = match self.lookup_hardware_addr(
  2116. tx_token,
  2117. &ip_repr.src_addr(),
  2118. &ip_repr.dst_addr(),
  2119. )? {
  2120. (HardwareAddress::Ethernet(addr), tx_token) => (addr, tx_token),
  2121. #[cfg(feature = "medium-ieee802154")]
  2122. (HardwareAddress::Ieee802154(_), _) => unreachable!(),
  2123. };
  2124. let caps = self.caps.clone();
  2125. self.dispatch_ethernet(tx_token, ip_repr.total_len(), |mut frame| {
  2126. frame.set_dst_addr(dst_hardware_addr);
  2127. match ip_repr {
  2128. #[cfg(feature = "proto-ipv4")]
  2129. IpRepr::Ipv4(_) => frame.set_ethertype(EthernetProtocol::Ipv4),
  2130. #[cfg(feature = "proto-ipv6")]
  2131. IpRepr::Ipv6(_) => frame.set_ethertype(EthernetProtocol::Ipv6),
  2132. }
  2133. ip_repr.emit(frame.payload_mut(), &caps.checksum);
  2134. let payload = &mut frame.payload_mut()[ip_repr.buffer_len()..];
  2135. packet.emit_payload(ip_repr, payload, &caps);
  2136. })
  2137. }
  2138. #[cfg(feature = "medium-ip")]
  2139. Medium::Ip => {
  2140. let tx_len = ip_repr.total_len();
  2141. tx_token.consume(self.now, tx_len, |mut tx_buffer| {
  2142. debug_assert!(tx_buffer.as_ref().len() == tx_len);
  2143. ip_repr.emit(&mut tx_buffer, &self.caps.checksum);
  2144. let payload = &mut tx_buffer[ip_repr.buffer_len()..];
  2145. packet.emit_payload(ip_repr, payload, &self.caps);
  2146. Ok(())
  2147. })
  2148. }
  2149. #[cfg(feature = "medium-ieee802154")]
  2150. Medium::Ieee802154 => self.dispatch_ieee802154(tx_token, packet),
  2151. }
  2152. }
  2153. #[cfg(feature = "medium-ieee802154")]
  2154. fn dispatch_ieee802154<Tx: TxToken>(&mut self, tx_token: Tx, packet: IpPacket) -> Result<()> {
  2155. let ip_repr = packet.ip_repr();
  2156. assert!(!ip_repr.dst_addr().is_unspecified());
  2157. match self.caps.medium {
  2158. #[cfg(feature = "medium-ieee802154")]
  2159. Medium::Ieee802154 => {
  2160. let (dst_hardware_addr, tx_token) = match self.lookup_hardware_addr(
  2161. tx_token,
  2162. &ip_repr.src_addr(),
  2163. &ip_repr.dst_addr(),
  2164. )? {
  2165. (HardwareAddress::Ieee802154(addr), tx_token) => (addr, tx_token),
  2166. _ => unreachable!(),
  2167. };
  2168. let ack_request = dst_hardware_addr.is_unicast();
  2169. let ack_request = match packet {
  2170. IpPacket::Icmpv6(_) => false,
  2171. _ => ack_request,
  2172. };
  2173. let mut tx_len = 0;
  2174. let ll_src_addr =
  2175. if let Some(HardwareAddress::Ieee802154(addr)) = self.hardware_addr {
  2176. Some(addr)
  2177. } else {
  2178. return Err(Error::Malformed);
  2179. };
  2180. let ieee_repr = Ieee802154Repr {
  2181. frame_type: Ieee802154FrameType::Data,
  2182. security_enabled: false,
  2183. frame_pending: false,
  2184. ack_request,
  2185. sequence_number: Some(self.get_sequence_number()),
  2186. pan_id_compression: true,
  2187. frame_version: Ieee802154FrameVersion::Ieee802154_2003,
  2188. dst_pan_id: self.pan_id,
  2189. dst_addr: Some(dst_hardware_addr),
  2190. src_pan_id: self.pan_id,
  2191. src_addr: ll_src_addr,
  2192. };
  2193. let (src_addr, dst_addr) = match (ip_repr.src_addr(), ip_repr.dst_addr()) {
  2194. (IpAddress::Ipv6(src_addr), IpAddress::Ipv6(dst_addr)) => (src_addr, dst_addr),
  2195. #[allow(unreachable_patterns)]
  2196. _ => return Err(Error::Unaddressable),
  2197. };
  2198. #[allow(unreachable_patterns)]
  2199. let (next_header, hop_limit) = match &packet {
  2200. #[cfg(feature = "socket-udp")]
  2201. IpPacket::Udp(_) => (SixlowpanNextHeader::Compressed, 64),
  2202. IpPacket::Icmpv6((_, repr)) => (
  2203. SixlowpanNextHeader::Uncompressed(IpProtocol::Icmpv6),
  2204. match repr {
  2205. Icmpv6Repr::Ndisc(_) => 255,
  2206. _ => 64,
  2207. },
  2208. ),
  2209. _ => return Err(Error::Unrecognized),
  2210. };
  2211. let iphc_repr = SixlowpanIphcRepr {
  2212. src_addr,
  2213. ll_src_addr,
  2214. dst_addr,
  2215. ll_dst_addr: Some(dst_hardware_addr),
  2216. next_header,
  2217. hop_limit,
  2218. };
  2219. tx_len += ieee_repr.buffer_len();
  2220. tx_len += iphc_repr.buffer_len();
  2221. #[allow(unreachable_patterns)]
  2222. match &packet {
  2223. #[cfg(feature = "socket-udp")]
  2224. IpPacket::Udp((_, udp_repr, payload)) => {
  2225. let udp_repr = SixlowpanUdpRepr(*udp_repr);
  2226. tx_len += udp_repr.header_len() + payload.len();
  2227. }
  2228. IpPacket::Icmpv6((_, icmp)) => {
  2229. tx_len += icmp.buffer_len();
  2230. }
  2231. _ => return Err(Error::Unrecognized),
  2232. }
  2233. tx_token.consume(self.now, tx_len, |mut tx_buffer| {
  2234. // 1. Create the header of 802.15.4
  2235. let mut ieee_packet = Ieee802154Frame::new_unchecked(&mut tx_buffer);
  2236. ieee_repr.emit(&mut ieee_packet);
  2237. let mut start = ieee_repr.buffer_len();
  2238. // 2. Create the header for 6LoWPAN IPHC
  2239. let mut iphc_packet =
  2240. SixlowpanIphcPacket::new_unchecked(&mut tx_buffer[start..tx_len]);
  2241. iphc_repr.emit(&mut iphc_packet);
  2242. start += iphc_repr.buffer_len();
  2243. #[allow(unreachable_patterns)]
  2244. match packet {
  2245. #[cfg(feature = "socket-udp")]
  2246. IpPacket::Udp((_, udp_repr, payload)) => {
  2247. // 3. Create the header for 6LoWPAN UDP
  2248. let mut udp_packet =
  2249. SixlowpanUdpPacket::new_unchecked(&mut tx_buffer[start..tx_len]);
  2250. SixlowpanUdpRepr(udp_repr).emit(
  2251. &mut udp_packet,
  2252. &iphc_repr.src_addr,
  2253. &iphc_repr.dst_addr,
  2254. payload.len(),
  2255. |buf| buf.copy_from_slice(payload),
  2256. );
  2257. }
  2258. #[cfg(feature = "proto-ipv6")]
  2259. IpPacket::Icmpv6((_, icmp_repr)) => {
  2260. // 3. Create the header for ICMPv6
  2261. let mut icmp_packet =
  2262. Icmpv6Packet::new_unchecked(&mut tx_buffer[start..tx_len]);
  2263. icmp_repr.emit(
  2264. &iphc_repr.src_addr.into(),
  2265. &iphc_repr.dst_addr.into(),
  2266. &mut icmp_packet,
  2267. &self.caps.checksum,
  2268. );
  2269. }
  2270. _ => return Err(Error::Unrecognized),
  2271. }
  2272. Ok(())
  2273. })
  2274. }
  2275. #[allow(unreachable_patterns)]
  2276. _ => Err(Error::NotSupported),
  2277. }
  2278. }
  2279. #[cfg(feature = "proto-igmp")]
  2280. fn igmp_report_packet<'any>(
  2281. &self,
  2282. version: IgmpVersion,
  2283. group_addr: Ipv4Address,
  2284. ) -> Option<IpPacket<'any>> {
  2285. let iface_addr = self.ipv4_address()?;
  2286. let igmp_repr = IgmpRepr::MembershipReport {
  2287. group_addr,
  2288. version,
  2289. };
  2290. let pkt = IpPacket::Igmp((
  2291. Ipv4Repr {
  2292. src_addr: iface_addr,
  2293. // Send to the group being reported
  2294. dst_addr: group_addr,
  2295. next_header: IpProtocol::Igmp,
  2296. payload_len: igmp_repr.buffer_len(),
  2297. hop_limit: 1,
  2298. // TODO: add Router Alert IPv4 header option. See
  2299. // [#183](https://github.com/m-labs/smoltcp/issues/183).
  2300. },
  2301. igmp_repr,
  2302. ));
  2303. Some(pkt)
  2304. }
  2305. #[cfg(feature = "proto-igmp")]
  2306. fn igmp_leave_packet<'any>(&self, group_addr: Ipv4Address) -> Option<IpPacket<'any>> {
  2307. self.ipv4_address().map(|iface_addr| {
  2308. let igmp_repr = IgmpRepr::LeaveGroup { group_addr };
  2309. IpPacket::Igmp((
  2310. Ipv4Repr {
  2311. src_addr: iface_addr,
  2312. dst_addr: Ipv4Address::MULTICAST_ALL_ROUTERS,
  2313. next_header: IpProtocol::Igmp,
  2314. payload_len: igmp_repr.buffer_len(),
  2315. hop_limit: 1,
  2316. },
  2317. igmp_repr,
  2318. ))
  2319. })
  2320. }
  2321. }
  2322. #[cfg(test)]
  2323. mod test {
  2324. use std::collections::BTreeMap;
  2325. #[cfg(feature = "proto-igmp")]
  2326. use std::vec::Vec;
  2327. use super::*;
  2328. use crate::iface::Interface;
  2329. #[cfg(feature = "medium-ethernet")]
  2330. use crate::iface::NeighborCache;
  2331. use crate::phy::{ChecksumCapabilities, Loopback};
  2332. #[cfg(feature = "proto-igmp")]
  2333. use crate::time::Instant;
  2334. use crate::{Error, Result};
  2335. #[allow(unused)]
  2336. fn fill_slice(s: &mut [u8], val: u8) {
  2337. for x in s.iter_mut() {
  2338. *x = val
  2339. }
  2340. }
  2341. fn create<'a>() -> (Interface<'a>, SocketSet<'a>, Loopback) {
  2342. #[cfg(feature = "medium-ethernet")]
  2343. return create_ethernet();
  2344. #[cfg(not(feature = "medium-ethernet"))]
  2345. return create_ip();
  2346. }
  2347. #[cfg(all(feature = "medium-ip"))]
  2348. #[allow(unused)]
  2349. fn create_ip<'a>() -> (Interface<'a>, SocketSet<'a>, Loopback) {
  2350. // Create a basic device
  2351. let mut device = Loopback::new(Medium::Ip);
  2352. let ip_addrs = [
  2353. #[cfg(feature = "proto-ipv4")]
  2354. IpCidr::new(IpAddress::v4(127, 0, 0, 1), 8),
  2355. #[cfg(feature = "proto-ipv6")]
  2356. IpCidr::new(IpAddress::v6(0, 0, 0, 0, 0, 0, 0, 1), 128),
  2357. #[cfg(feature = "proto-ipv6")]
  2358. IpCidr::new(IpAddress::v6(0xfdbe, 0, 0, 0, 0, 0, 0, 1), 64),
  2359. ];
  2360. let iface_builder = InterfaceBuilder::new().ip_addrs(ip_addrs);
  2361. #[cfg(feature = "proto-igmp")]
  2362. let iface_builder = iface_builder.ipv4_multicast_groups(BTreeMap::new());
  2363. let iface = iface_builder.finalize(&mut device);
  2364. (iface, SocketSet::new(vec![]), device)
  2365. }
  2366. #[cfg(all(feature = "medium-ethernet"))]
  2367. fn create_ethernet<'a>() -> (Interface<'a>, SocketSet<'a>, Loopback) {
  2368. // Create a basic device
  2369. let mut device = Loopback::new(Medium::Ethernet);
  2370. let ip_addrs = [
  2371. #[cfg(feature = "proto-ipv4")]
  2372. IpCidr::new(IpAddress::v4(127, 0, 0, 1), 8),
  2373. #[cfg(feature = "proto-ipv6")]
  2374. IpCidr::new(IpAddress::v6(0, 0, 0, 0, 0, 0, 0, 1), 128),
  2375. #[cfg(feature = "proto-ipv6")]
  2376. IpCidr::new(IpAddress::v6(0xfdbe, 0, 0, 0, 0, 0, 0, 1), 64),
  2377. ];
  2378. let iface_builder = InterfaceBuilder::new()
  2379. .hardware_addr(EthernetAddress::default().into())
  2380. .neighbor_cache(NeighborCache::new(BTreeMap::new()))
  2381. .ip_addrs(ip_addrs);
  2382. #[cfg(feature = "proto-igmp")]
  2383. let iface_builder = iface_builder.ipv4_multicast_groups(BTreeMap::new());
  2384. let iface = iface_builder.finalize(&mut device);
  2385. (iface, SocketSet::new(vec![]), device)
  2386. }
  2387. #[cfg(feature = "proto-igmp")]
  2388. fn recv_all(device: &mut Loopback, timestamp: Instant) -> Vec<Vec<u8>> {
  2389. let mut pkts = Vec::new();
  2390. while let Some((rx, _tx)) = device.receive() {
  2391. rx.consume(timestamp, |pkt| {
  2392. pkts.push(pkt.to_vec());
  2393. Ok(())
  2394. })
  2395. .unwrap();
  2396. }
  2397. pkts
  2398. }
  2399. #[derive(Debug, PartialEq)]
  2400. #[cfg_attr(feature = "defmt", derive(defmt::Format))]
  2401. struct MockTxToken;
  2402. impl TxToken for MockTxToken {
  2403. fn consume<R, F>(self, _: Instant, _: usize, _: F) -> Result<R>
  2404. where
  2405. F: FnOnce(&mut [u8]) -> Result<R>,
  2406. {
  2407. Err(Error::Unaddressable)
  2408. }
  2409. }
  2410. #[test]
  2411. #[should_panic(expected = "hardware_addr required option was not set")]
  2412. #[cfg(all(feature = "medium-ethernet"))]
  2413. fn test_builder_initialization_panic() {
  2414. let mut device = Loopback::new(Medium::Ethernet);
  2415. InterfaceBuilder::new().finalize(&mut device);
  2416. }
  2417. #[test]
  2418. #[cfg(feature = "proto-ipv4")]
  2419. fn test_no_icmp_no_unicast_ipv4() {
  2420. let (mut iface, mut sockets, _device) = create();
  2421. // Unknown Ipv4 Protocol
  2422. //
  2423. // Because the destination is the broadcast address
  2424. // this should not trigger and Destination Unreachable
  2425. // response. See RFC 1122 § 3.2.2.
  2426. let repr = IpRepr::Ipv4(Ipv4Repr {
  2427. src_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x01]),
  2428. dst_addr: Ipv4Address::BROADCAST,
  2429. next_header: IpProtocol::Unknown(0x0c),
  2430. payload_len: 0,
  2431. hop_limit: 0x40,
  2432. });
  2433. let mut bytes = vec![0u8; 54];
  2434. repr.emit(&mut bytes, &ChecksumCapabilities::default());
  2435. let frame = Ipv4Packet::new_unchecked(&bytes);
  2436. // Ensure that the unknown protocol frame does not trigger an
  2437. // ICMP error response when the destination address is a
  2438. // broadcast address
  2439. assert_eq!(iface.process_ipv4(&mut sockets, &frame), None);
  2440. }
  2441. #[test]
  2442. #[cfg(feature = "proto-ipv6")]
  2443. fn test_no_icmp_no_unicast_ipv6() {
  2444. let (mut iface, mut sockets, _device) = create();
  2445. // Unknown Ipv6 Protocol
  2446. //
  2447. // Because the destination is the broadcast address
  2448. // this should not trigger and Destination Unreachable
  2449. // response. See RFC 1122 § 3.2.2.
  2450. let repr = IpRepr::Ipv6(Ipv6Repr {
  2451. src_addr: Ipv6Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 1),
  2452. dst_addr: Ipv6Address::LINK_LOCAL_ALL_NODES,
  2453. next_header: IpProtocol::Unknown(0x0c),
  2454. payload_len: 0,
  2455. hop_limit: 0x40,
  2456. });
  2457. let mut bytes = vec![0u8; 54];
  2458. repr.emit(&mut bytes, &ChecksumCapabilities::default());
  2459. let frame = Ipv6Packet::new_unchecked(&bytes);
  2460. // Ensure that the unknown protocol frame does not trigger an
  2461. // ICMP error response when the destination address is a
  2462. // broadcast address
  2463. assert_eq!(iface.process_ipv6(&mut sockets, &frame), None);
  2464. }
  2465. #[test]
  2466. #[cfg(feature = "proto-ipv4")]
  2467. fn test_icmp_error_no_payload() {
  2468. static NO_BYTES: [u8; 0] = [];
  2469. let (mut iface, mut sockets, _device) = create();
  2470. // Unknown Ipv4 Protocol with no payload
  2471. let repr = IpRepr::Ipv4(Ipv4Repr {
  2472. src_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x02]),
  2473. dst_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x01]),
  2474. next_header: IpProtocol::Unknown(0x0c),
  2475. payload_len: 0,
  2476. hop_limit: 0x40,
  2477. });
  2478. let mut bytes = vec![0u8; 34];
  2479. repr.emit(&mut bytes, &ChecksumCapabilities::default());
  2480. let frame = Ipv4Packet::new_unchecked(&bytes);
  2481. // The expected Destination Unreachable response due to the
  2482. // unknown protocol
  2483. let icmp_repr = Icmpv4Repr::DstUnreachable {
  2484. reason: Icmpv4DstUnreachable::ProtoUnreachable,
  2485. header: Ipv4Repr {
  2486. src_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x02]),
  2487. dst_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x01]),
  2488. next_header: IpProtocol::Unknown(12),
  2489. payload_len: 0,
  2490. hop_limit: 64,
  2491. },
  2492. data: &NO_BYTES,
  2493. };
  2494. let expected_repr = IpPacket::Icmpv4((
  2495. Ipv4Repr {
  2496. src_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x01]),
  2497. dst_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x02]),
  2498. next_header: IpProtocol::Icmp,
  2499. payload_len: icmp_repr.buffer_len(),
  2500. hop_limit: 64,
  2501. },
  2502. icmp_repr,
  2503. ));
  2504. // Ensure that the unknown protocol triggers an error response.
  2505. // And we correctly handle no payload.
  2506. assert_eq!(
  2507. iface.process_ipv4(&mut sockets, &frame),
  2508. Some(expected_repr)
  2509. );
  2510. }
  2511. #[test]
  2512. #[cfg(feature = "proto-ipv4")]
  2513. fn test_local_subnet_broadcasts() {
  2514. let (mut iface, _, _device) = create();
  2515. iface.update_ip_addrs(|addrs| {
  2516. addrs.iter_mut().next().map(|addr| {
  2517. *addr = IpCidr::Ipv4(Ipv4Cidr::new(Ipv4Address([192, 168, 1, 23]), 24));
  2518. });
  2519. });
  2520. assert!(iface.is_subnet_broadcast(Ipv4Address([192, 168, 1, 255])),);
  2521. assert!(!iface.is_subnet_broadcast(Ipv4Address([192, 168, 1, 254])),);
  2522. iface.update_ip_addrs(|addrs| {
  2523. addrs.iter_mut().next().map(|addr| {
  2524. *addr = IpCidr::Ipv4(Ipv4Cidr::new(Ipv4Address([192, 168, 23, 24]), 16));
  2525. });
  2526. });
  2527. assert!(!iface.is_subnet_broadcast(Ipv4Address([192, 168, 23, 255])),);
  2528. assert!(!iface.is_subnet_broadcast(Ipv4Address([192, 168, 23, 254])),);
  2529. assert!(!iface.is_subnet_broadcast(Ipv4Address([192, 168, 255, 254])),);
  2530. assert!(iface.is_subnet_broadcast(Ipv4Address([192, 168, 255, 255])),);
  2531. iface.update_ip_addrs(|addrs| {
  2532. addrs.iter_mut().next().map(|addr| {
  2533. *addr = IpCidr::Ipv4(Ipv4Cidr::new(Ipv4Address([192, 168, 23, 24]), 8));
  2534. });
  2535. });
  2536. assert!(!iface.is_subnet_broadcast(Ipv4Address([192, 23, 1, 255])),);
  2537. assert!(!iface.is_subnet_broadcast(Ipv4Address([192, 23, 1, 254])),);
  2538. assert!(!iface.is_subnet_broadcast(Ipv4Address([192, 255, 255, 254])),);
  2539. assert!(iface.is_subnet_broadcast(Ipv4Address([192, 255, 255, 255])),);
  2540. }
  2541. #[test]
  2542. #[cfg(all(feature = "socket-udp", feature = "proto-ipv4"))]
  2543. fn test_icmp_error_port_unreachable() {
  2544. static UDP_PAYLOAD: [u8; 12] = [
  2545. 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x57, 0x6f, 0x6c, 0x64, 0x21,
  2546. ];
  2547. let (mut iface, mut sockets, _device) = create();
  2548. let mut udp_bytes_unicast = vec![0u8; 20];
  2549. let mut udp_bytes_broadcast = vec![0u8; 20];
  2550. let mut packet_unicast = UdpPacket::new_unchecked(&mut udp_bytes_unicast);
  2551. let mut packet_broadcast = UdpPacket::new_unchecked(&mut udp_bytes_broadcast);
  2552. let udp_repr = UdpRepr {
  2553. src_port: 67,
  2554. dst_port: 68,
  2555. };
  2556. let ip_repr = IpRepr::Ipv4(Ipv4Repr {
  2557. src_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x02]),
  2558. dst_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x01]),
  2559. next_header: IpProtocol::Udp,
  2560. payload_len: udp_repr.header_len() + UDP_PAYLOAD.len(),
  2561. hop_limit: 64,
  2562. });
  2563. // Emit the representations to a packet
  2564. udp_repr.emit(
  2565. &mut packet_unicast,
  2566. &ip_repr.src_addr(),
  2567. &ip_repr.dst_addr(),
  2568. UDP_PAYLOAD.len(),
  2569. |buf| buf.copy_from_slice(&UDP_PAYLOAD),
  2570. &ChecksumCapabilities::default(),
  2571. );
  2572. let data = packet_unicast.into_inner();
  2573. // The expected Destination Unreachable ICMPv4 error response due
  2574. // to no sockets listening on the destination port.
  2575. let icmp_repr = Icmpv4Repr::DstUnreachable {
  2576. reason: Icmpv4DstUnreachable::PortUnreachable,
  2577. header: Ipv4Repr {
  2578. src_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x02]),
  2579. dst_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x01]),
  2580. next_header: IpProtocol::Udp,
  2581. payload_len: udp_repr.header_len() + UDP_PAYLOAD.len(),
  2582. hop_limit: 64,
  2583. },
  2584. data: data,
  2585. };
  2586. let expected_repr = IpPacket::Icmpv4((
  2587. Ipv4Repr {
  2588. src_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x01]),
  2589. dst_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x02]),
  2590. next_header: IpProtocol::Icmp,
  2591. payload_len: icmp_repr.buffer_len(),
  2592. hop_limit: 64,
  2593. },
  2594. icmp_repr,
  2595. ));
  2596. // Ensure that the unknown protocol triggers an error response.
  2597. // And we correctly handle no payload.
  2598. assert_eq!(
  2599. iface.process_udp(&mut sockets, ip_repr, false, data),
  2600. Some(expected_repr)
  2601. );
  2602. let ip_repr = IpRepr::Ipv4(Ipv4Repr {
  2603. src_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x02]),
  2604. dst_addr: Ipv4Address::BROADCAST,
  2605. next_header: IpProtocol::Udp,
  2606. payload_len: udp_repr.header_len() + UDP_PAYLOAD.len(),
  2607. hop_limit: 64,
  2608. });
  2609. // Emit the representations to a packet
  2610. udp_repr.emit(
  2611. &mut packet_broadcast,
  2612. &ip_repr.src_addr(),
  2613. &IpAddress::Ipv4(Ipv4Address::BROADCAST),
  2614. UDP_PAYLOAD.len(),
  2615. |buf| buf.copy_from_slice(&UDP_PAYLOAD),
  2616. &ChecksumCapabilities::default(),
  2617. );
  2618. // Ensure that the port unreachable error does not trigger an
  2619. // ICMP error response when the destination address is a
  2620. // broadcast address and no socket is bound to the port.
  2621. assert_eq!(
  2622. iface.process_udp(&mut sockets, ip_repr, false, packet_broadcast.into_inner()),
  2623. None
  2624. );
  2625. }
  2626. #[test]
  2627. #[cfg(feature = "socket-udp")]
  2628. fn test_handle_udp_broadcast() {
  2629. use crate::wire::IpEndpoint;
  2630. static UDP_PAYLOAD: [u8; 5] = [0x48, 0x65, 0x6c, 0x6c, 0x6f];
  2631. let (mut iface, mut sockets, _device) = create();
  2632. let rx_buffer = udp::PacketBuffer::new(vec![udp::PacketMetadata::EMPTY], vec![0; 15]);
  2633. let tx_buffer = udp::PacketBuffer::new(vec![udp::PacketMetadata::EMPTY], vec![0; 15]);
  2634. let udp_socket = udp::Socket::new(rx_buffer, tx_buffer);
  2635. let mut udp_bytes = vec![0u8; 13];
  2636. let mut packet = UdpPacket::new_unchecked(&mut udp_bytes);
  2637. let socket_handle = sockets.add(udp_socket);
  2638. #[cfg(feature = "proto-ipv6")]
  2639. let src_ip = Ipv6Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 1);
  2640. #[cfg(all(not(feature = "proto-ipv6"), feature = "proto-ipv4"))]
  2641. let src_ip = Ipv4Address::new(0x7f, 0x00, 0x00, 0x02);
  2642. let udp_repr = UdpRepr {
  2643. src_port: 67,
  2644. dst_port: 68,
  2645. };
  2646. #[cfg(feature = "proto-ipv6")]
  2647. let ip_repr = IpRepr::Ipv6(Ipv6Repr {
  2648. src_addr: src_ip,
  2649. dst_addr: Ipv6Address::LINK_LOCAL_ALL_NODES,
  2650. next_header: IpProtocol::Udp,
  2651. payload_len: udp_repr.header_len() + UDP_PAYLOAD.len(),
  2652. hop_limit: 0x40,
  2653. });
  2654. #[cfg(all(not(feature = "proto-ipv6"), feature = "proto-ipv4"))]
  2655. let ip_repr = IpRepr::Ipv4(Ipv4Repr {
  2656. src_addr: src_ip,
  2657. dst_addr: Ipv4Address::BROADCAST,
  2658. next_header: IpProtocol::Udp,
  2659. payload_len: udp_repr.header_len() + UDP_PAYLOAD.len(),
  2660. hop_limit: 0x40,
  2661. });
  2662. // Bind the socket to port 68
  2663. let socket = sockets.get_mut::<udp::Socket>(socket_handle);
  2664. assert_eq!(socket.bind(68), Ok(()));
  2665. assert!(!socket.can_recv());
  2666. assert!(socket.can_send());
  2667. udp_repr.emit(
  2668. &mut packet,
  2669. &ip_repr.src_addr(),
  2670. &ip_repr.dst_addr(),
  2671. UDP_PAYLOAD.len(),
  2672. |buf| buf.copy_from_slice(&UDP_PAYLOAD),
  2673. &ChecksumCapabilities::default(),
  2674. );
  2675. // Packet should be handled by bound UDP socket
  2676. assert_eq!(
  2677. iface.process_udp(&mut sockets, ip_repr, false, packet.into_inner()),
  2678. None
  2679. );
  2680. // Make sure the payload to the UDP packet processed by process_udp is
  2681. // appended to the bound sockets rx_buffer
  2682. let socket = sockets.get_mut::<udp::Socket>(socket_handle);
  2683. assert!(socket.can_recv());
  2684. assert_eq!(
  2685. socket.recv(),
  2686. Ok((&UDP_PAYLOAD[..], IpEndpoint::new(src_ip.into(), 67)))
  2687. );
  2688. }
  2689. #[test]
  2690. #[cfg(feature = "proto-ipv4")]
  2691. fn test_handle_ipv4_broadcast() {
  2692. use crate::wire::{Icmpv4Packet, Icmpv4Repr, Ipv4Packet};
  2693. let (mut iface, mut sockets, _device) = create();
  2694. let our_ipv4_addr = iface.ipv4_address().unwrap();
  2695. let src_ipv4_addr = Ipv4Address([127, 0, 0, 2]);
  2696. // ICMPv4 echo request
  2697. let icmpv4_data: [u8; 4] = [0xaa, 0x00, 0x00, 0xff];
  2698. let icmpv4_repr = Icmpv4Repr::EchoRequest {
  2699. ident: 0x1234,
  2700. seq_no: 0xabcd,
  2701. data: &icmpv4_data,
  2702. };
  2703. // Send to IPv4 broadcast address
  2704. let ipv4_repr = Ipv4Repr {
  2705. src_addr: src_ipv4_addr,
  2706. dst_addr: Ipv4Address::BROADCAST,
  2707. next_header: IpProtocol::Icmp,
  2708. hop_limit: 64,
  2709. payload_len: icmpv4_repr.buffer_len(),
  2710. };
  2711. // Emit to ip frame
  2712. let mut bytes = vec![0u8; ipv4_repr.buffer_len() + icmpv4_repr.buffer_len()];
  2713. let frame = {
  2714. ipv4_repr.emit(
  2715. &mut Ipv4Packet::new_unchecked(&mut bytes),
  2716. &ChecksumCapabilities::default(),
  2717. );
  2718. icmpv4_repr.emit(
  2719. &mut Icmpv4Packet::new_unchecked(&mut bytes[ipv4_repr.buffer_len()..]),
  2720. &ChecksumCapabilities::default(),
  2721. );
  2722. Ipv4Packet::new_unchecked(&bytes)
  2723. };
  2724. // Expected ICMPv4 echo reply
  2725. let expected_icmpv4_repr = Icmpv4Repr::EchoReply {
  2726. ident: 0x1234,
  2727. seq_no: 0xabcd,
  2728. data: &icmpv4_data,
  2729. };
  2730. let expected_ipv4_repr = Ipv4Repr {
  2731. src_addr: our_ipv4_addr,
  2732. dst_addr: src_ipv4_addr,
  2733. next_header: IpProtocol::Icmp,
  2734. hop_limit: 64,
  2735. payload_len: expected_icmpv4_repr.buffer_len(),
  2736. };
  2737. let expected_packet = IpPacket::Icmpv4((expected_ipv4_repr, expected_icmpv4_repr));
  2738. assert_eq!(
  2739. iface.process_ipv4(&mut sockets, &frame),
  2740. Some(expected_packet)
  2741. );
  2742. }
  2743. #[test]
  2744. #[cfg(feature = "socket-udp")]
  2745. fn test_icmp_reply_size() {
  2746. #[cfg(feature = "proto-ipv6")]
  2747. use crate::wire::Icmpv6DstUnreachable;
  2748. #[cfg(all(feature = "proto-ipv4", not(feature = "proto-ipv6")))]
  2749. use crate::wire::IPV4_MIN_MTU as MIN_MTU;
  2750. #[cfg(feature = "proto-ipv6")]
  2751. use crate::wire::IPV6_MIN_MTU as MIN_MTU;
  2752. #[cfg(all(feature = "proto-ipv4", not(feature = "proto-ipv6")))]
  2753. const MAX_PAYLOAD_LEN: usize = 528;
  2754. #[cfg(feature = "proto-ipv6")]
  2755. const MAX_PAYLOAD_LEN: usize = 1192;
  2756. let (mut iface, mut sockets, _device) = create();
  2757. #[cfg(all(feature = "proto-ipv4", not(feature = "proto-ipv6")))]
  2758. let src_addr = Ipv4Address([192, 168, 1, 1]);
  2759. #[cfg(all(feature = "proto-ipv4", not(feature = "proto-ipv6")))]
  2760. let dst_addr = Ipv4Address([192, 168, 1, 2]);
  2761. #[cfg(feature = "proto-ipv6")]
  2762. let src_addr = Ipv6Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 1);
  2763. #[cfg(feature = "proto-ipv6")]
  2764. let dst_addr = Ipv6Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 2);
  2765. // UDP packet that if not tructated will cause a icmp port unreachable reply
  2766. // to exeed the minimum mtu bytes in length.
  2767. let udp_repr = UdpRepr {
  2768. src_port: 67,
  2769. dst_port: 68,
  2770. };
  2771. let mut bytes = vec![0xff; udp_repr.header_len() + MAX_PAYLOAD_LEN];
  2772. let mut packet = UdpPacket::new_unchecked(&mut bytes[..]);
  2773. udp_repr.emit(
  2774. &mut packet,
  2775. &src_addr.into(),
  2776. &dst_addr.into(),
  2777. MAX_PAYLOAD_LEN,
  2778. |buf| fill_slice(buf, 0x2a),
  2779. &ChecksumCapabilities::default(),
  2780. );
  2781. #[cfg(all(feature = "proto-ipv4", not(feature = "proto-ipv6")))]
  2782. let ip_repr = Ipv4Repr {
  2783. src_addr: src_addr,
  2784. dst_addr: dst_addr,
  2785. next_header: IpProtocol::Udp,
  2786. hop_limit: 64,
  2787. payload_len: udp_repr.header_len() + MAX_PAYLOAD_LEN,
  2788. };
  2789. #[cfg(feature = "proto-ipv6")]
  2790. let ip_repr = Ipv6Repr {
  2791. src_addr: src_addr,
  2792. dst_addr: dst_addr,
  2793. next_header: IpProtocol::Udp,
  2794. hop_limit: 64,
  2795. payload_len: udp_repr.header_len() + MAX_PAYLOAD_LEN,
  2796. };
  2797. let payload = packet.into_inner();
  2798. // Expected packets
  2799. #[cfg(feature = "proto-ipv6")]
  2800. let expected_icmp_repr = Icmpv6Repr::DstUnreachable {
  2801. reason: Icmpv6DstUnreachable::PortUnreachable,
  2802. header: ip_repr,
  2803. data: &payload[..MAX_PAYLOAD_LEN],
  2804. };
  2805. #[cfg(feature = "proto-ipv6")]
  2806. let expected_ip_repr = Ipv6Repr {
  2807. src_addr: dst_addr,
  2808. dst_addr: src_addr,
  2809. next_header: IpProtocol::Icmpv6,
  2810. hop_limit: 64,
  2811. payload_len: expected_icmp_repr.buffer_len(),
  2812. };
  2813. #[cfg(all(feature = "proto-ipv4", not(feature = "proto-ipv6")))]
  2814. let expected_icmp_repr = Icmpv4Repr::DstUnreachable {
  2815. reason: Icmpv4DstUnreachable::PortUnreachable,
  2816. header: ip_repr,
  2817. data: &payload[..MAX_PAYLOAD_LEN],
  2818. };
  2819. #[cfg(all(feature = "proto-ipv4", not(feature = "proto-ipv6")))]
  2820. let expected_ip_repr = Ipv4Repr {
  2821. src_addr: dst_addr,
  2822. dst_addr: src_addr,
  2823. next_header: IpProtocol::Icmp,
  2824. hop_limit: 64,
  2825. payload_len: expected_icmp_repr.buffer_len(),
  2826. };
  2827. // The expected packet does not exceed the IPV4_MIN_MTU
  2828. #[cfg(feature = "proto-ipv6")]
  2829. assert_eq!(
  2830. expected_ip_repr.buffer_len() + expected_icmp_repr.buffer_len(),
  2831. MIN_MTU
  2832. );
  2833. // The expected packet does not exceed the IPV4_MIN_MTU
  2834. #[cfg(all(feature = "proto-ipv4", not(feature = "proto-ipv6")))]
  2835. assert_eq!(
  2836. expected_ip_repr.buffer_len() + expected_icmp_repr.buffer_len(),
  2837. MIN_MTU
  2838. );
  2839. // The expected packet and the generated packet are equal
  2840. #[cfg(all(feature = "proto-ipv4", not(feature = "proto-ipv6")))]
  2841. assert_eq!(
  2842. iface.process_udp(&mut sockets, ip_repr.into(), false, payload),
  2843. Some(IpPacket::Icmpv4((expected_ip_repr, expected_icmp_repr)))
  2844. );
  2845. #[cfg(feature = "proto-ipv6")]
  2846. assert_eq!(
  2847. iface.process_udp(&mut sockets, ip_repr.into(), false, payload),
  2848. Some(IpPacket::Icmpv6((expected_ip_repr, expected_icmp_repr)))
  2849. );
  2850. }
  2851. #[test]
  2852. #[cfg(all(feature = "medium-ethernet", feature = "proto-ipv4"))]
  2853. fn test_handle_valid_arp_request() {
  2854. let (mut iface, mut sockets, _device) = create_ethernet();
  2855. let mut eth_bytes = vec![0u8; 42];
  2856. let local_ip_addr = Ipv4Address([0x7f, 0x00, 0x00, 0x01]);
  2857. let remote_ip_addr = Ipv4Address([0x7f, 0x00, 0x00, 0x02]);
  2858. let local_hw_addr = EthernetAddress([0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
  2859. let remote_hw_addr = EthernetAddress([0x52, 0x54, 0x00, 0x00, 0x00, 0x00]);
  2860. let repr = ArpRepr::EthernetIpv4 {
  2861. operation: ArpOperation::Request,
  2862. source_hardware_addr: remote_hw_addr,
  2863. source_protocol_addr: remote_ip_addr,
  2864. target_hardware_addr: EthernetAddress::default(),
  2865. target_protocol_addr: local_ip_addr,
  2866. };
  2867. let mut frame = EthernetFrame::new_unchecked(&mut eth_bytes);
  2868. frame.set_dst_addr(EthernetAddress::BROADCAST);
  2869. frame.set_src_addr(remote_hw_addr);
  2870. frame.set_ethertype(EthernetProtocol::Arp);
  2871. let mut packet = ArpPacket::new_unchecked(frame.payload_mut());
  2872. repr.emit(&mut packet);
  2873. // Ensure an ARP Request for us triggers an ARP Reply
  2874. assert_eq!(
  2875. iface.process_ethernet(&mut sockets, frame.into_inner()),
  2876. Some(EthernetPacket::Arp(ArpRepr::EthernetIpv4 {
  2877. operation: ArpOperation::Reply,
  2878. source_hardware_addr: local_hw_addr,
  2879. source_protocol_addr: local_ip_addr,
  2880. target_hardware_addr: remote_hw_addr,
  2881. target_protocol_addr: remote_ip_addr
  2882. }))
  2883. );
  2884. // Ensure the address of the requestor was entered in the cache
  2885. assert_eq!(
  2886. iface.lookup_hardware_addr(
  2887. MockTxToken,
  2888. &IpAddress::Ipv4(local_ip_addr),
  2889. &IpAddress::Ipv4(remote_ip_addr)
  2890. ),
  2891. Ok((HardwareAddress::Ethernet(remote_hw_addr), MockTxToken))
  2892. );
  2893. }
  2894. #[test]
  2895. #[cfg(all(feature = "medium-ethernet", feature = "proto-ipv6"))]
  2896. fn test_handle_valid_ndisc_request() {
  2897. let (mut iface, mut sockets, _device) = create_ethernet();
  2898. let mut eth_bytes = vec![0u8; 86];
  2899. let local_ip_addr = Ipv6Address::new(0xfdbe, 0, 0, 0, 0, 0, 0, 1);
  2900. let remote_ip_addr = Ipv6Address::new(0xfdbe, 0, 0, 0, 0, 0, 0, 2);
  2901. let local_hw_addr = EthernetAddress([0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
  2902. let remote_hw_addr = EthernetAddress([0x52, 0x54, 0x00, 0x00, 0x00, 0x00]);
  2903. let solicit = Icmpv6Repr::Ndisc(NdiscRepr::NeighborSolicit {
  2904. target_addr: local_ip_addr,
  2905. lladdr: Some(remote_hw_addr.into()),
  2906. });
  2907. let ip_repr = IpRepr::Ipv6(Ipv6Repr {
  2908. src_addr: remote_ip_addr,
  2909. dst_addr: local_ip_addr.solicited_node(),
  2910. next_header: IpProtocol::Icmpv6,
  2911. hop_limit: 0xff,
  2912. payload_len: solicit.buffer_len(),
  2913. });
  2914. let mut frame = EthernetFrame::new_unchecked(&mut eth_bytes);
  2915. frame.set_dst_addr(EthernetAddress([0x33, 0x33, 0x00, 0x00, 0x00, 0x00]));
  2916. frame.set_src_addr(remote_hw_addr);
  2917. frame.set_ethertype(EthernetProtocol::Ipv6);
  2918. ip_repr.emit(frame.payload_mut(), &ChecksumCapabilities::default());
  2919. solicit.emit(
  2920. &remote_ip_addr.into(),
  2921. &local_ip_addr.solicited_node().into(),
  2922. &mut Icmpv6Packet::new_unchecked(&mut frame.payload_mut()[ip_repr.buffer_len()..]),
  2923. &ChecksumCapabilities::default(),
  2924. );
  2925. let icmpv6_expected = Icmpv6Repr::Ndisc(NdiscRepr::NeighborAdvert {
  2926. flags: NdiscNeighborFlags::SOLICITED,
  2927. target_addr: local_ip_addr,
  2928. lladdr: Some(local_hw_addr.into()),
  2929. });
  2930. let ipv6_expected = Ipv6Repr {
  2931. src_addr: local_ip_addr,
  2932. dst_addr: remote_ip_addr,
  2933. next_header: IpProtocol::Icmpv6,
  2934. hop_limit: 0xff,
  2935. payload_len: icmpv6_expected.buffer_len(),
  2936. };
  2937. // Ensure an Neighbor Solicitation triggers a Neighbor Advertisement
  2938. assert_eq!(
  2939. iface.process_ethernet(&mut sockets, frame.into_inner()),
  2940. Some(EthernetPacket::Ip(IpPacket::Icmpv6((
  2941. ipv6_expected,
  2942. icmpv6_expected
  2943. ))))
  2944. );
  2945. // Ensure the address of the requestor was entered in the cache
  2946. assert_eq!(
  2947. iface.lookup_hardware_addr(
  2948. MockTxToken,
  2949. &IpAddress::Ipv6(local_ip_addr),
  2950. &IpAddress::Ipv6(remote_ip_addr)
  2951. ),
  2952. Ok((HardwareAddress::Ethernet(remote_hw_addr), MockTxToken))
  2953. );
  2954. }
  2955. #[test]
  2956. #[cfg(all(feature = "medium-ethernet", feature = "proto-ipv4"))]
  2957. fn test_handle_other_arp_request() {
  2958. let (mut iface, mut sockets, _device) = create_ethernet();
  2959. let mut eth_bytes = vec![0u8; 42];
  2960. let remote_ip_addr = Ipv4Address([0x7f, 0x00, 0x00, 0x02]);
  2961. let remote_hw_addr = EthernetAddress([0x52, 0x54, 0x00, 0x00, 0x00, 0x00]);
  2962. let repr = ArpRepr::EthernetIpv4 {
  2963. operation: ArpOperation::Request,
  2964. source_hardware_addr: remote_hw_addr,
  2965. source_protocol_addr: remote_ip_addr,
  2966. target_hardware_addr: EthernetAddress::default(),
  2967. target_protocol_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x03]),
  2968. };
  2969. let mut frame = EthernetFrame::new_unchecked(&mut eth_bytes);
  2970. frame.set_dst_addr(EthernetAddress::BROADCAST);
  2971. frame.set_src_addr(remote_hw_addr);
  2972. frame.set_ethertype(EthernetProtocol::Arp);
  2973. let mut packet = ArpPacket::new_unchecked(frame.payload_mut());
  2974. repr.emit(&mut packet);
  2975. // Ensure an ARP Request for someone else does not trigger an ARP Reply
  2976. assert_eq!(
  2977. iface.process_ethernet(&mut sockets, frame.into_inner()),
  2978. None
  2979. );
  2980. // Ensure the address of the requestor was NOT entered in the cache
  2981. assert_eq!(
  2982. iface.lookup_hardware_addr(
  2983. MockTxToken,
  2984. &IpAddress::Ipv4(Ipv4Address([0x7f, 0x00, 0x00, 0x01])),
  2985. &IpAddress::Ipv4(remote_ip_addr)
  2986. ),
  2987. Err(Error::Unaddressable)
  2988. );
  2989. }
  2990. #[test]
  2991. #[cfg(all(feature = "medium-ethernet", feature = "proto-ipv4"))]
  2992. fn test_arp_flush_after_update_ip() {
  2993. let (mut iface, mut sockets, _device) = create_ethernet();
  2994. let mut eth_bytes = vec![0u8; 42];
  2995. let local_ip_addr = Ipv4Address([0x7f, 0x00, 0x00, 0x01]);
  2996. let remote_ip_addr = Ipv4Address([0x7f, 0x00, 0x00, 0x02]);
  2997. let local_hw_addr = EthernetAddress([0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
  2998. let remote_hw_addr = EthernetAddress([0x52, 0x54, 0x00, 0x00, 0x00, 0x00]);
  2999. let repr = ArpRepr::EthernetIpv4 {
  3000. operation: ArpOperation::Request,
  3001. source_hardware_addr: remote_hw_addr,
  3002. source_protocol_addr: remote_ip_addr,
  3003. target_hardware_addr: EthernetAddress::default(),
  3004. target_protocol_addr: Ipv4Address([0x7f, 0x00, 0x00, 0x01]),
  3005. };
  3006. let mut frame = EthernetFrame::new_unchecked(&mut eth_bytes);
  3007. frame.set_dst_addr(EthernetAddress::BROADCAST);
  3008. frame.set_src_addr(remote_hw_addr);
  3009. frame.set_ethertype(EthernetProtocol::Arp);
  3010. {
  3011. let mut packet = ArpPacket::new_unchecked(frame.payload_mut());
  3012. repr.emit(&mut packet);
  3013. }
  3014. // Ensure an ARP Request for us triggers an ARP Reply
  3015. assert_eq!(
  3016. iface.process_ethernet(&mut sockets, frame.into_inner()),
  3017. Some(EthernetPacket::Arp(ArpRepr::EthernetIpv4 {
  3018. operation: ArpOperation::Reply,
  3019. source_hardware_addr: local_hw_addr,
  3020. source_protocol_addr: local_ip_addr,
  3021. target_hardware_addr: remote_hw_addr,
  3022. target_protocol_addr: remote_ip_addr
  3023. }))
  3024. );
  3025. // Ensure the address of the requestor was entered in the cache
  3026. assert_eq!(
  3027. iface.lookup_hardware_addr(
  3028. MockTxToken,
  3029. &IpAddress::Ipv4(local_ip_addr),
  3030. &IpAddress::Ipv4(remote_ip_addr)
  3031. ),
  3032. Ok((HardwareAddress::Ethernet(remote_hw_addr), MockTxToken))
  3033. );
  3034. // Update IP addrs to trigger ARP cache flush
  3035. let local_ip_addr_new = Ipv4Address([0x7f, 0x00, 0x00, 0x01]);
  3036. iface.update_ip_addrs(|addrs| {
  3037. addrs.iter_mut().next().map(|addr| {
  3038. *addr = IpCidr::Ipv4(Ipv4Cidr::new(local_ip_addr_new, 24));
  3039. });
  3040. });
  3041. // ARP cache flush after address change
  3042. assert!(!iface.has_neighbor(&IpAddress::Ipv4(remote_ip_addr)));
  3043. }
  3044. #[test]
  3045. #[cfg(all(feature = "socket-icmp", feature = "proto-ipv4"))]
  3046. fn test_icmpv4_socket() {
  3047. use crate::wire::Icmpv4Packet;
  3048. let (mut iface, mut sockets, _device) = create();
  3049. let rx_buffer = icmp::PacketBuffer::new(vec![icmp::PacketMetadata::EMPTY], vec![0; 24]);
  3050. let tx_buffer = icmp::PacketBuffer::new(vec![icmp::PacketMetadata::EMPTY], vec![0; 24]);
  3051. let icmpv4_socket = icmp::Socket::new(rx_buffer, tx_buffer);
  3052. let socket_handle = sockets.add(icmpv4_socket);
  3053. let ident = 0x1234;
  3054. let seq_no = 0x5432;
  3055. let echo_data = &[0xff; 16];
  3056. let socket = sockets.get_mut::<icmp::Socket>(socket_handle);
  3057. // Bind to the ID 0x1234
  3058. assert_eq!(socket.bind(icmp::Endpoint::Ident(ident)), Ok(()));
  3059. // Ensure the ident we bound to and the ident of the packet are the same.
  3060. let mut bytes = [0xff; 24];
  3061. let mut packet = Icmpv4Packet::new_unchecked(&mut bytes);
  3062. let echo_repr = Icmpv4Repr::EchoRequest {
  3063. ident,
  3064. seq_no,
  3065. data: echo_data,
  3066. };
  3067. echo_repr.emit(&mut packet, &ChecksumCapabilities::default());
  3068. let icmp_data = &packet.into_inner()[..];
  3069. let ipv4_repr = Ipv4Repr {
  3070. src_addr: Ipv4Address::new(0x7f, 0x00, 0x00, 0x02),
  3071. dst_addr: Ipv4Address::new(0x7f, 0x00, 0x00, 0x01),
  3072. next_header: IpProtocol::Icmp,
  3073. payload_len: 24,
  3074. hop_limit: 64,
  3075. };
  3076. let ip_repr = IpRepr::Ipv4(ipv4_repr);
  3077. // Open a socket and ensure the packet is handled due to the listening
  3078. // socket.
  3079. assert!(!sockets.get_mut::<icmp::Socket>(socket_handle).can_recv());
  3080. // Confirm we still get EchoReply from `smoltcp` even with the ICMP socket listening
  3081. let echo_reply = Icmpv4Repr::EchoReply {
  3082. ident,
  3083. seq_no,
  3084. data: echo_data,
  3085. };
  3086. let ipv4_reply = Ipv4Repr {
  3087. src_addr: ipv4_repr.dst_addr,
  3088. dst_addr: ipv4_repr.src_addr,
  3089. ..ipv4_repr
  3090. };
  3091. assert_eq!(
  3092. iface.process_icmpv4(&mut sockets, ip_repr, icmp_data),
  3093. Some(IpPacket::Icmpv4((ipv4_reply, echo_reply)))
  3094. );
  3095. let socket = sockets.get_mut::<icmp::Socket>(socket_handle);
  3096. assert!(socket.can_recv());
  3097. assert_eq!(
  3098. socket.recv(),
  3099. Ok((
  3100. icmp_data,
  3101. IpAddress::Ipv4(Ipv4Address::new(0x7f, 0x00, 0x00, 0x02))
  3102. ))
  3103. );
  3104. }
  3105. #[test]
  3106. #[cfg(feature = "proto-ipv6")]
  3107. fn test_solicited_node_addrs() {
  3108. let (mut iface, _, _device) = create();
  3109. let mut new_addrs = vec![
  3110. IpCidr::new(IpAddress::v6(0xfe80, 0, 0, 0, 1, 2, 0, 2), 64),
  3111. IpCidr::new(IpAddress::v6(0xfe80, 0, 0, 0, 3, 4, 0, 0xffff), 64),
  3112. ];
  3113. iface.update_ip_addrs(|addrs| {
  3114. new_addrs.extend(addrs.to_vec());
  3115. *addrs = From::from(new_addrs);
  3116. });
  3117. assert!(iface.has_solicited_node(Ipv6Address::new(0xff02, 0, 0, 0, 0, 1, 0xff00, 0x0002)));
  3118. assert!(iface.has_solicited_node(Ipv6Address::new(0xff02, 0, 0, 0, 0, 1, 0xff00, 0xffff)));
  3119. assert!(!iface.has_solicited_node(Ipv6Address::new(0xff02, 0, 0, 0, 0, 1, 0xff00, 0x0003)));
  3120. }
  3121. #[test]
  3122. #[cfg(feature = "proto-ipv6")]
  3123. fn test_icmpv6_nxthdr_unknown() {
  3124. let (mut iface, mut sockets, _device) = create();
  3125. let remote_ip_addr = Ipv6Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 1);
  3126. let payload = [0x12, 0x34, 0x56, 0x78];
  3127. let ipv6_repr = Ipv6Repr {
  3128. src_addr: remote_ip_addr,
  3129. dst_addr: Ipv6Address::LOOPBACK,
  3130. next_header: IpProtocol::HopByHop,
  3131. payload_len: 12,
  3132. hop_limit: 0x40,
  3133. };
  3134. let mut bytes = vec![0; 52];
  3135. let frame = {
  3136. let ip_repr = IpRepr::Ipv6(ipv6_repr);
  3137. ip_repr.emit(&mut bytes, &ChecksumCapabilities::default());
  3138. let mut offset = ipv6_repr.buffer_len();
  3139. {
  3140. let mut hbh_pkt = Ipv6HopByHopHeader::new_unchecked(&mut bytes[offset..]);
  3141. hbh_pkt.set_next_header(IpProtocol::Unknown(0x0c));
  3142. hbh_pkt.set_header_len(0);
  3143. offset += 8;
  3144. {
  3145. let mut pad_pkt = Ipv6Option::new_unchecked(&mut *hbh_pkt.options_mut());
  3146. Ipv6OptionRepr::PadN(3).emit(&mut pad_pkt);
  3147. }
  3148. {
  3149. let mut pad_pkt = Ipv6Option::new_unchecked(&mut hbh_pkt.options_mut()[5..]);
  3150. Ipv6OptionRepr::Pad1.emit(&mut pad_pkt);
  3151. }
  3152. }
  3153. bytes[offset..].copy_from_slice(&payload);
  3154. Ipv6Packet::new_unchecked(&bytes)
  3155. };
  3156. let reply_icmp_repr = Icmpv6Repr::ParamProblem {
  3157. reason: Icmpv6ParamProblem::UnrecognizedNxtHdr,
  3158. pointer: 40,
  3159. header: ipv6_repr,
  3160. data: &payload[..],
  3161. };
  3162. let reply_ipv6_repr = Ipv6Repr {
  3163. src_addr: Ipv6Address::LOOPBACK,
  3164. dst_addr: remote_ip_addr,
  3165. next_header: IpProtocol::Icmpv6,
  3166. payload_len: reply_icmp_repr.buffer_len(),
  3167. hop_limit: 0x40,
  3168. };
  3169. // Ensure the unknown next header causes a ICMPv6 Parameter Problem
  3170. // error message to be sent to the sender.
  3171. assert_eq!(
  3172. iface.process_ipv6(&mut sockets, &frame),
  3173. Some(IpPacket::Icmpv6((reply_ipv6_repr, reply_icmp_repr)))
  3174. );
  3175. }
  3176. #[test]
  3177. #[cfg(feature = "proto-igmp")]
  3178. fn test_handle_igmp() {
  3179. fn recv_igmp(device: &mut Loopback, timestamp: Instant) -> Vec<(Ipv4Repr, IgmpRepr)> {
  3180. let caps = device.capabilities();
  3181. let checksum_caps = &caps.checksum;
  3182. recv_all(device, timestamp)
  3183. .iter()
  3184. .filter_map(|frame| {
  3185. let ipv4_packet = match caps.medium {
  3186. #[cfg(feature = "medium-ethernet")]
  3187. Medium::Ethernet => {
  3188. let eth_frame = EthernetFrame::new_checked(frame).ok()?;
  3189. Ipv4Packet::new_checked(eth_frame.payload()).ok()?
  3190. }
  3191. #[cfg(feature = "medium-ip")]
  3192. Medium::Ip => Ipv4Packet::new_checked(&frame[..]).ok()?,
  3193. #[cfg(feature = "medium-ieee802154")]
  3194. Medium::Ieee802154 => todo!(),
  3195. };
  3196. let ipv4_repr = Ipv4Repr::parse(&ipv4_packet, checksum_caps).ok()?;
  3197. let ip_payload = ipv4_packet.payload();
  3198. let igmp_packet = IgmpPacket::new_checked(ip_payload).ok()?;
  3199. let igmp_repr = IgmpRepr::parse(&igmp_packet).ok()?;
  3200. Some((ipv4_repr, igmp_repr))
  3201. })
  3202. .collect::<Vec<_>>()
  3203. }
  3204. let groups = [
  3205. Ipv4Address::new(224, 0, 0, 22),
  3206. Ipv4Address::new(224, 0, 0, 56),
  3207. ];
  3208. let (mut iface, mut sockets, mut device) = create();
  3209. // Join multicast groups
  3210. let timestamp = Instant::now();
  3211. for group in &groups {
  3212. iface
  3213. .join_multicast_group(&mut device, *group, timestamp)
  3214. .unwrap();
  3215. }
  3216. let reports = recv_igmp(&mut device, timestamp);
  3217. assert_eq!(reports.len(), 2);
  3218. for (i, group_addr) in groups.iter().enumerate() {
  3219. assert_eq!(reports[i].0.next_header, IpProtocol::Igmp);
  3220. assert_eq!(reports[i].0.dst_addr, *group_addr);
  3221. assert_eq!(
  3222. reports[i].1,
  3223. IgmpRepr::MembershipReport {
  3224. group_addr: *group_addr,
  3225. version: IgmpVersion::Version2,
  3226. }
  3227. );
  3228. }
  3229. // General query
  3230. let timestamp = Instant::now();
  3231. const GENERAL_QUERY_BYTES: &[u8] = &[
  3232. 0x46, 0xc0, 0x00, 0x24, 0xed, 0xb4, 0x00, 0x00, 0x01, 0x02, 0x47, 0x43, 0xac, 0x16,
  3233. 0x63, 0x04, 0xe0, 0x00, 0x00, 0x01, 0x94, 0x04, 0x00, 0x00, 0x11, 0x64, 0xec, 0x8f,
  3234. 0x00, 0x00, 0x00, 0x00, 0x02, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  3235. 0x00, 0x00, 0x00, 0x00,
  3236. ];
  3237. {
  3238. // Transmit GENERAL_QUERY_BYTES into loopback
  3239. let tx_token = device.transmit().unwrap();
  3240. tx_token
  3241. .consume(timestamp, GENERAL_QUERY_BYTES.len(), |buffer| {
  3242. buffer.copy_from_slice(GENERAL_QUERY_BYTES);
  3243. Ok(())
  3244. })
  3245. .unwrap();
  3246. }
  3247. // Trigger processing until all packets received through the
  3248. // loopback have been processed, including responses to
  3249. // GENERAL_QUERY_BYTES. Therefore `recv_all()` would return 0
  3250. // pkts that could be checked.
  3251. iface.socket_ingress(&mut device, &mut sockets);
  3252. // Leave multicast groups
  3253. let timestamp = Instant::now();
  3254. for group in &groups {
  3255. iface
  3256. .leave_multicast_group(&mut device, *group, timestamp)
  3257. .unwrap();
  3258. }
  3259. let leaves = recv_igmp(&mut device, timestamp);
  3260. assert_eq!(leaves.len(), 2);
  3261. for (i, group_addr) in groups.iter().cloned().enumerate() {
  3262. assert_eq!(leaves[i].0.next_header, IpProtocol::Igmp);
  3263. assert_eq!(leaves[i].0.dst_addr, Ipv4Address::MULTICAST_ALL_ROUTERS);
  3264. assert_eq!(leaves[i].1, IgmpRepr::LeaveGroup { group_addr });
  3265. }
  3266. }
  3267. #[test]
  3268. #[cfg(all(feature = "proto-ipv4", feature = "socket-raw"))]
  3269. fn test_raw_socket_no_reply() {
  3270. use crate::wire::{IpVersion, Ipv4Packet, UdpPacket, UdpRepr};
  3271. let (mut iface, mut sockets, _device) = create();
  3272. let packets = 1;
  3273. let rx_buffer =
  3274. raw::PacketBuffer::new(vec![raw::PacketMetadata::EMPTY; packets], vec![0; 48 * 1]);
  3275. let tx_buffer = raw::PacketBuffer::new(
  3276. vec![raw::PacketMetadata::EMPTY; packets],
  3277. vec![0; 48 * packets],
  3278. );
  3279. let raw_socket = raw::Socket::new(IpVersion::Ipv4, IpProtocol::Udp, rx_buffer, tx_buffer);
  3280. sockets.add(raw_socket);
  3281. let src_addr = Ipv4Address([127, 0, 0, 2]);
  3282. let dst_addr = Ipv4Address([127, 0, 0, 1]);
  3283. const PAYLOAD_LEN: usize = 10;
  3284. let udp_repr = UdpRepr {
  3285. src_port: 67,
  3286. dst_port: 68,
  3287. };
  3288. let mut bytes = vec![0xff; udp_repr.header_len() + PAYLOAD_LEN];
  3289. let mut packet = UdpPacket::new_unchecked(&mut bytes[..]);
  3290. udp_repr.emit(
  3291. &mut packet,
  3292. &src_addr.into(),
  3293. &dst_addr.into(),
  3294. PAYLOAD_LEN,
  3295. |buf| fill_slice(buf, 0x2a),
  3296. &ChecksumCapabilities::default(),
  3297. );
  3298. let ipv4_repr = Ipv4Repr {
  3299. src_addr: src_addr,
  3300. dst_addr: dst_addr,
  3301. next_header: IpProtocol::Udp,
  3302. hop_limit: 64,
  3303. payload_len: udp_repr.header_len() + PAYLOAD_LEN,
  3304. };
  3305. // Emit to frame
  3306. let mut bytes = vec![0u8; ipv4_repr.buffer_len() + udp_repr.header_len() + PAYLOAD_LEN];
  3307. let frame = {
  3308. ipv4_repr.emit(
  3309. &mut Ipv4Packet::new_unchecked(&mut bytes),
  3310. &ChecksumCapabilities::default(),
  3311. );
  3312. udp_repr.emit(
  3313. &mut UdpPacket::new_unchecked(&mut bytes[ipv4_repr.buffer_len()..]),
  3314. &src_addr.into(),
  3315. &dst_addr.into(),
  3316. PAYLOAD_LEN,
  3317. |buf| fill_slice(buf, 0x2a),
  3318. &ChecksumCapabilities::default(),
  3319. );
  3320. Ipv4Packet::new_unchecked(&bytes)
  3321. };
  3322. assert_eq!(iface.process_ipv4(&mut sockets, &frame), None);
  3323. }
  3324. #[test]
  3325. #[cfg(all(feature = "proto-ipv4", feature = "socket-raw", feature = "socket-udp"))]
  3326. fn test_raw_socket_with_udp_socket() {
  3327. use crate::wire::{IpEndpoint, IpVersion, Ipv4Packet, UdpPacket, UdpRepr};
  3328. static UDP_PAYLOAD: [u8; 5] = [0x48, 0x65, 0x6c, 0x6c, 0x6f];
  3329. let (mut iface, mut sockets, _device) = create();
  3330. let udp_rx_buffer = udp::PacketBuffer::new(vec![udp::PacketMetadata::EMPTY], vec![0; 15]);
  3331. let udp_tx_buffer = udp::PacketBuffer::new(vec![udp::PacketMetadata::EMPTY], vec![0; 15]);
  3332. let udp_socket = udp::Socket::new(udp_rx_buffer, udp_tx_buffer);
  3333. let udp_socket_handle = sockets.add(udp_socket);
  3334. // Bind the socket to port 68
  3335. let socket = sockets.get_mut::<udp::Socket>(udp_socket_handle);
  3336. assert_eq!(socket.bind(68), Ok(()));
  3337. assert!(!socket.can_recv());
  3338. assert!(socket.can_send());
  3339. let packets = 1;
  3340. let raw_rx_buffer =
  3341. raw::PacketBuffer::new(vec![raw::PacketMetadata::EMPTY; packets], vec![0; 48 * 1]);
  3342. let raw_tx_buffer = raw::PacketBuffer::new(
  3343. vec![raw::PacketMetadata::EMPTY; packets],
  3344. vec![0; 48 * packets],
  3345. );
  3346. let raw_socket = raw::Socket::new(
  3347. IpVersion::Ipv4,
  3348. IpProtocol::Udp,
  3349. raw_rx_buffer,
  3350. raw_tx_buffer,
  3351. );
  3352. sockets.add(raw_socket);
  3353. let src_addr = Ipv4Address([127, 0, 0, 2]);
  3354. let dst_addr = Ipv4Address([127, 0, 0, 1]);
  3355. let udp_repr = UdpRepr {
  3356. src_port: 67,
  3357. dst_port: 68,
  3358. };
  3359. let mut bytes = vec![0xff; udp_repr.header_len() + UDP_PAYLOAD.len()];
  3360. let mut packet = UdpPacket::new_unchecked(&mut bytes[..]);
  3361. udp_repr.emit(
  3362. &mut packet,
  3363. &src_addr.into(),
  3364. &dst_addr.into(),
  3365. UDP_PAYLOAD.len(),
  3366. |buf| buf.copy_from_slice(&UDP_PAYLOAD),
  3367. &ChecksumCapabilities::default(),
  3368. );
  3369. let ipv4_repr = Ipv4Repr {
  3370. src_addr: src_addr,
  3371. dst_addr: dst_addr,
  3372. next_header: IpProtocol::Udp,
  3373. hop_limit: 64,
  3374. payload_len: udp_repr.header_len() + UDP_PAYLOAD.len(),
  3375. };
  3376. // Emit to frame
  3377. let mut bytes =
  3378. vec![0u8; ipv4_repr.buffer_len() + udp_repr.header_len() + UDP_PAYLOAD.len()];
  3379. let frame = {
  3380. ipv4_repr.emit(
  3381. &mut Ipv4Packet::new_unchecked(&mut bytes),
  3382. &ChecksumCapabilities::default(),
  3383. );
  3384. udp_repr.emit(
  3385. &mut UdpPacket::new_unchecked(&mut bytes[ipv4_repr.buffer_len()..]),
  3386. &src_addr.into(),
  3387. &dst_addr.into(),
  3388. UDP_PAYLOAD.len(),
  3389. |buf| buf.copy_from_slice(&UDP_PAYLOAD),
  3390. &ChecksumCapabilities::default(),
  3391. );
  3392. Ipv4Packet::new_unchecked(&bytes)
  3393. };
  3394. assert_eq!(iface.process_ipv4(&mut sockets, &frame), None);
  3395. // Make sure the UDP socket can still receive in presence of a Raw socket that handles UDP
  3396. let socket = sockets.get_mut::<udp::Socket>(udp_socket_handle);
  3397. assert!(socket.can_recv());
  3398. assert_eq!(
  3399. socket.recv(),
  3400. Ok((&UDP_PAYLOAD[..], IpEndpoint::new(src_addr.into(), 67)))
  3401. );
  3402. }
  3403. }