Пример #1
0
static void
icmpSendEcho(struct in_addr to, int opcode, const char *payload, int len)
{
    static pingerEchoData pecho;
    if (payload && len == 0)
	len = strlen(payload);
    assert(len <= PINGER_PAYLOAD_SZ);
    pecho.to = to;
    pecho.opcode = (unsigned char) opcode;
    pecho.psize = len;
    xmemcpy(pecho.payload, payload, len);
    icmpSend(&pecho, sizeof(pingerEchoData) - PINGER_PAYLOAD_SZ + len);
}
Пример #2
0
/**
 * Send an ICMP Echo (Ping) Request.
 * @param dst destination address
 * @param id  ping stream identifier
 * @param seq sequence number
 * @return OK if packet was sent, otherwise SYSERR
 */
syscall icmpEchoRequest(struct netaddr *dst, ushort id, ushort seq)
{
    struct packet *pkt = NULL;
    struct icmpEcho *echo = NULL;
    int result = OK;
    irqmask im;

    ICMP_TRACE("echo request(%d, %d)", id, seq);
    pkt = netGetbuf();
    if (SYSERR == (int)pkt)
    {
        ICMP_TRACE("Failed to acquire packet buffer");
        return SYSERR;
    }

    pkt->len = sizeof(struct icmpEcho);
    pkt->curr -= pkt->len;

    echo = (struct icmpEcho *)pkt->curr;
    echo->id = hs2net(id);
    echo->seq = hs2net(seq);
    /* Our optional data payload includes room for the departure */
    /*  and arrival timestamps, in seconds, milliseconds, and    */
    /*  clock cycles.                                            */
    im = disable();
    echo->timecyc = hl2net(clkcount());
    echo->timetic = hl2net(clkticks);
    echo->timesec = hl2net(clktime);
    restore(im);
    echo->arrivcyc = 0;
    echo->arrivtic = 0;
    echo->arrivsec = 0;

    ICMP_TRACE("Sending Echo Request id = %d, seq = %d, time = %d.%d",
               net2hs(echo->id), net2hs(echo->seq),
               net2hl(echo->timesec), net2hl(echo->timetic));

    result = icmpSend(pkt, ICMP_ECHO, 0, sizeof(struct icmpEcho), dst);
    netFreebuf(pkt);
    return result;
}
Пример #3
0
/**
 * @ingroup icmp
 *
 * Compose ICMP Time Exceeded message.
 * @param unreached packet that could not be sent
 * @param code      ICMP destination unreachable code number
 * @return OK if packet was sent, otherwise SYSERR
 */
syscall icmpTimeExceeded(struct packet *unreached, int code)
{
    struct packet *pkt = NULL;
    struct ipv4Pkt *ip = NULL;
    struct netaddr dst;
    int result = OK;
    int ihl = 0;

    ICMP_TRACE("Time exceeded (%d)", code);
    pkt = netGetbuf();
    if (SYSERR == (int)pkt)
    {
        ICMP_TRACE("Failed to acquire packet buffer");
        return SYSERR;
    }

    ip = (struct ipv4Pkt *)unreached->nethdr;
    dst.type = NETADDR_IPv4;
    dst.len = IPv4_ADDR_LEN;
    /* Send error message back to original source.                */
    memcpy(dst.addr, ip->src, dst.len);
    ihl = (ip->ver_ihl & IPv4_IHL) * 4;

    /* Message will contain at least ICMP_DEF_DATALEN             */
    /*  of packet in question, as per RFC 792.                    */
    pkt->len = ihl + ICMP_DEF_DATALEN;
    pkt->curr -= pkt->len;

    memcpy(pkt->curr, ip, ihl + ICMP_DEF_DATALEN);
    /* First four octets of payload are unused.                   */
    pkt->curr -= 4;
    pkt->len += 4;
    *((ulong *)pkt->curr) = 0;

    result = icmpSend(pkt, ICMP_TIMEEXCD, code, pkt->len, &dst);

    netFreebuf(pkt);
    return result;
}