if (packetAliasMode & PKT_ALIAS_REVERSE) return PacketAliasIn(ptr, maxpacketsize);
if (packetAliasMode & PKT_ALIAS_REVERSE) { packetAliasMode &= ~PKT_ALIAS_REVERSE; iresult = PacketAliasIn(ptr, maxpacketsize); packetAliasMode |= PKT_ALIAS_REVERSE; return iresult; }
UdpAliasIn(struct ip *pip){    struct udphdr *ud;    struct alias_link *link;/* Return if proxy-only mode is enabled */    if (packetAliasMode & PKT_ALIAS_PROXY_ONLY)        return PKT_ALIAS_OK;    ud = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2));    link = FindUdpTcpIn(pip->ip_src, pip->ip_dst,                        ud->uh_sport, ud->uh_dport,                        IPPROTO_UDP);    if (link != NULL)    {        struct in_addr alias_address;        struct in_addr original_address;        u_short alias_port;        int accumulate;        u_short *sptr;	int r = 0;        alias_address = GetAliasAddress(link);        original_address = GetOriginalAddress(link);        alias_port = ud->uh_dport;        ud->uh_dport = GetOriginalPort(link);/* If NETBIOS Datagram, It should be alias address in UDP Data, too */		if (ntohs(ud->uh_dport) == NETBIOS_DGM_PORT_NUMBER         || ntohs(ud->uh_sport) == NETBIOS_DGM_PORT_NUMBER )		{            r = AliasHandleUdpNbt(pip, link, &original_address, ud->uh_dport);		} else if (ntohs(ud->uh_dport) == NETBIOS_NS_PORT_NUMBER         || ntohs(ud->uh_sport) == NETBIOS_NS_PORT_NUMBER )		{            r = AliasHandleUdpNbtNS(pip, link, 								&alias_address,								&alias_port,								&original_address, 								&ud->uh_dport );		}        if (ntohs(ud->uh_dport) == CUSEEME_PORT_NUMBER)            AliasHandleCUSeeMeIn(pip, original_address);/* If UDP checksum is not zero, then adjust since destination port *//* is being unaliased and destination port is being altered.       */        if (ud->uh_sum != 0)        {            accumulate  = alias_port;            accumulate -= ud->uh_dport;            sptr = (u_short *) &alias_address;            accumulate += *sptr++;            accumulate += *sptr;            sptr = (u_short *) &original_address;            accumulate -= *sptr++;            accumulate -= *sptr;            ADJUST_CHECKSUM(accumulate, ud->uh_sum)        }/* Restore original IP address */        DifferentialChecksum(&pip->ip_sum,                             (u_short *) &original_address,                             (u_short *) &pip->ip_dst,                             2);        pip->ip_dst = original_address;	/*	 * If we cannot figure out the packet, ignore it.	 */	if (r < 0)	    return(PKT_ALIAS_IGNORED);	else	    return(PKT_ALIAS_OK);    }    return(PKT_ALIAS_IGNORED);}static intUdpAliasOut(struct ip *pip){    struct udphdr *ud;    struct alias_link *link;/* Return if proxy-only mode is enabled */    if (packetAliasMode & PKT_ALIAS_PROXY_ONLY)        return PKT_ALIAS_OK;    ud = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2));    link = FindUdpTcpOut(pip->ip_src, pip->ip_dst,                         ud->uh_sport, ud->uh_dport,                         IPPROTO_UDP);    if (link != NULL)    {        u_short alias_port;        struct in_addr alias_address;        alias_address = GetAliasAddress(link);        alias_port = GetAliasPort(link);        if (ntohs(ud->uh_dport) == CUSEEME_PORT_NUMBER)            AliasHandleCUSeeMeOut(pip, link);/* If NETBIOS Datagram, It should be alias address in UDP Data, too */		if (ntohs(ud->uh_dport) == NETBIOS_DGM_PORT_NUMBER         || ntohs(ud->uh_sport) == NETBIOS_DGM_PORT_NUMBER )		{            AliasHandleUdpNbt(pip, link, &alias_address, alias_port);		} else if (ntohs(ud->uh_dport) == NETBIOS_NS_PORT_NUMBER         || ntohs(ud->uh_sport) == NETBIOS_NS_PORT_NUMBER )		{            AliasHandleUdpNbtNS(pip, link,								&pip->ip_src,								&ud->uh_sport,							    &alias_address,							 	&alias_port); 		}/* If UDP checksum is not zero, adjust since source port is *//* being aliased and source address is being altered        */        if (ud->uh_sum != 0)        {            int accumulate;            u_short *sptr;            accumulate  = ud->uh_sport;            accumulate -= alias_port;            sptr = (u_short *) &(pip->ip_src);            accumulate += *sptr++;            accumulate += *sptr;            sptr = (u_short *) &alias_address;            accumulate -= *sptr++;            accumulate -= *sptr;            ADJUST_CHECKSUM(accumulate, ud->uh_sum)        }/* Put alias port in UDP header */        ud->uh_sport = alias_port;/* Change source address */        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 intTcpAliasIn(struct ip *pip){    struct tcphdr *tc;    struct alias_link *link;    tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));    link = FindUdpTcpIn(pip->ip_src, pip->ip_dst,                        tc->th_sport, tc->th_dport,                        IPPROTO_TCP);    if (link != NULL)    {        struct in_addr alias_address;        struct in_addr original_address;        struct in_addr proxy_address;        u_short alias_port;        u_short proxy_port;        int accumulate;        u_short *sptr;        alias_address = GetAliasAddress(link);        original_address = GetOriginalAddress(link);        proxy_address = GetProxyAddress(link);        alias_port = tc->th_dport;        tc->th_dport = GetOriginalPort(link);        proxy_port = GetProxyPort(link);/* Adjust TCP checksum since destination port is being unaliased *//* and destination port is being altered.                        */        accumulate  = alias_port;        accumulate -= tc->th_dport;        sptr = (u_short *) &alias_address;        accumulate += *sptr++;        accumulate += *sptr;        sptr = (u_short *) &original_address;        accumulate -= *sptr++;        accumulate -= *sptr;/* If this is a proxy, then modify the tcp source port  and   checksum accumulation */        if (proxy_port != 0)        {            accumulate += tc->th_sport;            tc->th_sport = proxy_port;            accumulate -= tc->th_sport;            sptr = (u_short *) &pip->ip_src;            accumulate += *sptr++;            accumulate += *sptr;            sptr = (u_short *) &proxy_address;            accumulate -= *sptr++;            accumulate -= *sptr;        }/* See if ack number needs to be modified */        if (GetAckModified(link) == 1)        {            int delta;            delta = GetDeltaAckIn(pip, link);            if (delta != 0)            {                sptr = (u_short *) &tc->th_ack;                accumulate += *sptr++;                accumulate += *sptr;                tc->th_ack = htonl(ntohl(tc->th_ack) - delta);                sptr = (u_short *) &tc->th_ack;                accumulate -= *sptr++;                accumulate -= *sptr;            }        }        ADJUST_CHECKSUM(accumulate, tc->th_sum);/* Restore original IP address */        sptr = (u_short *) &pip->ip_dst;        accumulate  = *sptr++;        accumulate += *sptr;        pip->ip_dst = original_address;        sptr = (u_short *) &pip->ip_dst;        accumulate -= *sptr++;        accumulate -= *sptr;/* If this is a transparent proxy packet, then modify the source   address */        if (proxy_address.s_addr != 0)        {            sptr = (u_short *) &pip->ip_src;            accumulate += *sptr++;            accumulate += *sptr;            pip->ip_src = proxy_address;            sptr = (u_short *) &pip->ip_src;            accumulate -= *sptr++;            accumulate -= *sptr;        }        ADJUST_CHECKSUM(accumulate, pip->ip_sum);/* Monitor TCP connection state */        TcpMonitorIn(pip, link);        return(PKT_ALIAS_OK);    }    return(PKT_ALIAS_IGNORED);}static intTcpAliasOut(struct ip *pip, int maxpacketsize){    int proxy_type;    u_short dest_port;    u_short proxy_server_port;    struct in_addr dest_address;    struct in_addr proxy_server_address;    struct tcphdr *tc;    struct alias_link *link;    tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));    proxy_type = ProxyCheck(pip, &proxy_server_address, &proxy_server_port);    if (proxy_type == 0 && (packetAliasMode & PKT_ALIAS_PROXY_ONLY))        return PKT_ALIAS_OK;/* If this is a transparent proxy, save original destination,   then alter the destination and adust checksums */    dest_port = tc->th_dport;    dest_address = pip->ip_dst;    if (proxy_type != 0)    {        int accumulate;        u_short *sptr;        accumulate = tc->th_dport;        tc->th_dport = proxy_server_port;        accumulate -= tc->th_dport;        sptr = (u_short *) &(pip->ip_dst);        accumulate += *sptr++;        accumulate += *sptr;        sptr = (u_short *) &proxy_server_address;        accumulate -= *sptr++;        accumulate -= *sptr;        ADJUST_CHECKSUM(accumulate, tc->th_sum);        sptr = (u_short *) &(pip->ip_dst);        accumulate  = *sptr++;        accumulate += *sptr;        pip->ip_dst = proxy_server_address;        sptr = (u_short *) &(pip->ip_dst);        accumulate -= *sptr++;        accumulate -= *sptr;        ADJUST_CHECKSUM(accumulate, pip->ip_sum);    }    link = FindUdpTcpOut(pip->ip_src, pip->ip_dst,                         tc->th_sport, tc->th_dport,                         IPPROTO_TCP);    if (link !=NULL)    {        u_short alias_port;        struct in_addr alias_address;        int accumulate;        u_short *sptr;/* Save original destination address, if this is a proxy packet.   Also modify packet to include destination encoding. */        if (proxy_type != 0)        {            SetProxyPort(link, dest_port);            SetProxyAddress(link, dest_address);            ProxyModify(link, pip, maxpacketsize, proxy_type);        }/* Get alias address and port */        alias_port = GetAliasPort(link);        alias_address = GetAliasAddress(link);/* Monitor tcp connection state */        TcpMonitorOut(pip, link);/* Special processing for IP encoding protocols */        if (ntohs(tc->th_dport) == FTP_CONTROL_PORT_NUMBER         || ntohs(tc->th_sport) == FTP_CONTROL_PORT_NUMBER)            AliasHandleFtpOut(pip, link, maxpacketsize);        if (ntohs(tc->th_dport) == IRC_CONTROL_PORT_NUMBER_1         || ntohs(tc->th_dport) == IRC_CONTROL_PORT_NUMBER_2)            AliasHandleIrcOut(pip, link, maxpacketsize);/* Adjust TCP checksum since source port is being aliased *//* and source address is being altered                    */        accumulate  = tc->th_sport;        tc->th_sport = alias_port;        accumulate -= tc->th_sport;        sptr = (u_short *) &(pip->ip_src);        accumulate += *sptr++;        accumulate += *sptr;        sptr = (u_short *) &alias_address;        accumulate -= *sptr++;        accumulate -= *sptr;/* Modify sequence number if necessary */        if (GetAckModified(link) == 1)        {            int delta;            delta = GetDeltaSeqOut(pip, link);            if (delta != 0)            {                sptr = (u_short *) &tc->th_seq;                accumulate += *sptr++;                accumulate += *sptr;                tc->th_seq = htonl(ntohl(tc->th_seq) + delta);                sptr = (u_short *) &tc->th_seq;                accumulate -= *sptr++;                accumulate -= *sptr;            }        }        ADJUST_CHECKSUM(accumulate, tc->th_sum)/* Change source address */        sptr = (u_short *) &(pip->ip_src);        accumulate  = *sptr++;        accumulate += *sptr;        pip->ip_src = alias_address;        sptr = (u_short *) &(pip->ip_src);        accumulate -= *sptr++;        accumulate -= *sptr;        ADJUST_CHECKSUM(accumulate, pip->ip_sum)        return(PKT_ALIAS_OK);    }    return(PKT_ALIAS_IGNORED);}/* Fragment Handling    FragmentIn()    FragmentOut()The packet aliasing module has a limited ability for handling IPfragments.  If the ICMP, TCP or UDP header is in the first fragmentreceived, then the id number of the IP packet is saved, and otherfragments are identified according to their ID number and IP addressthey were sent from.  Pointers to unresolved fragments can also besaved and recalled when a header fragment is seen.*//* Local prototypes */static int FragmentIn(struct ip *);static int FragmentOut(struct ip *);static intFragmentIn(struct ip *pip){    struct alias_link *link;    link = FindFragmentIn2(pip->ip_src, pip->ip_dst, pip->ip_id);    if (link != NULL)    {        struct in_addr original_address;        GetFragmentAddr(link, &original_address);        DifferentialChecksum(&pip->ip_sum,                             (u_short *) &original_address,                             (u_short *) &pip->ip_dst,                             2);        pip->ip_dst = original_address;            return(PKT_ALIAS_OK);    }    return(PKT_ALIAS_UNRESOLVED_FRAGMENT);}static intFragmentOut(struct ip *pip){    struct in_addr alias_address;    alias_address = FindAliasAddress(pip->ip_src);    DifferentialChecksum(&pip->ip_sum,                         (u_short *) &alias_address,                         (u_short *) &pip->ip_src,                          2);    pip->ip_src = alias_address;    return(PKT_ALIAS_OK);}/* Outside World Access        PacketAliasSaveFragment()        PacketAliasGetFragment()        PacketAliasFragmentIn()        PacketAliasIn()        PacketAliasOut()(prototypes in alias.h)*/intPacketAliasSaveFragment(char *ptr){    int iresult;    struct alias_link *link;    struct ip *pip;    pip = (struct ip *) ptr;    link = AddFragmentPtrLink(pip->ip_src, pip->ip_id);    iresult = PKT_ALIAS_ERROR;    if (link != NULL)    {        SetFragmentPtr(link, ptr);        iresult = PKT_ALIAS_OK;    }    return(iresult);}char *PacketAliasGetFragment(char *ptr){    struct alias_link *link;    char *fptr;    struct ip *pip;    pip = (struct ip *) ptr;    link = FindFragmentPtr(pip->ip_src, pip->ip_id);    if (link != NULL)    {        GetFragmentPtr(link, &fptr);        SetFragmentPtr(link, NULL);        SetExpire(link, 0); /* Deletes link */        return(fptr);    }    else    {        return(NULL);    }}voidPacketAliasFragmentIn(char *ptr,          /* Points to correctly de-aliased                                             header fragment */                      char *ptr_fragment  /* Points to fragment which must                                             be de-aliased   */                     ){    struct ip *pip;    struct ip *fpip;    pip = (struct ip *) ptr;    fpip = (struct ip *) ptr_fragment;    DifferentialChecksum(&fpip->ip_sum,                         (u_short *) &pip->ip_dst,                         (u_short *) &fpip->ip_dst,                         2);    fpip->ip_dst = pip->ip_dst;}intPacketAliasIn(char *ptr, int maxpacketsize){    struct in_addr alias_addr;    struct ip *pip;    int iresult;    if (packetAliasMode & PKT_ALIAS_REVERSE)        return PacketAliasOut(ptr, maxpacketsize);    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:		iresult = PptpAliasIn(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);}/* Unregistered address ranges *//* 10.0.0.0   ->   10.255.255.255 */#define UNREG_ADDR_A_LOWER 0x0a000000#define UNREG_ADDR_A_UPPER 0x0affffff/* 172.16.0.0  ->  172.31.255.255 */#define UNREG_ADDR_B_LOWER 0xac100000#define UNREG_ADDR_B_UPPER 0xac1fffff/* 192.168.0.0 -> 192.168.255.255 */#define UNREG_ADDR_C_LOWER 0xc0a80000#define UNREG_ADDR_C_UPPER 0xc0a8ffffintPacketAliasOut(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)        return PacketAliasIn(ptr, maxpacketsize);    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)    {        unsigned int 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:		iresult = PptpAliasOut(pip);                break;        }    }    else    {        iresult = FragmentOut(pip);    }    SetDefaultAliasAddress(addr_save);    return(iresult);}