コード例 #1
0
ファイル: ping.c プロジェクト: OoOverflow/tapip
static void send_packet(void)
{
	if (!buf)
		buf = xmalloc(size + ICMP_HRD_SZ);
	struct icmp *icmphdr = (struct icmp *)buf;
	static int first = 1;
	if (first) {
		printf("PING "IPFMT" %d(%d) bytes of data\n",
			ipfmt(ipaddr),
			size,
			size + ICMP_HRD_SZ + IP_HRD_SZ);
		first = 0;
	}

	/* fill icmp data */
	memset(icmphdr->icmp_data, 'x', size);
	icmphdr->icmp_type = ICMP_T_ECHOREQ;
	icmphdr->icmp_code = 0;
	icmphdr->icmp_id = _htons(id);
	icmphdr->icmp_seq = _htons(seq);
	icmphdr->icmp_cksum = 0;
	icmphdr->icmp_cksum = icmp_chksum((unsigned short *)icmphdr,
			ICMP_HRD_SZ + size);
	seq++;
	/* socket apis */
	_send(sock, buf, ICMP_HRD_SZ + size, &skaddr);
	psend++;
}
コード例 #2
0
ファイル: icmp.c プロジェクト: 0xcc/tapip
void icmp_in(struct pkbuf *pkb)
{
	struct ip *iphdr = pkb2ip(pkb);
	struct icmp *icmphdr = ip2icmp(iphdr);
	int icmplen, type;
	/* sanity check */
	icmplen = ipdlen(iphdr);
	icmpdbg("%d bytes", icmplen);
	if (icmplen < ICMP_HRD_SZ) {
		icmpdbg("icmp header is too small");
		goto drop_pkb;
	}

	if (icmp_chksum((unsigned short *)icmphdr, icmplen) != 0) {
		icmpdbg("icmp checksum is error");
		goto drop_pkb;
	}

	type = icmphdr->icmp_type;
	if (type > ICMP_T_MAXNUM) {
		icmpdbg("unknown icmp type %d code %d",
					type, icmphdr->icmp_code);
		goto drop_pkb;
	}
	/* handle icmp type */
	icmp_table[type].handler(&icmp_table[type], pkb);
	return;
drop_pkb:
	free_pkb(pkb);
}
コード例 #3
0
ファイル: icmp_send.c プロジェクト: bherrera/NuttX
void icmp_send(FAR struct net_driver_s *dev, FAR in_addr_t *destaddr)
{
  FAR struct icmp_iphdr_s *picmp = ICMPBUF;

  if (dev->d_sndlen > 0)
    {
      IFF_SET_IPv4(dev->d_flags);

      /* The total length to send is the size of the application data plus
       * the IP and ICMP headers (and, eventually, the Ethernet header)
       */

      dev->d_len = dev->d_sndlen + IPICMP_HDRLEN;

      /* The total size of the data (for ICMP checksum calculation) includes
       * the size of the ICMP header
       */

      dev->d_sndlen += ICMP_HDRLEN;

      /* Initialize the IP header. */

      picmp->vhl         = 0x45;
      picmp->tos         = 0;
      picmp->len[0]      = (dev->d_len >> 8);
      picmp->len[1]      = (dev->d_len & 0xff);
      ++g_ipid;
      picmp->ipid[0]     = g_ipid >> 8;
      picmp->ipid[1]     = g_ipid & 0xff;
      picmp->ipoffset[0] = IP_FLAG_DONTFRAG >> 8;
      picmp->ipoffset[1] = IP_FLAG_DONTFRAG & 0xff;
      picmp->ttl         = IP_TTL;
      picmp->proto       = IP_PROTO_ICMP;

      net_ipv4addr_hdrcopy(picmp->srcipaddr, &dev->d_ipaddr);
      net_ipv4addr_hdrcopy(picmp->destipaddr, destaddr);

      /* Calculate IP checksum. */

      picmp->ipchksum    = 0;
      picmp->ipchksum    = ~(ipv4_chksum(dev));

      /* Calculate the ICMP checksum. */

      picmp->icmpchksum  = 0;
      picmp->icmpchksum  = ~(icmp_chksum(dev, dev->d_sndlen));
      if (picmp->icmpchksum == 0)
        {
          picmp->icmpchksum = 0xffff;
        }

      nllvdbg("Outgoing ICMP packet length: %d (%d)\n",
              dev->d_len, (picmp->len[0] << 8) | picmp->len[1]);

#ifdef CONFIG_NET_STATISTICS
      g_netstats.icmp.sent++;
      g_netstats.ipv4.sent++;
#endif
    }
コード例 #4
0
ファイル: icmp.c プロジェクト: 0xcc/tapip
/* NOTE: icmp dont drop @ipkb */
void icmp_send(unsigned char type, unsigned char code,
		unsigned int data, struct pkbuf *pkb_in)
{
	struct pkbuf *pkb;
	struct ip *iphdr = pkb2ip(pkb_in);
	struct icmp *icmphdr;
	int paylen = _ntohs(iphdr->ip_len);	/* icmp payload length */
	if (paylen < iphlen(iphdr) + 8)
		return;
	/*
	 * RFC 1812 Section 4.3.2.7 for sanity check
	 * An ICMP error message MUST NOT be sent as the result of receiving:
	 * 1. A packet sent as a Link Layer broadcast or multicast
	 * 2. A packet destined to an IP broadcast or IP multicast address
	 *[3] A packet whose source address has a network prefix of zero or is an
	 *      invalid source address (as defined in Section [5.3.7])
	 * 4. Any fragment of a datagram other then the first fragment (i.e., a
	 *      packet for which the fragment offset in the IP header is nonzero).
	 * 5. An ICMP error message
	 */
	if (pkb_in->pk_type != PKT_LOCALHOST)
		return;
	if (MULTICAST(iphdr->ip_dst) || BROADCAST(iphdr->ip_dst))
		return;
	if (iphdr->ip_fragoff & _htons(IP_FRAG_OFF))
		return;

	if (icmp_type_error(type) && iphdr->ip_pro == IP_P_ICMP) {
		icmphdr = ip2icmp(iphdr);
		if (icmphdr->icmp_type > ICMP_T_MAXNUM || icmp_error(icmphdr))
			return;
	}
	/* build icmp packet and send */
	/* ip packet size must be smaller than 576 bytes */
	if (IP_HRD_SZ + ICMP_HRD_SZ + paylen > 576)
		paylen = 576 - IP_HRD_SZ - ICMP_HRD_SZ;
	pkb = alloc_pkb(ETH_HRD_SZ + IP_HRD_SZ + ICMP_HRD_SZ + paylen);
	icmphdr = (struct icmp *)(pkb2ip(pkb)->ip_data);
	icmphdr->icmp_type = type;
	icmphdr->icmp_code = code;
	icmphdr->icmp_cksum = 0;
	icmphdr->icmp_undata = data;
	memcpy(icmphdr->icmp_data, (unsigned char *)iphdr, paylen);
	icmphdr->icmp_cksum =
		icmp_chksum((unsigned short *)icmphdr, ICMP_HRD_SZ + paylen);
	icmpdbg("to "IPFMT"(payload %d) [type %d code %d]\n",
		ipfmt(iphdr->ip_src), paylen, type, code);
	ip_send_info(pkb, 0, IP_HRD_SZ + ICMP_HRD_SZ + paylen,
						0, IP_P_ICMP, iphdr->ip_src);
}
コード例 #5
0
ファイル: icmp_ping.c プロジェクト: acassis/ros2_nuttx
static void icmp_echo_request(FAR struct net_driver_s *dev,
                              FAR in_addr_t *destaddr)
{
  FAR struct icmp_iphdr_s *picmp = ICMPBUF;
  FAR uint8_t *ptr;
  size_t sendlen;
  size_t icmplen;
  size_t pktlen;
  int i;

  /* The total length to send is the size of the application data plus the
   * IPv4 and ICMP headers (and, eventually, the Ethernet header)
   */

  pktlen = IPv4_PAYLOAD_SIZE + IPICMP_HDRLEN;

  /* The total size of the data (for ICMP checksum calculation) includes the
   * size of the ICMP header
   */

  icmplen = IPv4_PAYLOAD_SIZE + ICMP_HDRLEN;

  /* Initialize the IP header. */

  picmp->vhl         = 0x45;
  picmp->tos         = 0;
  picmp->len[0]      = (pktlen >> 8);
  picmp->len[1]      = (pktlen & 0xff);
  ++g_ipid;
  picmp->ipid[0]     = g_ipid >> 8;
  picmp->ipid[1]     = g_ipid & 0xff;
  picmp->ipoffset[0] = IP_FLAG_DONTFRAG >> 8;
  picmp->ipoffset[1] = IP_FLAG_DONTFRAG & 0xff;
  picmp->ttl         = IP_TTL;
  picmp->proto       = IP_PROTO_ICMP;

  net_ipv4addr_hdrcopy(picmp->srcipaddr, &dev->d_ipaddr);
  net_ipv4addr_hdrcopy(picmp->destipaddr, destaddr);

  /* Format the ICMP ECHO request packet */

  picmp->type  = ICMP_ECHO_REQUEST;
  picmp->icode = 0;
  picmp->id    = htons(pstate->png_id);
  picmp->seqno = htons(pstate->png_seqno);

  /* Insert some recognizable data into the packet */

  for (i = 0, ptr = ICMPDAT; i < ICMP_DATALEN; i++)
    {
      *ptr++ = i;
    }

  /* Calculate IP checksum. */

  picmp->ipchksum    = 0;
  picmp->ipchksum    = ~(ipv4_chksum(dev));

  /* Calculate the ICMP checksum. */

  picmp->icmpchksum  = 0;
  picmp->icmpchksum  = ~(icmp_chksum(dev, icmplen));
  if (picmp->icmpchksum == 0)
    {
      picmp->icmpchksum = 0xffff;
    }
}