@@ -430,6 +430,19 @@ def restore_etc_hosts(port):
430430 rewrite_etc_hosts (port )
431431
432432
433+ def _mask (ip , width ):
434+ nip = struct .unpack ('!I' , socket .inet_aton (ip ))[0 ]
435+ masked = nip & shl (shl (1 , width ) - 1 , 32 - width )
436+ return socket .inet_ntoa (struct .pack ('!I' , masked ))
437+
438+
439+ def ip_in_subnets (ip , subnets ):
440+ for swidth ,sexclude ,snet in sorted (subnets , reverse = True ):
441+ if _mask (snet , swidth ) == _mask (ip , swidth ):
442+ return not sexclude
443+ return False
444+
445+
433446# This is some voodoo for setting up the kernel's transparent
434447# proxying stuff. If subnets is empty, we just delete our sshuttle rules;
435448# otherwise we delete it, then make them from scratch.
@@ -521,8 +534,9 @@ def main(port, dnsport, syslog):
521534 line = sys .stdin .readline (128 )
522535 if line .startswith ('HOST ' ):
523536 (name ,ip ) = line [5 :].strip ().split (',' , 1 )
524- hostmap [name ] = ip
525- rewrite_etc_hosts (port )
537+ if ip_in_subnets (ip , subnets ):
538+ hostmap [name ] = ip
539+ rewrite_etc_hosts (port )
526540 elif line :
527541 raise Fatal ('expected EOF, got %r' % line )
528542 else :
0 commit comments