<commit_before>import re, errno, socket, select, struct
import compat.ssubprocess as ssubprocess
import helpers, ssyslog
from helpers import *

# python doesn't have a definition for this
IPPROTO_DIVERT = 254


def nonfatal(func, *args):
    try:
        func(*args)
    except Fatal, e:
        log('error: %s\n' % e)


def ipt_table_exists(name, family, table):
    if family == socket.AF_INET6:
        cmd = 'ip6tables'
    elif family == socket.AF_INET:
        cmd = 'iptables'
    else:
        raise Fatal("Unsupported socket type '%s'"%family)
    argv = [cmd, '-t', table, '-nL']
    p = ssubprocess.Popen(argv, stdout = ssubprocess.PIPE)
    for line in p.stdout:
        if line.startswith('Chain %s ' % name):
            return True
    rv = p.wait()
    if rv:
        raise Fatal('%r returned %d' % (argv, rv))


def ipt4(table, *args):
    argv = ['iptables', '-t', table] + list(args)
    debug1('>> %s\n' % ' '.join(argv))
    rv = ssubprocess.call(argv)
    if rv:
        raise Fatal('%r returned %d' % (argv, rv))

def ipt6(table, *args):
    argv = ['ip6tables', '-t', table] + list(args)
    debug1('>> %s\n' % ' '.join(argv))
    rv = ssubprocess.call(argv)
    if rv:
        raise Fatal('%r returned %d' % (argv, rv))

def ipt(family, *args):
    if family == socket.AF_INET6:
        ipt6(*args)
    elif family == socket.AF_INET:
        ipt4(*args)
    else:
        raise Fatal("Unsupported socket type '%s'"%family)
    

_no_ttl_module = False
def ipt_ttl(family, *args):
    global _no_ttl_module
    if not _no_ttl_module:
        # we avoid infinite loops by generating server-side connections
        # with ttl 42.  This makes the client side not recapture those
        # connections, in case client == server.
        try:
            argsplus = list(args) + ['-m', 'ttl', '!', '--ttl', '42']
            ipt(family, *argsplus)
        except Fatal:
            ipt(family, *args)
            # we only get here if the non-ttl attempt succeeds
            log('sshuttle: warning: your iptables is missing '
                'the ttl module.\n')
            _no_ttl_module = True
    else:
        ipt(family, *args)



# We name the chain based on the transproxy port number so that it's possible
# to run multiple copies of sshuttle at the same time.  Of course, the
# multiple copies shouldn't have overlapping subnets, or only the most-
# recently-started one will win (because we use "-I OUTPUT 1" instead of
# "-A OUTPUT").
def do_iptables_nat(port, dnsport, family, subnets):
    # only ipv4 supported with NAT
    if family != socket.AF_INET:
        return

    table = "nat"
    chain = 'sshuttle-%s' % port

    # basic cleanup/setup of chains
    if ipt_table_exists(chain, family, table):
        nonfatal(ipt, family, table, '-D', 'OUTPUT', '-j', chain)
        nonfatal(ipt, family, table, '-D', 'PREROUTING', '-j', chain)
        nonfatal(ipt, family, table, '-F', chain)
        ipt(family, table, '-X', chain)

    if subnets or dnsport:
        ipt(family, table, '-N', chain)
        ipt(family, table, '-F', chain)
        ipt(family, table, '-I', 'OUTPUT', '1', '-j', chain)
        ipt(family, table, '-I', 'PREROUTING', '1', '-j', chain)

    if subnets:
        # create new subnet entries.  Note that we're sorting in a very
        # particular order: we need to go from most-specific (largest swidth)
        # to least-specific, and at any given level of specificity, we want
        # excludes to come first.  That's why the columns are in such a non-
        # intuitive order.
        for f,swidth,sexclude,snet in sorted(subnets, key=lambda s: s[2], reverse=True):
            if f != family:
                pass
            elif sexclude:
                ipt(family, table, '-A', chain, '-j', 'RETURN',
                    '--dest', '%s/%s' % (snet,swidth),
                    '-p', 'tcp')
            else:
                ipt_ttl(family, table, '-A', chain, '-j', 'REDIRECT',
                        '--dest', '%s/%s' % (snet,swidth),
                        '-p', 'tcp',
                        '--to-ports', str(port))
                
    if dnsport:
        nslist = resolvconf_nameservers()
        for ip in nslist:
            ipt_ttl(family, table, '-A', chain, '-j', 'REDIRECT',
                    '--dest', '%s/32' % ip,
                    '-p', 'udp',
                    '--dport', '53',
                    '--to-ports', str(dnsport))

def do_iptables_tproxy(port, dnsport, family, subnets):
    if family not in [socket.AF_INET, socket.AF_INET6]:
        return

    table = "mangle"<commit_msg>Fix handling of IPv4/IPv6 DNS servers.<commit_after>import re, errno, socket, select, struct
import compat.ssubprocess as ssubprocess
import helpers, ssyslog
from helpers import *

# python doesn't have a definition for this
IPPROTO_DIVERT = 254


def nonfatal(func, *args):
    try:
        func(*args)
    except Fatal, e:
        log('error: %s\n' % e)


def ipt_table_exists(name, family, table):
    if family == socket.AF_INET6:
        cmd = 'ip6tables'
    elif family == socket.AF_INET:
        cmd = 'iptables'
    else:
        raise Fatal("Unsupported socket type '%s'"%family)
    argv = [cmd, '-t', table, '-nL']
    p = ssubprocess.Popen(argv, stdout = ssubprocess.PIPE)
    for line in p.stdout:
        if line.startswith('Chain %s ' % name):
            return True
    rv = p.wait()
    if rv:
        raise Fatal('%r returned %d' % (argv, rv))


def ipt4(table, *args):
    argv = ['iptables', '-t', table] + list(args)
    debug1('>> %s\n' % ' '.join(argv))
    rv = ssubprocess.call(argv)
    if rv:
        raise Fatal('%r returned %d' % (argv, rv))

def ipt6(table, *args):
    argv = ['ip6tables', '-t', table] + list(args)
    debug1('>> %s\n' % ' '.join(argv))
    rv = ssubprocess.call(argv)
    if rv:
        raise Fatal('%r returned %d' % (argv, rv))

def ipt(family, *args):
    if family == socket.AF_INET6:
        ipt6(*args)
    elif family == socket.AF_INET:
        ipt4(*args)
    else:
        raise Fatal("Unsupported socket type '%s'"%family)
    

_no_ttl_module = False
def ipt_ttl(family, *args):
    global _no_ttl_module
    if not _no_ttl_module:
        # we avoid infinite loops by generating server-side connections
        # with ttl 42.  This makes the client side not recapture those
        # connections, in case client == server.
        try:
            argsplus = list(args) + ['-m', 'ttl', '!', '--ttl', '42']
            ipt(family, *argsplus)
        except Fatal:
            ipt(family, *args)
            # we only get here if the non-ttl attempt succeeds
            log('sshuttle: warning: your iptables is missing '
                'the ttl module.\n')
            _no_ttl_module = True
    else:
        ipt(family, *args)



# We name the chain based on the transproxy port number so that it's possible
# to run multiple copies of sshuttle at the same time.  Of course, the
# multiple copies shouldn't have overlapping subnets, or only the most-
# recently-started one will win (because we use "-I OUTPUT 1" instead of
# "-A OUTPUT").
def do_iptables_nat(port, dnsport, family, subnets):
    # only ipv4 supported with NAT
    if family != socket.AF_INET:
        return

    table = "nat"
    chain = 'sshuttle-%s' % port

    # basic cleanup/setup of chains
    if ipt_table_exists(chain, family, table):
        nonfatal(ipt, family, table, '-D', 'OUTPUT', '-j', chain)
        nonfatal(ipt, family, table, '-D', 'PREROUTING', '-j', chain)
        nonfatal(ipt, family, table, '-F', chain)
        ipt(family, table, '-X', chain)

    if subnets or dnsport:
        ipt(family, table, '-N', chain)
        ipt(family, table, '-F', chain)
        ipt(family, table, '-I', 'OUTPUT', '1', '-j', chain)
        ipt(family, table, '-I', 'PREROUTING', '1', '-j', chain)

    if subnets:
        # create new subnet entries.  Note that we're sorting in a very
        # particular order: we need to go from most-specific (largest swidth)
        # to least-specific, and at any given level of specificity, we want
        # excludes to come first.  That's why the columns are in such a non-
        # intuitive order.
        for f,swidth,sexclude,snet in sorted(subnets, key=lambda s: s[2], reverse=True):
            if f != family:
                pass
            elif sexclude:
                ipt(family, table, '-A', chain, '-j', 'RETURN',
                    '--dest', '%s/%s' % (snet,swidth),
                    '-p', 'tcp')
            else:
                ipt_ttl(family, table, '-A', chain, '-j', 'REDIRECT',
                        '--dest', '%s/%s' % (snet,swidth),
                        '-p', 'tcp',
                        '--to-ports', str(port))
                
    if dnsport:
        nslist = resolvconf_nameservers()
        for ip in filter(lambda i: guess_address_family(i)==family, nslist):
            ipt_ttl(family, table, '-A', chain, '-j', 'REDIRECT',
                    '--dest', '%s/32' % ip,
                    '-p', 'udp',
                    '--dport', '53',
                    '--to-ports', str(dnsport))

def do_iptables_tproxy(port, dnsport, family, subnets):
    if family not in [socket.AF_INET, socket.AF_INET6]:
        return

    table = "mangle"
{'fraction_non_alphanumeric': 0.13816216216216215, 'fraction_numerical': 0.006054054054054054, 'mean_word_length': 2.128508623605005, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1112159', 'n_tokens_mistral': 3105, 'n_tokens_neox': 2960, 'n_words': 939}