Пример #1
0
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);
}
Пример #2
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);
}