/* * This function will send an ICMP echo request to the specified destionation. */ static int IcmpSendPing(uint32_t dest, uint16_t id, uint16_t seq, int len) { NETBUF *nb; int i; uint8_t *dp; uint32_t spec; /* Create a new NETBUF. */ nb = NutNetBufAlloc(NULL, NBAF_APPLICATION, len); if (nb) { /* Fill the data area with sample characters. */ dp = (uint8_t *) nb->nb_ap.vp; for (i = 0; i < len; i++) { *dp++ = 'a' + (i & 15); } /* Set up the echo request ID and sequence number. */ spec = id; spec <<= 16; spec |= seq; /* Send out the packet. The name of this function is misleading. */ if (NutIcmpReply(ICMP_ECHO, 0, htonl(spec), dest, nb) == 0) { /* Funny Nut/Net expects us to release the packet only if it has been successfully processed. */ NutNetBufFree(nb); return 0; } } /* Return an error. */ return -1; }
/*! * \brief Send an ICMP message as a response to a given destination. * * \param type Type of the ICMP message. See NutIcmpOutput() for * a list of valid types. * \param code Type subcode. * \param spec Type specific data item. * \param nb Network buffer structure containing the previously recevied * network packet. According to RFC792 the complete ip header * and the first 8 bytes of the transport netbuf is used as the * application data for the response. If this function returns * with an error, the buffer is freed. The destination addess is * taken from the ip header. * * \return 0 on success, -1 otherwise. */ int NutIcmpResponse(uint8_t type, uint8_t code, uint32_t spec, NETBUF * nb) { IPHDR *ip; uint32_t dest; ip = nb->nb_nw.vp; dest = ip->ip_src; if ((nb = NutNetBufAlloc(nb, NBAF_APPLICATION, sizeof(IPHDR) + 8)) == 0) return -1; memcpy(nb->nb_ap.vp, nb->nb_nw.vp, sizeof(IPHDR)); memcpy((char *)nb->nb_ap.vp + sizeof(IPHDR), nb->nb_tp.vp, 8); return NutIcmpReply(type, code, spec, dest, nb); }