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