static int LibAliasOutLocked(struct libalias *la, char *ptr, /* valid IP packet */ int maxpacketsize, /* How much the packet data may grow (FTP * and IRC inline changes) */ int create /* Create new entries ? */ ) { int iresult; struct in_addr addr_save; struct ip *pip; if (la->packetAliasMode & PKT_ALIAS_REVERSE) { la->packetAliasMode &= ~PKT_ALIAS_REVERSE; iresult = LibAliasInLocked(la, ptr, maxpacketsize); la->packetAliasMode |= PKT_ALIAS_REVERSE; goto getout; } HouseKeeping(la); ClearCheckNewLink(la); pip = (struct ip *)ptr; /* Defense against mangled packets */ if (ntohs(pip->ip_len) > maxpacketsize || (pip->ip_hl << 2) > maxpacketsize) { iresult = PKT_ALIAS_IGNORED; goto getout; } addr_save = GetDefaultAliasAddress(la); if (la->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(la, pip->ip_src); } } else if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY) { SetDefaultAliasAddress(la, pip->ip_src); } iresult = PKT_ALIAS_IGNORED; if ((ntohs(pip->ip_off) & IP_OFFMASK) == 0) { switch (pip->ip_p) { case IPPROTO_ICMP: iresult = IcmpAliasOut(la, pip, create); break; case IPPROTO_UDP: iresult = UdpAliasOut(la, pip, maxpacketsize, create); break; case IPPROTO_TCP: iresult = TcpAliasOut(la, pip, maxpacketsize, create); break; #ifdef _KERNEL case IPPROTO_SCTP: iresult = SctpAlias(la, pip, SN_TO_GLOBAL); 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(OUT, IP, la, pip, &ad); if (error == 0) iresult = PKT_ALIAS_OK; else iresult = ProtoAliasOut(la, &pip->ip_src, pip->ip_dst, pip->ip_p, &pip->ip_sum, create); } break; default: iresult = ProtoAliasOut(la, &pip->ip_src, pip->ip_dst, pip->ip_p, &pip->ip_sum, create); break; } } else { iresult = FragmentOut(la, &pip->ip_src, &pip->ip_sum); } SetDefaultAliasAddress(la, addr_save); getout: return (iresult); }
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); }
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); }