Ejemplo n.º 1
0
/*
 * 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);
}
Ejemplo n.º 2
0
/**
 * \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);
}