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); }
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); }