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); }
static void DoAliasing (int fd, int direction) { int bytes; int origBytes; int status; int addrSize; struct ip* ip; if (assignAliasAddr) { SetAliasAddressFromIfName (ifName); assignAliasAddr = 0; } /* * Get packet from socket. */ addrSize = sizeof packetAddr; origBytes = recvfrom (fd, packetBuf, sizeof packetBuf, 0, (struct sockaddr*) &packetAddr, &addrSize); if (origBytes == -1) { if (errno != EINTR) Warn ("read from divert socket failed"); return; } /* * This is a IP packet. */ ip = (struct ip*) packetBuf; if (direction == DONT_KNOW) { if (packetAddr.sin_addr.s_addr == INADDR_ANY) direction = OUTPUT; else direction = INPUT; } if (verbose) { /* * Print packet direction and protocol type. */ printf (direction == OUTPUT ? "Out " : "In "); switch (ip->ip_p) { case IPPROTO_TCP: printf ("[TCP] "); break; case IPPROTO_UDP: printf ("[UDP] "); break; case IPPROTO_ICMP: printf ("[ICMP] "); break; default: printf ("[%d] ", ip->ip_p); break; } /* * Print addresses. */ PrintPacket (ip); } if (direction == OUTPUT) { /* * Outgoing packets. Do aliasing. */ PacketAliasOut (packetBuf, IP_MAXPACKET); } else { /* * Do aliasing. */ status = PacketAliasIn (packetBuf, IP_MAXPACKET); if (status == PKT_ALIAS_IGNORED && dropIgnoredIncoming) { if (verbose) printf (" dropped.\n"); if (logDropped) SyslogPacket (ip, LOG_WARNING, "denied"); return; } } /* * Length might have changed during aliasing. */ bytes = ntohs (ip->ip_len); /* * Update alias overhead size for outgoing packets. */ if (direction == OUTPUT && bytes - origBytes > aliasOverhead) aliasOverhead = bytes - origBytes; if (verbose) { /* * Print addresses after aliasing. */ printf (" aliased to\n"); printf (" "); PrintPacket (ip); printf ("\n"); } packetLen = bytes; packetSock = fd; packetDirection = direction; FlushPacketBuffer (fd); }
static void DoAliasing(int fd, int direction) { int bytes; int origBytes; char buf[IP_MAXPACKET]; struct sockaddr_in addr; int wrote; int status; int addrSize; struct ip* ip; char msgBuf[80]; if (assignAliasAddr) { SetAliasAddressFromIfName(ifName); assignAliasAddr = 0; } /* * Get packet from socket. */ addrSize = sizeof addr; origBytes = recvfrom(fd, buf, sizeof buf, 0, (struct sockaddr *)&addr, &addrSize); if (origBytes == -1) { if (errno != EINTR) Warn("read from divert socket failed"); return; } /* * This is a IP packet. */ ip = (struct ip *)buf; if (direction == DONT_KNOW) { if (addr.sin_addr.s_addr == INADDR_ANY) direction = OUTPUT; else direction = INPUT; } if (verbose) { /* * Print packet direction and protocol type. */ printf(direction == OUTPUT ? "Out " : "In "); switch (ip->ip_p) { case IPPROTO_TCP: printf("[TCP] "); break; case IPPROTO_UDP: printf("[UDP] "); break; case IPPROTO_ICMP: printf("[ICMP] "); break; default: printf("[%d] ", ip->ip_p); break; } /* * Print addresses. */ PrintPacket(ip); } if (direction == OUTPUT) { /* * Outgoing packets. Do aliasing. */ PacketAliasOut(buf, IP_MAXPACKET); } else { /* * Do aliasing. */ status = PacketAliasIn(buf, IP_MAXPACKET); if (status == PKT_ALIAS_IGNORED && dropIgnoredIncoming) { if (verbose) printf(" dropped.\n"); if (logDropped) SyslogPacket(ip, LOG_WARNING, "denied"); return; } } /* * Length might have changed during aliasing. */ bytes = ntohs(ip->ip_len); /* * Update alias overhead size for outgoing packets. */ if (direction == OUTPUT && bytes - origBytes > aliasOverhead) aliasOverhead = bytes - origBytes; if (verbose) { /* * Print addresses after aliasing. */ printf(" aliased to\n"); printf(" "); PrintPacket(ip); printf("\n"); } /* * Put packet back for processing. */ wrote = sendto(fd, buf, bytes, 0, (struct sockaddr *)&addr, sizeof addr); if (wrote != bytes) { if (errno == EMSGSIZE) { if (direction == OUTPUT && ifMTU != -1) SendNeedFragIcmp(icmpSock, (struct ip *)buf, ifMTU - aliasOverhead); } else if (errno == EACCES && logIpfwDenied) { sprintf(msgBuf, "failed to write packet back"); Warn(msgBuf); } } }