/* * We have been called with an ip-packet located on stack in * _eth_send_loopback(). Hence, it's safe to call _eth_send() again * here. MAC-header is in front of 'ip'. */ int loopback_device (in_Header *ip) { int ip_hlen, ip_len; DWORD ip_dst; DWORD ip_ofs; WORD ip_flg; if (!loopback_enable || !_chk_ip_header(ip)) /* silently discard */ return (-1); ip_hlen = in_GetHdrLen (ip); /* length of IP-header (w/options) */ ip_len = intel16 (ip->length); /* total length of IP-packet */ ip_dst = ip->destination; ip->destination = ip->source; /* swap source and destination */ ip->source = ip_dst; ip->checksum = 0; ip->checksum = ~checksum (ip, ip_hlen); /* redo check-sum */ ip_ofs = intel16 (ip->frag_ofs); ip_flg = ip_ofs & ~IP_OFFMASK; ip_ofs = (ip_ofs & IP_OFFMASK) << 3; /* 0 <= ip_ofs <= 65536-8 */ if (ip_ofs || (ip_flg & IP_MF)) /* fragment; let _ip_fragment() */ return (ip_len); /* handle it on next poll */ if (ip->proto == ICMP_PROTO) { ICMP_PKT *icmp = (ICMP_PKT*) ((BYTE*)ip + ip_hlen); int len = icmp_loopback (icmp, ip_len - ip_hlen); if (len > 0) return (ip_hlen+len); } else if (ip->proto == UDP_PROTO) { udp_Header *udp = (udp_Header*) ((BYTE*)ip + ip_hlen); int len = udp_loopback (udp, ip_len-ip_hlen); if (len > 0) return (ip_hlen+len); } if (loopback_handler) ip_len = (*loopback_handler) (ip); return (ip_len); }
/** * \def loopback_device(). * * We have been called with an IP-packet located on stack by `send_loopback()' * (in pcsed.c). Hence, it's safe to call _eth_send() again here. * MAC-header is in front of 'ip'. */ int loopback_device (in_Header *ip) { int ip_len = 0; DWORD ip_dst; DWORD ip_ofs; WORD ip_flg; if (!(loopback_mode & LBACK_MODE_ENABLE)) return (-1); if (ip->ver == 4) { int ip_hlen; if (!_chk_ip4_header(ip)) /* silently discard */ return (-1); ip_hlen = in_GetHdrLen (ip); /* length of IP-header (w/options) */ ip_len = intel16 (ip->length); /* total length of IP-packet */ ip_dst = ip->destination; ip->destination = ip->source; /* swap source and destination */ ip->source = ip_dst; ip->checksum = 0; ip->checksum = ~CHECKSUM (ip, ip_hlen); /* redo check-sum */ ip_ofs = intel16 (ip->frag_ofs); ip_flg = (WORD) (ip_ofs & ~IP_OFFMASK); ip_ofs = (ip_ofs & IP_OFFMASK) << 3; /* 0 <= ip_ofs <= 65536-8 */ if (ip_ofs || (ip_flg & IP_MF)) /* fragment; let ip4_defragment() */ return (ip_len); /* handle it on next poll */ if (ip->proto == ICMP_PROTO) { ICMP_PKT *icmp = (ICMP_PKT*) ((BYTE*)ip + ip_hlen); int len = icmp_loopback (icmp, ip_len - ip_hlen); if (len > 0) return (ip_hlen+len); } else if (ip->proto == UDP_PROTO) { udp_Header *udp = (udp_Header*) ((BYTE*)ip + ip_hlen); int len = udp_loopback (udp, ip_len-ip_hlen); if (len > 0) return (ip_hlen+len); } } #if defined(USE_IPV6) else if (ip->ver == 6) { in6_Header *ip6 = (in6_Header*)ip; ip6_address ip6_dst; ip_len = intel16 (ip6->len); memcpy (&ip6_dst, &ip6->destination, sizeof(ip6_dst)); memcpy (&ip6->destination, &ip6->source, sizeof(ip6->destination)); memcpy (&ip6->source, &ip6_dst, sizeof(ip6->source)); if (ip6->next_hdr == IP6_NEXT_ICMP) { ICMP_PKT *icmp = (ICMP_PKT*) (ip6 + 1); int len = icmp_loopback (icmp, ip_len); if (len > 0) return (len + sizeof(*ip6)); } else if (ip6->next_hdr == UDP_PROTO) { udp_Header *udp = (udp_Header*) (ip6 + 1); int len = udp_loopback (udp, ip_len); if (len > 0) return (len + sizeof(*ip6)); } } else { (*_printf) ("%s: Illegal IP-packet (ver %d) for loopback device\n", __FILE__, ip->ver); return (-1); } #endif if (loopback_handler) ip_len = (*loopback_handler) (ip); return (ip_len); }