static void FlushPacketBuffer (int fd) { int wrote; char msgBuf[80]; /* * Put packet back for processing. */ wrote = sendto (fd, packetBuf, packetLen, 0, (struct sockaddr*) &packetAddr, sizeof packetAddr); if (wrote != packetLen) { /* * If buffer space is not available, * just return. Main loop will take care of * retrying send when space becomes available. */ if (errno == ENOBUFS) return; if (errno == EMSGSIZE) { if (packetDirection == OUTPUT && ifMTU != -1) SendNeedFragIcmp (icmpSock, (struct ip*) packetBuf, ifMTU - aliasOverhead); } else { sprintf (msgBuf, "failed to write packet back"); Warn (msgBuf); } } packetSock = -1; }
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); } } }