示例#1
0
static int
IcmpAliasOut1(struct ip *pip)
{
/*
    Alias outgoing echo and timestamp requests.
    De-alias outgoing echo and timestamp replies.
*/
    struct alias_link *link;
    struct icmp *ic;

    ic = (struct icmp *) ((char *) pip + (pip->ip_hl << 2));

/* Save overwritten data for when echo packet returns */
    link = FindIcmpOut(pip->ip_src, pip->ip_dst, ic->icmp_id, 1);
    if (link != NULL)
    {
        u_short alias_id;
        int accumulate;

        alias_id = GetAliasPort(link);

/* Since data field is being modified, adjust ICMP checksum */
        accumulate  = ic->icmp_id;
        accumulate -= alias_id;
        ADJUST_CHECKSUM(accumulate, ic->icmp_cksum);

/* Alias sequence number */
        ic->icmp_id = alias_id;

/* Change source address */
        {
            struct in_addr alias_address;

            alias_address = GetAliasAddress(link);
            DifferentialChecksum(&pip->ip_sum,
                                 (u_short *) &alias_address,
                                 (u_short *) &pip->ip_src,
                                 2);
            pip->ip_src = alias_address;
        }

        return(PKT_ALIAS_OK);
    }
    return(PKT_ALIAS_IGNORED);
}
示例#2
0
文件: alias.c 项目: ChaosJohn/freebsd
static int
IcmpAliasOut2(struct libalias *la, struct ip *pip)
{
/*
    Alias outgoing ICMP error messages containing
    IP header and first 64 bits of datagram.
*/
	struct ip *ip;
	struct icmp *ic, *ic2;
	struct udphdr *ud;
	struct tcphdr *tc;
	struct alias_link *lnk;

	LIBALIAS_LOCK_ASSERT(la);
	ic = (struct icmp *)ip_next(pip);
	ip = &ic->icmp_ip;

	ud = (struct udphdr *)ip_next(ip);
	tc = (struct tcphdr *)ip_next(ip);
	ic2 = (struct icmp *)ip_next(ip);

	if (ip->ip_p == IPPROTO_UDP)
		lnk = FindUdpTcpOut(la, ip->ip_dst, ip->ip_src,
		    ud->uh_dport, ud->uh_sport,
		    IPPROTO_UDP, 0);
	else if (ip->ip_p == IPPROTO_TCP)
		lnk = FindUdpTcpOut(la, ip->ip_dst, ip->ip_src,
		    tc->th_dport, tc->th_sport,
		    IPPROTO_TCP, 0);
	else if (ip->ip_p == IPPROTO_ICMP) {
		if (ic2->icmp_type == ICMP_ECHO || ic2->icmp_type == ICMP_TSTAMP)
			lnk = FindIcmpOut(la, ip->ip_dst, ip->ip_src, ic2->icmp_id, 0);
		else
			lnk = NULL;
	} else
		lnk = NULL;

	if (lnk != NULL) {
		if (ip->ip_p == IPPROTO_UDP || ip->ip_p == IPPROTO_TCP) {
			int accumulate;
			struct in_addr alias_address;
			u_short alias_port;

			alias_address = GetAliasAddress(lnk);
			alias_port = GetAliasPort(lnk);

/* Adjust ICMP checksum */
			accumulate = twowords(&ip->ip_dst);
			accumulate -= twowords(&alias_address);
			accumulate += ud->uh_dport;
			accumulate -= alias_port;
			ADJUST_CHECKSUM(accumulate, ic->icmp_cksum);

/*
 * Alias address in IP header if it comes from the host
 * the original TCP/UDP packet was destined for.
 */
			if (pip->ip_src.s_addr == ip->ip_dst.s_addr) {
				DifferentialChecksum(&pip->ip_sum,
				    &alias_address, &pip->ip_src, 2);
				pip->ip_src = alias_address;
			}
/* Alias address and port number of original IP packet
fragment contained in ICMP data section */
			ip->ip_dst = alias_address;
			ud->uh_dport = alias_port;
		} else if (ip->ip_p == IPPROTO_ICMP) {
			int accumulate;
			struct in_addr alias_address;
			u_short alias_id;

			alias_address = GetAliasAddress(lnk);
			alias_id = GetAliasPort(lnk);

/* Adjust ICMP checksum */
			accumulate = twowords(&ip->ip_dst);
			accumulate -= twowords(&alias_address);
			accumulate += ic2->icmp_id;
			accumulate -= alias_id;
			ADJUST_CHECKSUM(accumulate, ic->icmp_cksum);

/*
 * Alias address in IP header if it comes from the host
 * the original ICMP message was destined for.
 */
			if (pip->ip_src.s_addr == ip->ip_dst.s_addr) {
				DifferentialChecksum(&pip->ip_sum,
				    &alias_address, &pip->ip_src, 2);
				pip->ip_src = alias_address;
			}
/* Alias address of original IP packet and sequence number of
   embedded ICMP datagram */
			ip->ip_dst = alias_address;
			ic2->icmp_id = alias_id;
		}
		return (PKT_ALIAS_OK);
	}
	return (PKT_ALIAS_IGNORED);
}