示例#1
0
文件: alias.c 项目: ChaosJohn/freebsd
static int
LibAliasOutLocked(struct libalias *la, char *ptr,	/* valid IP packet */
    int maxpacketsize,		/* How much the packet data may grow (FTP
				 * and IRC inline changes) */
    int create                  /* Create new entries ? */
)
{
	int iresult;
	struct in_addr addr_save;
	struct ip *pip;

	if (la->packetAliasMode & PKT_ALIAS_REVERSE) {
		la->packetAliasMode &= ~PKT_ALIAS_REVERSE;
		iresult = LibAliasInLocked(la, ptr, maxpacketsize);
		la->packetAliasMode |= PKT_ALIAS_REVERSE;
		goto getout;
	}
	HouseKeeping(la);
	ClearCheckNewLink(la);
	pip = (struct ip *)ptr;

	/* Defense against mangled packets */
	if (ntohs(pip->ip_len) > maxpacketsize
	    || (pip->ip_hl << 2) > maxpacketsize) {
		iresult = PKT_ALIAS_IGNORED;
		goto getout;
	}

	addr_save = GetDefaultAliasAddress(la);
	if (la->packetAliasMode & PKT_ALIAS_UNREGISTERED_ONLY) {
		u_long addr;
		int iclass;

		iclass = 0;
		addr = ntohl(pip->ip_src.s_addr);
		if (addr >= UNREG_ADDR_C_LOWER && addr <= UNREG_ADDR_C_UPPER)
			iclass = 3;
		else if (addr >= UNREG_ADDR_B_LOWER && addr <= UNREG_ADDR_B_UPPER)
			iclass = 2;
		else if (addr >= UNREG_ADDR_A_LOWER && addr <= UNREG_ADDR_A_UPPER)
			iclass = 1;

		if (iclass == 0) {
			SetDefaultAliasAddress(la, pip->ip_src);
		}
	} else if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY) {
		SetDefaultAliasAddress(la, pip->ip_src);
	}
	iresult = PKT_ALIAS_IGNORED;
	if ((ntohs(pip->ip_off) & IP_OFFMASK) == 0) {
		switch (pip->ip_p) {
		case IPPROTO_ICMP:
			iresult = IcmpAliasOut(la, pip, create);
			break;
		case IPPROTO_UDP:
			iresult = UdpAliasOut(la, pip, maxpacketsize, create);
			break;
		case IPPROTO_TCP:
			iresult = TcpAliasOut(la, pip, maxpacketsize, create);
			break;
#ifdef _KERNEL
		case IPPROTO_SCTP:
		  iresult = SctpAlias(la, pip, SN_TO_GLOBAL);
			break;
#endif
		case IPPROTO_GRE: {
			int error;
			struct alias_data ad = {
				.lnk = NULL, 
				.oaddr = NULL, 
				.aaddr = NULL,
				.aport = NULL,
				.sport = NULL,
				.dport = NULL,
				.maxpktsize = 0                  
			};
			/* Walk out chain. */		
			error = find_handler(OUT, IP, la, pip, &ad);
			if (error == 0)
 				iresult = PKT_ALIAS_OK;
 			else
 				iresult = ProtoAliasOut(la, &pip->ip_src, 
				    pip->ip_dst, pip->ip_p, &pip->ip_sum, create);
		}
 			break;
		default:
			iresult = ProtoAliasOut(la, &pip->ip_src,
			    pip->ip_dst, pip->ip_p, &pip->ip_sum, create);
			break;
		}
	} else {
		iresult = FragmentOut(la, &pip->ip_src, &pip->ip_sum);
	}

	SetDefaultAliasAddress(la, addr_save);
getout:
	return (iresult);
}
示例#2
0
int
PacketAliasOut(char *ptr,           /* valid IP packet */
               int  maxpacketsize   /* How much the packet data may grow
                                       (FTP and IRC inline changes) */
              )
{
    int iresult;
    struct in_addr addr_save;
    struct ip *pip;

    if (packetAliasMode & PKT_ALIAS_REVERSE) {
        packetAliasMode &= ~PKT_ALIAS_REVERSE;
        iresult = PacketAliasIn(ptr, maxpacketsize);
        packetAliasMode |= PKT_ALIAS_REVERSE;
        return iresult;
    }

    HouseKeeping();
    ClearCheckNewLink();
    pip = (struct ip *) ptr;

    /* Defense against mangled packets */
    if (ntohs(pip->ip_len) > maxpacketsize
     || (pip->ip_hl<<2) > maxpacketsize)
        return PKT_ALIAS_IGNORED;

    addr_save = GetDefaultAliasAddress();
    if (packetAliasMode & PKT_ALIAS_UNREGISTERED_ONLY)
    {
        u_long addr;
        int iclass;

        iclass = 0;
        addr = ntohl(pip->ip_src.s_addr);
        if      (addr >= UNREG_ADDR_C_LOWER && addr <= UNREG_ADDR_C_UPPER)
            iclass = 3;
        else if (addr >= UNREG_ADDR_B_LOWER && addr <= UNREG_ADDR_B_UPPER)
            iclass = 2;
        else if (addr >= UNREG_ADDR_A_LOWER && addr <= UNREG_ADDR_A_UPPER)
            iclass = 1;

        if (iclass == 0)
        {
            SetDefaultAliasAddress(pip->ip_src);
        }
    }

    iresult = PKT_ALIAS_IGNORED;
    if ((ntohs(pip->ip_off) & IP_OFFMASK) == 0)
    {
        switch (pip->ip_p)
        {
            case IPPROTO_ICMP:
                iresult = IcmpAliasOut(pip);
                break;
            case IPPROTO_UDP:
                iresult = UdpAliasOut(pip);
                break;
            case IPPROTO_TCP:
                iresult = TcpAliasOut(pip, maxpacketsize);
                break;
	    case IPPROTO_GRE:
		if (AliasHandlePptpGreOut(pip) == 0)
		    iresult = PKT_ALIAS_OK;
		else
		    iresult = ProtoAliasOut(pip);
		break;
	    default:
		iresult = ProtoAliasOut(pip);
                break;
        }
    }
    else
    {
        iresult = FragmentOut(pip);
    }

    SetDefaultAliasAddress(addr_save);
    return(iresult);
}
示例#3
0
文件: alias.c 项目: ChaosJohn/freebsd
static int
LibAliasInLocked(struct libalias *la, char *ptr, int maxpacketsize)
{
	struct in_addr alias_addr;
	struct ip *pip;
	int iresult;

	if (la->packetAliasMode & PKT_ALIAS_REVERSE) {
		la->packetAliasMode &= ~PKT_ALIAS_REVERSE;
		iresult = LibAliasOutLocked(la, ptr, maxpacketsize, 1);
		la->packetAliasMode |= PKT_ALIAS_REVERSE;
		goto getout;
	}
	HouseKeeping(la);
	ClearCheckNewLink(la);
	pip = (struct ip *)ptr;
	alias_addr = pip->ip_dst;

	/* Defense against mangled packets */
	if (ntohs(pip->ip_len) > maxpacketsize
	    || (pip->ip_hl << 2) > maxpacketsize) {
		iresult = PKT_ALIAS_IGNORED; 
		goto getout;
	}

	iresult = PKT_ALIAS_IGNORED;
	if ((ntohs(pip->ip_off) & IP_OFFMASK) == 0) {
		switch (pip->ip_p) {
		case IPPROTO_ICMP:
			iresult = IcmpAliasIn(la, pip);
			break;
		case IPPROTO_UDP:
			iresult = UdpAliasIn(la, pip);
			break;
		case IPPROTO_TCP:
			iresult = TcpAliasIn(la, pip);
			break;
#ifdef _KERNEL
		case IPPROTO_SCTP:
		  iresult = SctpAlias(la, pip, SN_TO_LOCAL);
			break;
#endif
 		case IPPROTO_GRE: {
			int error;
			struct alias_data ad = {
				.lnk = NULL, 
				.oaddr = NULL, 
				.aaddr = NULL,
				.aport = NULL,
				.sport = NULL,
				.dport = NULL,
				.maxpktsize = 0                  
			};
			
			/* Walk out chain. */		
			error = find_handler(IN, IP, la, pip, &ad);
			if (error ==  0)
				iresult = PKT_ALIAS_OK;
			else
				iresult = ProtoAliasIn(la, pip->ip_src, 
				    &pip->ip_dst, pip->ip_p, &pip->ip_sum);
		}
 			break; 
		default:
			iresult = ProtoAliasIn(la, pip->ip_src, &pip->ip_dst,
			    pip->ip_p, &pip->ip_sum);
			break;
		}

		if (ntohs(pip->ip_off) & IP_MF) {
			struct alias_link *lnk;

			lnk = FindFragmentIn1(la, pip->ip_src, alias_addr, pip->ip_id);
			if (lnk != NULL) {
				iresult = PKT_ALIAS_FOUND_HEADER_FRAGMENT;
				SetFragmentAddr(lnk, pip->ip_dst);
			} else {
				iresult = PKT_ALIAS_ERROR;
			}
		}
	} else {
		iresult = FragmentIn(la, pip->ip_src, &pip->ip_dst, pip->ip_id,
		    &pip->ip_sum);
	}

getout:
	return (iresult);
}
示例#4
0
int
PacketAliasIn(char *ptr, int maxpacketsize)
{
    struct in_addr alias_addr;
    struct ip *pip;
    int iresult;

    if (packetAliasMode & PKT_ALIAS_REVERSE) {
        packetAliasMode &= ~PKT_ALIAS_REVERSE;
        iresult = PacketAliasOut(ptr, maxpacketsize);
        packetAliasMode |= PKT_ALIAS_REVERSE;
        return iresult;
    }

    HouseKeeping();
    ClearCheckNewLink();
    pip = (struct ip *) ptr;
    alias_addr = pip->ip_dst;
        
    /* Defense against mangled packets */
    if (ntohs(pip->ip_len) > maxpacketsize
     || (pip->ip_hl<<2) > maxpacketsize)
        return PKT_ALIAS_IGNORED;
        
    iresult = PKT_ALIAS_IGNORED;
    if ( (ntohs(pip->ip_off) & IP_OFFMASK) == 0 )
    {
        switch (pip->ip_p)
        {
            case IPPROTO_ICMP:
                iresult = IcmpAliasIn(pip);
                break;
            case IPPROTO_UDP:
                iresult = UdpAliasIn(pip);
                break;
            case IPPROTO_TCP:
                iresult = TcpAliasIn(pip);
                break;
            case IPPROTO_GRE:
		if (packetAliasMode & PKT_ALIAS_PROXY_ONLY ||
		    AliasHandlePptpGreIn(pip) == 0)
		    iresult = PKT_ALIAS_OK;
		else
		    iresult = ProtoAliasIn(pip);
		break;
	    default:
		iresult = ProtoAliasIn(pip);
                break;
        }

        if (ntohs(pip->ip_off) & IP_MF)
        {
            struct alias_link *link;

            link = FindFragmentIn1(pip->ip_src, alias_addr, pip->ip_id);
            if (link != NULL)
            {
                iresult = PKT_ALIAS_FOUND_HEADER_FRAGMENT;
                SetFragmentAddr(link, pip->ip_dst);
            }
            else
            {
                iresult = PKT_ALIAS_ERROR;
            }
        }
    }
    else
    {
        iresult = FragmentIn(pip);
    }

    return(iresult);
}