@@ -14,20 +14,23 @@ use crate::{Layer, Packet, ENCAP_TYPE_ETH};
1414
1515pub const ETH_HEADER_LENGTH : usize = 14_usize ;
1616
17+ /// A Map maintaining EtherType -> Creator fns for Layer Creators of L3 Layers.
18+ ///
19+ /// The creator function simply creates a `default` L3 struct that implements the dissector
20+ /// for the Layer.
1721pub fn get_ethertypes_map ( ) -> & ' static RwLock < HashMap < EtherType , LayerCreatorFn > > {
18- /// A Map maintaining EtherType -> Creator fns for Layer Creators of L3 Layers.
19- ///
20- /// The creator function simply creates a `default` L3 struct that implements the dissector
21- /// for the Layer.
22- pub ( crate ) static ETHERTYPES_MAP : OnceLock < RwLock < HashMap < EtherType , LayerCreatorFn > > > =
23- OnceLock :: new ( ) ;
22+ static ETHERTYPES_MAP : OnceLock < RwLock < HashMap < EtherType , LayerCreatorFn > > > = OnceLock :: new ( ) ;
2423 ETHERTYPES_MAP . get_or_init ( || RwLock :: new ( HashMap :: new ( ) ) )
2524}
2625
26+ /// A Map maintaining String -> EtherType of L3 Layers.
27+ pub fn get_inv_ethertypes_map ( ) -> & ' static RwLock < HashMap < String , EtherType > > {
28+ static INV_ETHERTYPES_MAP : OnceLock < RwLock < HashMap < String , EtherType > > > = OnceLock :: new ( ) ;
29+ INV_ETHERTYPES_MAP . get_or_init ( || RwLock :: new ( HashMap :: new ( ) ) )
30+ }
31+
2732// Register our Encap Types with the Packet.
2833pub ( crate ) fn register_defaults ( ) -> Result < ( ) , Error > {
29- get_ethertypes_map ( ) ;
30-
3134 Packet :: register_encap_type ( ENCAP_TYPE_ETH , Ethernet :: creator)
3235}
3336
@@ -36,12 +39,29 @@ pub(crate) fn register_defaults() -> Result<(), Error> {
3639/// A Layer that would handle subsequent decoding for a given Ethertype, should register itself
3740/// by calling this function. For example [`crate::layers::ipv4`] would call `register_ethertype`
3841/// with [`EtherType`] value of 0x0800, passing the creator function for that layer.
39- pub fn register_ethertype ( eth_type : EtherType , layer : LayerCreatorFn ) -> Result < ( ) , Error > {
40- let mut map = get_ethertypes_map ( ) . write ( ) . unwrap ( ) ;
41- if map. contains_key ( & eth_type) {
42- return Err ( Error :: RegisterError ( format ! ( "ether_type: {}" , eth_type) ) ) ;
42+ pub fn register_ethertype (
43+ eth_type : EtherType ,
44+ name : & str ,
45+ layer : LayerCreatorFn ,
46+ ) -> Result < ( ) , Error > {
47+ {
48+ let mut map = get_ethertypes_map ( ) . write ( ) . unwrap ( ) ;
49+ if map. contains_key ( & eth_type) {
50+ return Err ( Error :: RegisterError ( format ! ( "ether_type: {}" , eth_type) ) ) ;
51+ }
52+ map. insert ( eth_type, layer) ;
53+ }
54+
55+ {
56+ let mut inv_map = get_inv_ethertypes_map ( ) . write ( ) . unwrap ( ) ;
57+ if inv_map. contains_key ( name) {
58+ return Err ( Error :: RegisterError ( format ! (
59+ "Cannot find EtherType for : {}" ,
60+ name
61+ ) ) ) ;
62+ }
63+ inv_map. insert ( name. to_string ( ) , eth_type) ;
4364 }
44- map. insert ( eth_type, layer) ;
4565
4666 Ok ( ( ) )
4767}
@@ -103,16 +123,15 @@ impl Layer for Ethernet {
103123 result. extend ( self . dst_mac . as_slice ( ) ) ;
104124 result. extend ( self . src_mac . as_slice ( ) ) ;
105125
106- let ethertype: u16 = match info {
107- "ARP" => crate :: types:: ETHERTYPE_ARP ,
108- "IPv4" => crate :: types:: ETHERTYPE_IP ,
109- "IPv6" => crate :: types:: ETHERTYPE_IP6 ,
110- // FIXME: can also be `ETHERTYPE_MPLS_MULTICAST`
111- "MPLS" => crate :: types:: ETHERTYPE_MPLS_UNICAST ,
112- "raw" => 0xffff ,
113- // NOTE: should return Err instead
114- _ => unimplemented ! ( ) ,
115- } ;
126+ let ethertype = get_inv_ethertypes_map ( )
127+ . read ( )
128+ . unwrap ( )
129+ . get ( info)
130+ . copied ( )
131+ . unwrap_or_else ( || match info {
132+ "raw" => crate :: types:: ETHERTYPE_RAW ,
133+ _ => todo ! ( "Return Err here instead" ) ,
134+ } ) ;
116135
117136 result. extend ( ethertype. to_be_bytes ( ) ) ;
118137 result. extend ( next_layer. unwrap_or_default ( ) ) ;
0 commit comments