Esempio n. 1
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);
}
Esempio n. 2
0
static void DoAliasing (int fd, int direction)
{
	int			bytes;
	int			origBytes;
	int			status;
	int			addrSize;
	struct ip*		ip;

	if (assignAliasAddr) {

		SetAliasAddressFromIfName (ifName);
		assignAliasAddr = 0;
	}
/*
 * Get packet from socket.
 */
	addrSize  = sizeof packetAddr;
	origBytes = recvfrom (fd,
			      packetBuf,
			      sizeof packetBuf,
			      0,
			      (struct sockaddr*) &packetAddr,
			      &addrSize);

	if (origBytes == -1) {

		if (errno != EINTR)
			Warn ("read from divert socket failed");

		return;
	}
/*
 * This is a IP packet.
 */
	ip = (struct ip*) packetBuf;
	if (direction == DONT_KNOW) {
		if (packetAddr.sin_addr.s_addr == INADDR_ANY)
			direction = OUTPUT;
		else
			direction = INPUT;
	}

	if (verbose) {
/*
 * Print packet direction and protocol type.
 */
		printf (direction == OUTPUT ? "Out " : "In  ");

		switch (ip->ip_p) {
		case IPPROTO_TCP:
			printf ("[TCP]  ");
			break;

		case IPPROTO_UDP:
			printf ("[UDP]  ");
			break;

		case IPPROTO_ICMP:
			printf ("[ICMP] ");
			break;

		default:
			printf ("[%d]    ", ip->ip_p);
			break;
		}
/*
 * Print addresses.
 */
		PrintPacket (ip);
	}

	if (direction == OUTPUT) {
/*
 * Outgoing packets. Do aliasing.
 */
		PacketAliasOut (packetBuf, IP_MAXPACKET);
	}
	else {

/*
 * Do aliasing.
 */	
		status = PacketAliasIn (packetBuf, IP_MAXPACKET);
		if (status == PKT_ALIAS_IGNORED &&
		    dropIgnoredIncoming) {

			if (verbose)
				printf (" dropped.\n");

			if (logDropped)
				SyslogPacket (ip, LOG_WARNING, "denied");

			return;
		}
	}
/*
 * Length might have changed during aliasing.
 */
	bytes = ntohs (ip->ip_len);
/*
 * Update alias overhead size for outgoing packets.
 */
	if (direction == OUTPUT &&
	    bytes - origBytes > aliasOverhead)
		aliasOverhead = bytes - origBytes;

	if (verbose) {
		
/*
 * Print addresses after aliasing.
 */
		printf (" aliased to\n");
		printf ("           ");
		PrintPacket (ip);
		printf ("\n");
	}

	packetLen  	= bytes;
	packetSock 	= fd;
	packetDirection = direction;

	FlushPacketBuffer (fd);
}
Esempio n. 3
0
static void
DoAliasing(int fd, int direction)
{
	int			bytes;
	int			origBytes;
	char			buf[IP_MAXPACKET];
	struct sockaddr_in	addr;
	int			wrote;
	int			status;
	int			addrSize;
	struct ip*		ip;
	char			msgBuf[80];

	if (assignAliasAddr) {
		SetAliasAddressFromIfName(ifName);
		assignAliasAddr = 0;
	}
/*
 * Get packet from socket.
 */
	addrSize  = sizeof addr;
	origBytes = recvfrom(fd,
			     buf,
			     sizeof buf,
			     0,
			     (struct sockaddr *)&addr,
			     &addrSize);

	if (origBytes == -1) {
		if (errno != EINTR)
			Warn("read from divert socket failed");

		return;
	}
/*
 * This is a IP packet.
 */
	ip = (struct ip *)buf;
	if (direction == DONT_KNOW) {
		if (addr.sin_addr.s_addr == INADDR_ANY)
			direction = OUTPUT;
		else
			direction = INPUT;
	}

	if (verbose) {
/*
 * Print packet direction and protocol type.
 */
		printf(direction == OUTPUT ? "Out " : "In  ");

		switch (ip->ip_p) {
		case IPPROTO_TCP:
			printf("[TCP]  ");
			break;

		case IPPROTO_UDP:
			printf("[UDP]  ");
			break;

		case IPPROTO_ICMP:
			printf("[ICMP] ");
			break;

		default:
			printf("[%d]	", ip->ip_p);
			break;
		}
/*
 * Print addresses.
 */
		PrintPacket(ip);
	}

	if (direction == OUTPUT) {
/*
 * Outgoing packets. Do aliasing.
 */
		PacketAliasOut(buf, IP_MAXPACKET);
	} else {
/*
 * Do aliasing.
 */
		status = PacketAliasIn(buf, IP_MAXPACKET);
		if (status == PKT_ALIAS_IGNORED &&
		    dropIgnoredIncoming) {
			if (verbose)
				printf(" dropped.\n");

			if (logDropped)
				SyslogPacket(ip, LOG_WARNING, "denied");

			return;
		}
	}
/*
 * Length might have changed during aliasing.
 */
	bytes = ntohs(ip->ip_len);
/*
 * Update alias overhead size for outgoing packets.
 */
	if (direction == OUTPUT &&
	    bytes - origBytes > aliasOverhead)
		aliasOverhead = bytes - origBytes;

	if (verbose) {
/*
 * Print addresses after aliasing.
 */
		printf(" aliased to\n");
		printf("	   ");
		PrintPacket(ip);
		printf("\n");
	}

/*
 * Put packet back for processing.
 */
	wrote = sendto(fd,
		       buf,
		       bytes,
		       0,
		       (struct sockaddr *)&addr,
		       sizeof addr);

	if (wrote != bytes) {
		if (errno == EMSGSIZE) {
			if (direction == OUTPUT &&
			    ifMTU != -1)
				SendNeedFragIcmp(icmpSock,
						 (struct ip *)buf,
						 ifMTU - aliasOverhead);
		} else if (errno == EACCES && logIpfwDenied) {
			sprintf(msgBuf, "failed to write packet back");
			Warn(msgBuf);
		}
	}
}