3737from scapy .utils import inet_aton , inet_ntoa , lhex , mac2str , str2mac , EDecimal
3838from scapy .utils6 import in6_6to4ExtractAddr , in6_isaddr6to4 , \
3939 in6_isaddrTeredo , in6_ptop , Net6 , teredoAddrExtractInfo
40- from scapy .base_classes import Gen , Net , BasePacket , Field_metaclass
41- from scapy .error import warning
40+ from scapy .base_classes import (
41+ _NetIP ,
42+ BasePacket ,
43+ Field_metaclass ,
44+ Net ,
45+ NetIP ,
46+ )
4247
4348# Typing imports
4449from typing import (
@@ -849,6 +854,7 @@ def h2i(self, pkt, x):
849854 if isinstance (x , bytes ):
850855 x = plain_str (x ) # type: ignore
851856 if isinstance (x , str ):
857+ x = NetIP (x )
852858 try :
853859 inet_aton (x )
854860 except socket .error :
@@ -893,6 +899,8 @@ def any2i(self, pkt, x):
893899
894900 def i2repr (self , pkt , x ):
895901 # type: (Optional[Packet], Union[str, Net]) -> str
902+ if isinstance (x , _NetIP ):
903+ return repr (x )
896904 r = self .resolve (self .i2h (pkt , x ))
897905 return r if isinstance (r , str ) else repr (r )
898906
@@ -902,29 +910,16 @@ def randval(self):
902910
903911
904912class SourceIPField (IPField ):
905- __slots__ = ["dstname" ]
906-
907- def __init__ (self , name , dstname ):
908- # type: (str, Optional[str]) -> None
913+ def __init__ (self , name ):
914+ # type: (str) -> None
909915 IPField .__init__ (self , name , None )
910- self .dstname = dstname
911916
912917 def __findaddr (self , pkt ):
913- # type: (Packet) -> str
918+ # type: (Packet) -> Optional[ str]
914919 if conf .route is None :
915920 # unused import, only to initialize conf.route
916921 import scapy .route # noqa: F401
917- dst = ("0.0.0.0" if self .dstname is None
918- else getattr (pkt , self .dstname ) or "0.0.0.0" )
919- if isinstance (dst , (Gen , list )):
920- r = {
921- conf .route .route (str (daddr ))
922- for daddr in dst
923- } # type: Set[Tuple[str, str, str]]
924- if len (r ) > 1 :
925- warning ("More than one possible route for %r" % (dst ,))
926- return min (r )[1 ]
927- return conf .route .route (dst )[1 ]
922+ return pkt .route ()[1 ]
928923
929924 def i2m (self , pkt , x ):
930925 # type: (Optional[Packet], Optional[Union[str, Net]]) -> bytes
@@ -945,18 +940,19 @@ def __init__(self, name, default):
945940 Field .__init__ (self , name , default , "16s" )
946941
947942 def h2i (self , pkt , x ):
948- # type: (Optional[Packet], Optional[str] ) -> str
943+ # type: (Optional[Packet], Any ) -> str
949944 if isinstance (x , bytes ):
950945 x = plain_str (x )
951946 if isinstance (x , str ):
947+ x = NetIP (x )
952948 try :
953- x = in6_ptop (x )
949+ in6_ptop (x )
954950 except socket .error :
955951 return Net6 (x ) # type: ignore
956952 elif isinstance (x , tuple ):
957953 if len (x ) != 2 :
958954 raise ValueError ("Invalid IPv6 format" )
959- return Net6 (* x )
955+ return Net6 (* x ) # type: ignore
960956 elif isinstance (x , list ):
961957 x = [self .h2i (pkt , n ) for n in x ]
962958 return x # type: ignore
@@ -990,6 +986,8 @@ def i2repr(self, pkt, x):
990986 elif in6_isaddr6to4 (x ): # print encapsulated address
991987 vaddr = in6_6to4ExtractAddr (x )
992988 return "%s [6to4 GW: %s]" % (self .i2h (pkt , x ), vaddr )
989+ elif isinstance (x , _NetIP ):
990+ return repr (x )
993991 r = self .i2h (pkt , x ) # No specific information to return
994992 return r if isinstance (r , str ) else repr (r )
995993
@@ -999,36 +997,27 @@ def randval(self):
999997
1000998
1001999class SourceIP6Field (IP6Field ):
1002- __slots__ = ["dstname" ]
1003-
1004- def __init__ (self , name , dstname ):
1005- # type: (str, str) -> None
1000+ def __init__ (self , name ):
1001+ # type: (str) -> None
10061002 IP6Field .__init__ (self , name , None )
1007- self .dstname = dstname
1003+
1004+ def __findaddr (self , pkt ):
1005+ # type: (Packet) -> Optional[str]
1006+ if conf .route6 is None :
1007+ # unused import, only to initialize conf.route
1008+ import scapy .route6 # noqa: F401
1009+ return pkt .route ()[1 ]
10081010
10091011 def i2m (self , pkt , x ):
10101012 # type: (Optional[Packet], Optional[Union[str, Net6]]) -> bytes
1011- if x is None :
1012- dst = ("::" if self .dstname is None else
1013- getattr (pkt , self .dstname ) or "::" )
1014- iff , x , nh = conf .route6 .route (dst )
1013+ if x is None and pkt is not None :
1014+ x = self .__findaddr (pkt )
10151015 return super (SourceIP6Field , self ).i2m (pkt , x )
10161016
10171017 def i2h (self , pkt , x ):
10181018 # type: (Optional[Packet], Optional[Union[str, Net6]]) -> str
1019- if x is None :
1020- if conf .route6 is None :
1021- # unused import, only to initialize conf.route6
1022- import scapy .route6 # noqa: F401
1023- dst = ("::" if self .dstname is None else getattr (pkt , self .dstname )) # noqa: E501
1024- if isinstance (dst , (Gen , list )):
1025- r = {conf .route6 .route (str (daddr ))
1026- for daddr in dst }
1027- if len (r ) > 1 :
1028- warning ("More than one possible route for %r" % (dst ,))
1029- x = min (r )[1 ]
1030- else :
1031- x = conf .route6 .route (dst )[1 ]
1019+ if x is None and pkt is not None :
1020+ x = self .__findaddr (pkt )
10321021 return super (SourceIP6Field , self ).i2h (pkt , x )
10331022
10341023
0 commit comments