Beispiel #1
0
static int icmp_proc(struct netbuf *buf)
{
  int ret = 0;

  switch (buf->cmd) {
  case ICMP_CMD_RECV:
    ret = icmp_recv(buf);
    break;

  case ICMP_CMD_SEND:
    ret = icmp_send(buf);
    break;

  default:
    break;
  }

  return ret;
}
Beispiel #2
0
/*------------------------------------------------------------------------
 * xsh_ping - shell command to ping a remote host
 *------------------------------------------------------------------------
 */
shellcmd xsh_ping(int nargs, char *args[])
{
	uint32	ipaddr;			/* IP address in binary		*/
	int32	retval;			/* return value			*/
	int32	icmpid;			/* ICMP ID to use		*/
	static	int32	seq = 0;	/* sequence number		*/
	char	buf[56];		/* buffer of chars		*/
	int32	i;			/* index into buffer		*/
	int32	nextval;		/* next value to use		*/

	/* For argument '--help', emit help about the 'ping' command	*/

	if (nargs == 2 && strncmp(args[1], "--help", 7) == 0) {
		printf("Use: %s  address\n\n", args[0]);
		printf("Description:\n");
		printf("\tUse ICMP Echo to ping a remote host\n");
		printf("Options:\n");
		printf("\t--help\t display this help and exit\n");
		printf("\taddress\t an IP address in dotted decimal\n");
		return 0;
	}

	/* Check for valid number of arguments */

	if (nargs != 2) {
		fprintf(stderr, "%s: invalid arguments\n", args[0]);
		fprintf(stderr, "Try '%s --help' for more information\n",
				args[0]);
		return 1;
	}

	/* convert argument to binary */

	retval = dot2ip(args[1], &ipaddr);
	if ((int32)retval == SYSERR) {
		fprintf(stderr, "%s: invalid IP address\n", args[0]);
		return 1;
	}

	/* Register to receive an ICMP Echo Reply */

	icmpid = icmp_register(ipaddr);
	if (icmpid == SYSERR) {
		fprintf(stderr, "%s: ICMP registration fails\n", args[0]);
		return 1;
	}

	/* Fill the buffer with values - start with low-order byte of	*/
	/*	the sequence number and increment			*/

	nextval = seq;
	for (i = 0; i<sizeof(buf); i++) {
		buf[i] = 0xff & nextval++;
	}

	/* Send an ICMP Echo Request */

	retval = icmp_send(ipaddr, ICMP_ECHOREQST, icmpid, seq++, buf,
				sizeof(buf));
	if (retval == SYSERR) {
		fprintf(stderr, "%s: cannot send a ping\n", args[0]);
		icmp_release(icmpid);
		return 1;
	}

	/* Read a reply */

	retval = icmp_recv(icmpid, buf, sizeof(buf), 3000);
	icmp_release(icmpid);
	if (retval == TIMEOUT) {
		fprintf(stderr, "%s: no response from %s\n\n", args[0],
					args[1]);
		return 1;
	}
	fprintf(stderr, "host %s is alive\n", args[1]);
	return 0;
}
Beispiel #3
0
static void *recv_loop(void *data)
{
    session_t *session = net_init(ifname, src_ip_addr, 0, 0, 0, ICMP, -1);
    icmp_packet_t packet;
    ndp_neighbor_discover_t n_discvr;

    while(is_initialized)
    {
        size_t recv = icmp_recv(session, &packet);
        if(!recv)
            continue;

        switch(packet.type)
        {
            case ICMP_TYPE_NEIGHBOR_SOLICITATION:
                memcpy(n_discvr.buffer, packet.body, recv);

                if(memcmp(n_discvr.target_addr, session->src_ip,
                          IP_ADDR_LEN) != 0)
                    continue;

                ndp_option_t opt;
                memcpy(opt.buffer, n_discvr.options, recv + NDP_ND_HEADER_LEN);

                if(opt.type != NDP_SOURCE_LINK_ADDR_OPT || opt.len != 1)
                {
                    fprintf(stderr, "Error: Invalid NDP option type: %d. "
                                    "Expected: %d (NDP_SOURCE_LINK_ADDR_OPT)"
                                    "\n.", opt.type, NDP_SOURCE_LINK_ADDR_OPT);
                    continue;
                }

                ndp_table_insert(session->last_sender_ip, opt.body);

                ndp_neighbor_discover_t ndp_resp;
                ndp_option_t opt_resp;

                memcpy(ndp_resp.target_addr, n_discvr.target_addr, IP_ADDR_LEN);
                // sol & override flag
                ndp_resp.reserved = netb_l( 1 << 30 | 1 << 29 );

                opt_resp.type = NDP_TARGET_LINK_ADDR_OPT;
                opt_resp.len = 1;
                memcpy(opt_resp.body, session->src_addr, ETH_ADDR_LEN);

                size_t opts_len = NDP_OPT_HEADER_LEN + ETH_ADDR_LEN;
                memcpy(ndp_resp.options, opt_resp.buffer, opts_len);

                size_t resp = icmp_send(session, session->last_sender_ip,
                                        ICMP_TYPE_NEIGHBOR_ADVERTISEMENT, 0,
                                        ndp_resp.buffer,
                                        NDP_ND_HEADER_LEN + opts_len);

                if(resp <= 0)
                {
                    fprintf(stderr, "Error: Cannot respond with "
                                    "ICMP_TYPE_NEIGHBOR_ADVERTISEMENT!\n.");
                    continue;
                }

                break;

            case ICMP_TYPE_NEIGHBOR_ADVERTISEMENT:
                memcpy(n_discvr.buffer, packet.body, recv);
                uint8_t zeros[IP_ADDR_LEN] = { 0x0 };

                if(memcmp(zeros, n_discvr.target_addr, IP_ADDR_LEN) == 0)
                    continue; // not sure why it's even possible...

                if(recv <= offsetof(ndp_neighbor_discover_t, options))
                    continue; // If there's no option, ignore

                memcpy(opt.buffer, n_discvr.options, recv + NDP_ND_HEADER_LEN);

                if(opt.type != NDP_TARGET_LINK_ADDR_OPT || opt.len != 1)
                {
                    fprintf(stderr, "Error: Invalid NDP option type: %d. "
                                    "Expected: %d (NDP_TARGET_LINK_ADDR_OPT)"
                                    "\n.", opt.type, NDP_TARGET_LINK_ADDR_OPT);
                    continue;
                }

                ndp_table_insert(n_discvr.target_addr, opt.body);

                break;

            default:
                break; // unsupported ICMP type
        }
    }

    net_free(session);
    return 0;
}