Ejemplo n.º 1
0
static int icmp_echo_reply (const in_Header *ip, const union ICMP_PKT *req,
                            unsigned len)
{
  struct _pkt     *pkt;
  union  ICMP_PKT *icmp;

  if (!icmp_check(ip,ICMP_ECHO))
     return (0);

  icmp_print (2, _LANG("PING reply sent"), 0);

#if defined(USE_FRAGMENTS)
  if (len > _mtu - sizeof(*ip))
  {
    icmp = (union ICMP_PKT*) req;        /* reuse input for output */
    icmp->echo.type     = ICMP_ECHOREPLY;
    icmp->echo.checksum = 0;
    icmp->echo.checksum = ~CHECKSUM (icmp, len);
    return _IP4_SEND_FRAGMENTS (NULL, ICMP_PROTO, ip->source, icmp, len);
  }
#endif

  pkt  = (struct _pkt*) _eth_formatpacket (MAC_SRC(ip), IP4_TYPE);
  icmp = &pkt->icmp;

  len = min (len, _mtu - sizeof(*ip));
  memcpy (icmp, req, len);
  icmp->echo.type = ICMP_ECHOREPLY;
  icmp->echo.code = req->echo.code; /* Win uses 0, Unix !0 */

  /* Use supplied ip values in case we ever multi-home.
   * Note that ip values are still in network order.
   */
  return icmp_send (pkt, ip->destination, ip->source, len);
}
Ejemplo n.º 2
0
/*
 * igmp_report - send a IGMP Report packet
 *
 * int igmp_report (DWORD ip)
 * Where:
 *      ip is the IP address to report.
 *
 * Returns:
 *      0   if unable to send report
 *      1   report was sent successfully
 */
int igmp_report (DWORD ip)
{
    struct IGMP_PKT *pkt;
    IGMP_packet     *igmp;
    eth_address      ethaddr;

    /* get the ethernet addr of the destination
     */
    multi_to_eth ((DWORD)ALL_SYSTEMS, (BYTE*)&ethaddr);

    /* format the packet with the request's hardware address
     */
    pkt  = (struct IGMP_PKT*) _eth_formatpacket (ethaddr, IP_TYPE);
    igmp = &pkt->igmp;
    ip = intel (ip);

    /* fill in the igmp packet
     */
    igmp->type     = IGMP_REPORT;
    igmp->version  = IGMP_VERSION;
    igmp->mbz      = 0;
    igmp->address  = ip;
    igmp->checksum = 0;
    igmp->checksum = ~checksum (igmp,sizeof(*igmp));

    return IP_OUTPUT (&pkt->in, 0, ip, IGMP_PROTO,
                      0, 0, 0, (int)sizeof(*igmp), NULL);
}
Ejemplo n.º 3
0
/**
 * Send an "ICMP Time Exceeded" (reassebly timeout) back to 'ip->source'
 */
int icmp_send_timexceed (const in_Header *ip, const void *mac_dest)
{
  struct _pkt    *pkt;
  union ICMP_PKT *icmp;

  if (!icmp_check(ip,ICMP_TIMXCEED))
     return (0);

  pkt  = (struct _pkt*) _eth_formatpacket (mac_dest, IP4_TYPE);
  icmp = &pkt->icmp;

  icmp_print (1, icmp_exceed_str[1], ip->destination);

  memset (&icmp->unused, 0, sizeof(icmp->unused));

  icmp->unused.type = ICMP_TIMXCEED;
  icmp->unused.code = 1;

  icmp->unused.ip.hdrlen         = sizeof(in_Header) / 4;
  icmp->unused.ip.ver            = 4;
  icmp->unused.ip.ttl            = _default_ttl;
  icmp->unused.ip.identification = ip->identification;
  icmp->unused.ip.length         = intel16 (sizeof(in_Header));
  icmp->unused.ip.proto          = ip->proto;
  icmp->unused.ip.checksum       = ~CHECKSUM (&icmp->unused.ip, sizeof(in_Header));

  return icmp_send (pkt, ip->destination, ip->source, sizeof(icmp->unused));
}
Ejemplo n.º 4
0
/**
 * Send an ICMP destination/protocol unreachable back to 'ip->source'.
 * Limit the rate of these to 20 per second. Ref. RFC-1812.
 */
int icmp_send_unreach (const in_Header *ip, int code)
{
  static DWORD next_time = 0UL;
  struct _pkt    *pkt;
  union ICMP_PKT *unr;
  unsigned        len;

  if (!icmp_check(ip,ICMP_UNREACH))
     return (0);

  if (next_time && !chk_timeout(next_time))
     return (0);

  next_time = set_timeout (50);

  pkt = (struct _pkt*) _eth_formatpacket (MAC_SRC(ip), IP4_TYPE);
  unr = &pkt->icmp;
  len = intel16 (ip->length) - in_GetHdrLen (ip);
  len = min (len, sizeof(*ip)+sizeof(unr->unused.spares));

  icmp_print (1, _LANG(icmp_unreach_str[code]), ip->destination);
  memcpy (&unr->unused.ip, ip, len);
  unr->unused.type = ICMP_UNREACH;
  unr->unused.code = (BYTE) code;

  return icmp_send (pkt, ip->destination, ip->source, sizeof(unr->unused));
}
Ejemplo n.º 5
0
void *icmp_Format (DWORD host)
{
  mac_address dest;

  /* We use ARP rather than supplied hardware address.
   * After first ping this will still be in cache.
   */
  if (!_arp_resolve(host,&dest,0))  /* unable to find address */
     return (NULL);     

  return _eth_formatpacket (&dest, IP_TYPE);
}
Ejemplo n.º 6
0
void icmp_mask_req (void)
{
  mac_address    *dst = (_pktserial ? NULL : &_eth_brdcast);
  struct _pkt    *pkt = (struct _pkt*) _eth_formatpacket (dst, IP_TYPE);
  union icmp_pkt *req = &pkt->icmp;

  addr_mask_id = (WORD) set_timeout (0);   /* get a random ID */
  req->mask.type       = ICMP_MASKREQ;
  req->mask.code       = 0;
  req->mask.identifier = addr_mask_id;
  req->mask.sequence   = addr_mask_seq++;
  req->mask.mask       = 0;
  icmp_send (pkt, 0, (DWORD)INADDR_BROADCAST, sizeof(req->mask));
}
Ejemplo n.º 7
0
/**
 * Build and send a PPPoE Session packet (IPCP or LCP packet).
 */
int pppoe_send_sess (const void *sock, const BYTE *buf, WORD len)
{
  pppoe_Packet *pkt;

  pkt = (pppoe_Packet*) _eth_formatpacket (&ac_macAddr[0], PPPOE_SESS_TYPE);

  pkt->ver     = 1;
  pkt->type    = 1;
  pkt->code    = PPPOE_CODE_SESS;
  pkt->session = session;
  pkt->length  = intel16 (len);

  memcpy (pkt->data, buf, len);
  return _eth_send (len + PPPOE_HDR_SIZE, sock, __FILE__, __LINE__);
}
Ejemplo n.º 8
0
static int _rarp_request (void)
{
  rarp_Header *rarp = (rarp_Header*) _eth_formatpacket (&_eth_brdcast[0],
                                                        RARP_TYPE);
  rarp->hwType       = intel16 (_eth_get_hwtype(NULL,NULL));
  rarp->protType     = IP4_TYPE;
  rarp->hwAddrLen    = sizeof (mac_address);
  rarp->protoAddrLen = sizeof (my_ip_addr);
  rarp->opcode       = RARP_REQUEST;
  rarp->srcIPAddr    = 0;
  rarp->dstIPAddr    = 0;
  memcpy (rarp->srcEthAddr, _eth_addr, sizeof(mac_address));
  memcpy (rarp->dstEthAddr, _eth_addr, sizeof(mac_address));

  return _eth_send (sizeof(*rarp), NULL, __FILE__, __LINE__);
}
Ejemplo n.º 9
0
/**
 * Build and send a PADx (PPPoE Active Discovery) packet as
 * link-layer broadcast or unicast.
 */
static int pppoe_send_disc (int code)
{
  pppoe_Packet *pkt;
  WORD          len;

  pkt = (pppoe_Packet*) _eth_formatpacket (&ac_macAddr[0], PPPOE_DISC_TYPE);
  len = build_pad (pkt, code);

  pkt->ver     = 1;
  pkt->type    = 1;
  pkt->code    = code;
  pkt->session = session;
  pkt->length  = intel16 (len);

#if defined(USE_DEBUG)
  if (cfg.trace)
     (*_printf) ("PPPOE: sending %s\n", pppoe_get_code(code));
#endif

  return _eth_send (len + PPPOE_HDR_SIZE, NULL, __FILE__, __LINE__);
}
Ejemplo n.º 10
0
/*
 *  Send an "ICMP Time Exceeded" (reassebly timeout) back to 'ip->source'
 */
void icmp_timexceed (const in_Header *ip, const void *mac_dest)
{
  struct _pkt    *pkt;
  union icmp_pkt *tim;
  int             len;

  if (!icmp_chk_src(ip,ICMP_TIMXCEED))
     return;

  pkt = (struct _pkt*) _eth_formatpacket (mac_dest, IP_TYPE);
  tim = &pkt->icmp;
  len = intel16 (ip->length) - in_GetHdrLen (ip);
  len = min (len, sizeof(*ip) + sizeof(tim->unused.spares));

  icmp_print (1, icmp_exceed_str[1], ip->destination);
  memcpy (&tim->unused.ip, ip, len);
  tim->unused.type = ICMP_TIMXCEED;
  tim->unused.code = 1;

  icmp_send (pkt, ip->destination, ip->source, sizeof(tim->unused));
}
Ejemplo n.º 11
0
/*
 *  Send an ICMP destination/protocol unreachable back to ip->source
 */
void icmp_unreach (const in_Header *ip, int code)
{
  struct _pkt    *pkt;
  union icmp_pkt *unr;
  int             len;

  if (!icmp_chk_src(ip,ICMP_UNREACH))
     return;

  pkt = (struct _pkt*) _eth_formatpacket (MAC_SRC(ip), IP_TYPE);
  unr = &pkt->icmp;
  len = intel16 (ip->length) - in_GetHdrLen (ip);
  len = min (len, sizeof(*ip)+sizeof(unr->unused.spares));

  icmp_print (1, icmp_unreach_str[code], ip->destination);
  memcpy (&unr->unused.ip, ip, len);
  unr->unused.type = ICMP_UNREACH;
  unr->unused.code = code;

  icmp_send (pkt, ip->destination, ip->source, sizeof(unr->unused));
}
Ejemplo n.º 12
0
static int ping_gateway (DWORD host, void *eth)
{
  struct ping_pkt  *pkt;
  struct icmp_echo *icmp;
  struct in_Header *ip;
  int    len;

  pkt  = (struct ping_pkt*) _eth_formatpacket (eth, IP4_TYPE);
  ip   = &pkt->in;
  icmp = &pkt->icmp;
  len  = sizeof (*icmp);
  icmp_id = (WORD) set_timeout (0);  /* "random" id */

  icmp->type       = ICMP_ECHO;
  icmp->code       = 0;
  icmp->index      = 1;
  icmp->identifier = icmp_id;
  icmp->sequence   = icmp_seq++;
  icmp->checksum   = 0;
  icmp->checksum   = ~CHECKSUM (icmp, len);

  return IP4_OUTPUT (ip, 0, intel(host), ICMP_PROTO, 1,
                     (BYTE)_default_tos, 0, len, NULL);
}
Ejemplo n.º 13
0
/*
 *  Raw IP transmitter
 */
static int ip_transmit (Socket *socket, const void *tx, int len)
{
  eth_address eth;
  u_long      dest;
  unsigned    tx_len, tx_room;
  sock_type  *sk = (sock_type*)socket->udp_sock;

  struct ip   *ip  = (struct ip*) tx;
  const  BYTE *buf = (const BYTE*) tx;
  WORD   flags     = 0;
  DWORD  offset;
  UINT   h_len, o_len;

  tcp_tick (NULL);        /* process other TCBs too */
  tcp_Retransmitter (1);

  /* This should never happen
   */
  if (ip && (socket->so_state & SS_NBIO) &&
      sock_tbleft(sk) < (len + socket->send_lowat))
  {
    SOCK_DEBUGF ((socket, ", EWOULDBLOCK"));
    SOCK_ERR (EWOULDBLOCK);
    return (-1);
  }

  if (ip)
  {
    offset = ntohs (ip->ip_off);
    flags  = offset & ~IP_OFFMASK;
    offset = (offset & IP_OFFMASK) << 3; /* 0 <= ip_ofs <= 65536-8 */
  }

  SOCK_DEBUGF ((socket, ", %s / Raw",
                inet_ntoa(socket->remote_addr->sin_addr)));

  if (ip && (socket->inp_flags & INP_HDRINCL))
  {
    dest    = ip->ip_dst.s_addr;
    tx_len  = len;
    tx_room = mtu;
  }
  else
  {
    dest    = socket->remote_addr->sin_addr.s_addr;
    tx_len  = len + sizeof (*ip);
    tx_room = mtu + sizeof (*ip);
  }

  if (!dest || !_arp_resolve(ntohl(dest),&eth,0))
  {
    SOCK_DEBUGF ((socket, ", no route"));
    SOCK_ERR (EHOSTUNREACH);
    STAT (ipstats.ips_noroute++);
    return (-1);
  }

#if defined(USE_FRAGMENTS)
  if (!(socket->inp_flags & INP_HDRINCL) &&
      tx_len + socket->ip_opt_len > tx_room)
  {
    sk = (sock_type*)socket->raw_sock;

    if (flags & IP_DF)
    {
      SOCK_DEBUGF ((socket, ", EMSGSIZE"));
      SOCK_ERR (EMSGSIZE);
      STAT (ipstats.ips_toolong++);
      return (-1);
    }
    return SEND_IP_FRAGMENTS (sk, sk->raw.ip_type, dest, buf, len);
  }
#else
  if (!(socket->inp_flags & INP_HDRINCL) &&
      tx_len + socket->ip_opt_len > tx_room)
  {
    SOCK_DEBUGF ((socket, ", EMSGSIZE"));
    SOCK_ERR (EMSGSIZE);
    STAT (ipstats.ips_toolong++);
    return (-1);
  }
#endif

  ip = (struct ip*) _eth_formatpacket (&eth, IP_TYPE);

  if (socket->inp_flags & INP_HDRINCL)
  {
    memcpy (ip, buf, len);
    if (ip->ip_src.s_addr == 0)
    {
      ip->ip_src.s_addr = gethostid();
      ip->ip_sum = 0;
      ip->ip_sum = ~checksum ((void*)ip, ip->ip_hl << 2);
    }
    if (ip->ip_sum == 0)
        ip->ip_sum = ~checksum ((void*)ip, ip->ip_hl << 2);
  }
  else
  {
    if (socket->ip_opt && socket->ip_opt_len > 0)
    {
      BYTE *data;

      o_len = min (socket->ip_opt_len, sizeof(socket->ip_opt->ip_opts));
      h_len = sizeof(*ip) + o_len;
      data  = (BYTE*)ip + h_len;
      memcpy (ip+1, &socket->ip_opt->ip_opts, o_len);
      memcpy (data, buf, len);
      tx_len += o_len;
      if (socket->ip_opt->ip_dst.s_addr)   /* using source routing */
         dest = socket->ip_opt->ip_dst.s_addr;
    }
    else
    {
      if (buf)
         memcpy (ip+1, buf, len);
      h_len = sizeof (*ip);
    }

    ip->ip_v   = IPVERSION;
    ip->ip_hl  = h_len >> 2;
    ip->ip_tos = socket->ip_tos;
    ip->ip_len = htons (tx_len);
    ip->ip_id  = _get_ip_id();
    ip->ip_off = 0;
    ip->ip_ttl = socket->ip_ttl;
    ip->ip_p   = socket->so_proto;

    ip->ip_src.s_addr = gethostid();
    ip->ip_dst.s_addr = dest;

    ip->ip_sum = 0;
    ip->ip_sum = ~checksum (ip, h_len);
  }

  DEBUG_TX (NULL, ip);

  if (!_eth_send(tx_len))
  {
    SOCK_DEBUGF ((socket, ", ENETDOWN"));
    SOCK_ERR (ENETDOWN);
    return (-1);
  }
  if (buf)
     buf += tx_len;

  return (len);
}
Ejemplo n.º 14
0
/*
 *  Handler for incoming ICMP packets
 */
void icmp_handler (const in_Header *ip, BOOL broadcast)
{
  union icmp_pkt *icmp;
  in_Header      *orig_ip;
  int             len, type, code;
  BOOL            for_me, i_orig;  /* is it for me, did I originate it */
  const char     *msg;

  DEBUG_RX (NULL, ip);

  if (block_icmp)   /* application is handling ICMP; not needed */
     return;

  len    = in_GetHdrLen (ip);
  icmp   = (union icmp_pkt*) ((BYTE*)ip + len);
  len    = intel16 (ip->length) - len;
  for_me = (DWORD) (intel(ip->destination) - my_ip_addr) <= multihomes;

  if (!for_me || broadcast)  /* drop broadcast pings.. */
     return;

  if (len < sizeof(icmp->info))
  {
    STAT (icmpstats.icps_tooshort++);
    return;
  }

  if (checksum(icmp,len) != 0xFFFF)
  {
    STAT (icmpstats.icps_checksum++);
    icmp_print (1, _LANG("bad checksum"), ip->source);
    return;
  }

  type    = icmp->unused.type;
  code    = icmp->unused.code;
  orig_ip = &icmp->ip.ip;
  i_orig  = is_local_addr (intel(orig_ip->source));

  if (type == ICMP_MASKREPLY)
  {
    if (!_domask_req)
       return;
    i_orig = TRUE;
  }

  /* !! this needs work
   */
  if (!i_orig &&
      (type != ICMP_ECHOREPLY && type != ICMP_ECHO &&
       type != ICMP_IREQREPLY && type != ICMP_TSTAMP))
  {
    icmp_bogus (ip, type, NULL);
    return;
  }

  switch (type)
  {
    case ICMP_ECHOREPLY:  /* check if we were waiting for it */
         STAT (icmpstats.icps_inhist[ICMP_ECHOREPLY]++);
         ping_hcache = intel (ip->source);
         ping_tcache = set_timeout (1000) - *(DWORD*)&icmp->echo.identifier;
         if (ping_tcache > 0x7FFFFFFFL)
             ping_tcache += 0x1800B0L;
         ping_number = *(DWORD*)(((BYTE*)&icmp->echo.identifier) + 4);
         return;

    case ICMP_UNREACH:
         STAT (icmpstats.icps_inhist[ICMP_UNREACH]++);
         if (code < DIM(icmp_unreach_str))
         {
           icmp_print (1, msg = icmp_unreach_str[code], ip->source);
#if !defined(USE_UDP_ONLY)
           if (orig_ip->proto == TCP_PROTO)
              _tcp_cancel (orig_ip, type, msg, 0);
           else
#endif
           if (orig_ip->proto == UDP_PROTO)
              _udp_cancel (orig_ip, type, msg, 0);
         }
         else
           STAT (icmpstats.icps_badcode++);
         return;

    case ICMP_SOURCEQUENCH:
         STAT (icmpstats.icps_inhist[ICMP_SOURCEQUENCH]++);
#if !defined(USE_UDP_ONLY)
         if (orig_ip->proto == TCP_PROTO)
         {
           icmp_print (1, _LANG("Source Quench"), ip->source);
           _tcp_cancel (orig_ip, type, NULL, 0);
         }
#endif
         return;

    case ICMP_REDIRECT:
         STAT (icmpstats.icps_inhist[ICMP_REDIRECT]++);
         if (code < 4)
         {
           DWORD new_gw = intel (icmp->ip.ipaddr);

           /* Check if new gateway is on our subnet
            */
           if ((new_gw ^ my_ip_addr) & sin_mask)
           {
             char buf[100], adr[20];
             strcpy (buf, ", GW = ");
             strcat (buf, _inet_ntoa(adr,new_gw));
             icmp_bogus (ip, type, buf);
             return;
           }
           icmp_print (1, msg = icmp_redirect_str[code], ip->source);

           switch (orig_ip->proto)
           {
#if !defined(USE_UDP_ONLY)
             case TCP_PROTO:
                  if (do_redirect.tcp)  /* do it to some socket */
                     _tcp_cancel (orig_ip, type, msg, new_gw);
                  break;
#endif
             case UDP_PROTO:
                  if (do_redirect.udp)
                     _udp_cancel (orig_ip, type, msg, new_gw);
                  break;

             case ICMP_PROTO:
                  if (do_redirect.icmp)
                  {
                    _ip_recursion = 1;
                    _arp_register (new_gw, intel(orig_ip->destination), 0);
                    _ip_recursion = 0;
                  }
                  break;

             case IGMP_PROTO:
                  if (do_redirect.igmp)
                  {
                    _ip_recursion = 1;
                    _arp_register (new_gw, intel(orig_ip->destination), 0);
                    _ip_recursion = 0;
                  }
                  break;
           }
         }
         else
           STAT (icmpstats.icps_badcode++);
         return;

    case ICMP_ECHO:
         STAT (icmpstats.icps_inhist[ICMP_ECHO]++);
         icmp_print (2, _LANG("PING requested of us"), ip->source);
         {
           /* Extract eth-address and create Echo reply packet.
            */
           struct _pkt     *pkt;
           union  icmp_pkt *newicmp;

           if (!icmp_chk_src(ip,ICMP_ECHO))
              return;

           pkt     = (struct _pkt*) _eth_formatpacket (MAC_SRC(ip), IP_TYPE);
           newicmp = &pkt->icmp;

           /* Don't let a huge reassembled ICMP-packet kill us.
            */
           len = min (len, mtu - sizeof(*ip));
           memcpy (newicmp, icmp, len);
           newicmp->echo.type = ICMP_ECHOREPLY;
           newicmp->echo.code = code;

           /* Use supplied ip values in case we ever multi-home.
            * Note that ip values are still in network order.
            */
           icmp_send (pkt, ip->destination, ip->source, len);
           icmp_print (2, _LANG("PING reply sent"), 0);
         }
         return;

    case ICMP_TIMXCEED:
         if (code >= DIM(icmp_exceed_str))
         {
           STAT (icmpstats.icps_badcode++);
           return;
         }
         STAT (icmpstats.icps_inhist[ICMP_TIMXCEED]++);

         if (code != 1)
            switch (orig_ip->proto)
            {
#if !defined(USE_UDP_ONLY)
              case TCP_PROTO:
                   icmp_print (1, icmp_exceed_str[code], ip->source);
                   _tcp_cancel (orig_ip, ICMP_TIMXCEED, NULL, 0);
                   break;
#endif
              case UDP_PROTO:
                   icmp_print (1, icmp_exceed_str[code], ip->source);
                   _udp_cancel (orig_ip, ICMP_TIMXCEED, NULL, 0);
                   break;
            }
         return;

    case ICMP_PARAMPROB:
         STAT (icmpstats.icps_inhist[ICMP_PARAMPROB]++);
         switch (orig_ip->proto)
         {
#if !defined(USE_UDP_ONLY)
           case TCP_PROTO:
                icmp_print (0, _LANG(icmp_type_str[type]), ip->source);
                _tcp_cancel (orig_ip, type, NULL, 0);
                break;
#endif
           case UDP_PROTO:
                icmp_print (0, _LANG(icmp_type_str[type]), ip->source);
                _udp_cancel (orig_ip, type, NULL, 0);
                break;
         }
         return;

    case ICMP_ROUTERADVERT:  /* todo !! */
         STAT (icmpstats.icps_inhist[ICMP_ROUTERADVERT]++);
         icmp_print (1, _LANG(icmp_type_str[type]), ip->source);
         return;

    case ICMP_ROUTERSOLICIT: /* todo !! */
         STAT (icmpstats.icps_inhist[ICMP_ROUTERSOLICIT]++);
         icmp_print (1, _LANG(icmp_type_str[type]), ip->source);
         return;

    case ICMP_TSTAMP:
         STAT (icmpstats.icps_inhist[ICMP_TSTAMP]++);
         icmp_print (1, _LANG(icmp_type_str[type]), ip->source);
         /* todo!!, send reply? */
         return;

    case ICMP_TSTAMPREPLY:
         STAT (icmpstats.icps_inhist[ICMP_TSTAMPREPLY]++);
         icmp_print (1, _LANG(icmp_type_str[type]), ip->source);
         /* todo!!, should store */
         return;

    case ICMP_IREQ:
         STAT (icmpstats.icps_inhist[ICMP_IREQ]++);
         icmp_print (1, _LANG(icmp_type_str[type]), ip->source);
         /* todo!!, send reply */
         return;

    case ICMP_IREQREPLY:
         STAT (icmpstats.icps_inhist[ICMP_IREQREPLY]++);
         icmp_print (1, _LANG(icmp_type_str[type]), ip->source);
         /* todo!!, send reply upwards */
         return;

    case ICMP_MASKREQ:
         STAT (icmpstats.icps_inhist[ICMP_MASKREQ]++);
         break;

    case ICMP_MASKREPLY:
         STAT (icmpstats.icps_inhist[ICMP_MASKREPLY]++);
         icmp_print (0, _LANG(icmp_type_str[type]), ip->source);
         if ((icmp->mask.identifier == addr_mask_id)    &&
             (icmp->mask.sequence   == addr_mask_seq-1) &&
             sin_mask != intel(icmp->mask.mask))
            outsnl ("Conflicting net-mask from \"ICMP Addr Mask Reply\"\7");
         addr_mask_id = 0;
         return;
  }
}