Пример #1
0
static int raw_sendmsg(struct sock *sk, struct msghdr *msg, int len, int noblock, 
	int flags)
{
	if(msg->msg_iovlen==1)
		return raw_sendto(sk,msg->msg_iov[0].iov_base,len, noblock, flags, msg->msg_name, msg->msg_namelen);
	else
	{
		/*
		 *	For awkward cases we linearise the buffer first. In theory this is only frames
		 *	whose iovec's don't split on 4 byte boundaries, and soon encrypted stuff (to keep
		 *	skip happy). We are a bit more general about it.
		 */
		 
		unsigned char *buf;
		int fs;
		int err;
		if(len>65515)
			return -EMSGSIZE;
		buf=kmalloc(len, GFP_KERNEL);
		if(buf==NULL)
			return -ENOBUFS;
		memcpy_fromiovec(buf, msg->msg_iov, len);
		fs=get_fs();
		set_fs(get_ds());
		err=raw_sendto(sk,buf,len, noblock, flags, msg->msg_name, msg->msg_namelen);
		set_fs(fs);
		kfree_s(buf,len);
		return err;
	}
}
Пример #2
0
static void
ping_send(struct raw_pcb *raw, ip_addr_t *addr)
{
  struct pbuf *p;
  struct icmp_echo_hdr *iecho;
  size_t ping_size = sizeof(struct icmp_echo_hdr) + PING_DATA_SIZE;

  LWIP_DEBUGF( PING_DEBUG, ("ping: send "));
  ip_addr_debug_print(PING_DEBUG, addr);
  LWIP_DEBUGF( PING_DEBUG, ("\n"));
  LWIP_ASSERT("ping_size <= 0xffff", ping_size <= 0xffff);

  p = pbuf_alloc(PBUF_IP, (u16_t)ping_size, PBUF_RAM);
  if (!p) {
    return;
  }
  if ((p->len == p->tot_len) && (p->next == NULL)) {
    iecho = (struct icmp_echo_hdr *)p->payload;

    ping_prepare_echo(iecho, (u16_t)ping_size);

    raw_sendto(raw, p, addr);
    ping_time = sys_now();
  }
  pbuf_free(p);
}
Пример #3
0
/**
 * Send some data on a RAW or UDP pcb contained in a netconn
 * Called from netconn_send
 *
 * @param msg the api_msg_msg pointing to the connection
 */
void
do_send(struct api_msg_msg *msg)
{
  if (!ERR_IS_FATAL(msg->conn->err)) {
    if (msg->conn->pcb.tcp != NULL) {
      switch (NETCONNTYPE_GROUP(msg->conn->type)) {
#if LWIP_RAW
      case NETCONN_RAW:
        if (msg->msg.b->addr == NULL) {
          msg->conn->err = raw_send(msg->conn->pcb.raw, msg->msg.b->p);
        } else {
          msg->conn->err = raw_sendto(msg->conn->pcb.raw, msg->msg.b->p, msg->msg.b->addr);
        }
        break;
#endif
#if LWIP_UDP
      case NETCONN_UDP:
        if (msg->msg.b->addr == NULL) {
          msg->conn->err = udp_send(msg->conn->pcb.udp, msg->msg.b->p);
        } else {
          msg->conn->err = udp_sendto(msg->conn->pcb.udp, msg->msg.b->p, msg->msg.b->addr, msg->msg.b->port);
        }
        break;
#endif /* LWIP_UDP */
      default:
        break;
      }
    }
  }
  TCPIP_APIMSG_ACK(msg);
}
Пример #4
0
void *toRawDev(void *arg)
{
	gpacket_t *inpkt = (gpacket_t *)arg;
	interface_t *iface;
	arp_packet_t *apkt;
	char tmpbuf[MAX_TMPBUF_LEN];
	int pkt_size;

	verbose(1, "[toRawDev]:: entering the function.. ");
	// find the outgoing interface and device...
	if ((iface = findInterface(inpkt->frame.dst_interface)) != NULL)
	{
		char tmp[40];
		memset(tmp, 0, sizeof(tmp));
		IP2Dot(tmp, inpkt->frame.src_ip_addr);
		/* The Amazon network has the prefix 172, so if a packet is sent to the raw interface and it does
		not begin with that prefix, we know that the packet has come from the local gini network instead.
		In this case we want to apply a SNAT, to make the packet seem as if it has come from the cRouter 
		so that Amazon machines will be able to respond (recognize the address). Note that the reverse
		NAT operation is performed in ip.c*/
		/*if(inpkt->data.header.prot != htons(ARP_PROTOCOL) && !(tmp[0] == '1' && tmp[1] == '7' && tmp[2] == '2')) {
			//printf("\n\n TRYING TO PING AMAZON CLOUD\n");				
			//printGPacket(inpkt, 3, "CONNOR PACKET");
			ip_packet_t *ipkt = (ip_packet_t *)(inpkt->data.data);
			ipkt->ip_hdr_len = 5;                                  // no IP header options!!
			icmphdr_t *icmphdr = (icmphdr_t *)((uchar *)ipkt + ipkt->ip_hdr_len*4);
			printf("\n\nICMP ID: %d\n", icmphdr->un.echo.id); 
			The IP address given to the SNAT function is the private ip address of the 
			Amazon instance that is running the cRouter in reverse 
			applySNAT("62.44.31.172", (ip_packet_t*)inpkt->data.data, icmphdr->un.echo.id);
			printNAT();	
		}*/
		/* send IP packet or ARP reply */
		if (inpkt->data.header.prot == htons(ARP_PROTOCOL))
		{
			printf("CONNORS DEBUG arp in toRawDev\n");
			apkt = (arp_packet_t *) inpkt->data.data;
			COPY_MAC(apkt->src_hw_addr, iface->mac_addr);
			COPY_IP(apkt->src_ip_addr, gHtonl(tmpbuf, iface->ip_addr));
		}
		if(inpkt->data.header.prot == htons(ICMP_PROTOCOL)){
			printf("\nICMP Request over raw\n");
		}		
		pkt_size = findPacketSize(&(inpkt->data));
		verbose(2, "[toRawDev]:: raw_sendto called for interface %d.. ", iface->interface_id);
		raw_sendto(iface->vpl_data, &(inpkt->data), pkt_size);
		free(inpkt);          // finally destroy the memory allocated to the packet..
	} else
		error("[toRawDev]:: ERROR!! Could not find outgoing interface ...");

	// this is just a dummy return -- return value not used.
	return arg;
}
Пример #5
0
static void raw_ip_op_write(struct socket * sock, message * m, __unused int blk)
{
	int ret;
	struct pbuf * pbuf;
	struct ip_hdr * ip_hdr;

	debug_print("socket num %ld data size %d",
			get_sock_num(sock), m->COUNT);

	if (sock->pcb == NULL) {
		ret = EIO;
		goto write_err;
	}

	if ((size_t) m->COUNT > sock->buf_size) {
		ret = ENOMEM;
		goto write_err;
	}

	pbuf = pbuf_alloc(PBUF_LINK, m->COUNT, PBUF_RAM);
	if (!pbuf) {
		ret = ENOMEM;
		goto write_err;
	}

	if ((ret = copy_from_user(m->m_source, pbuf->payload, m->COUNT,
				(cp_grant_id_t) m->IO_GRANT, 0)) != OK) {
		pbuf_free(pbuf);
		goto write_err;
	}

	ip_hdr = (struct ip_hdr *) pbuf->payload;
	if (pbuf_header(pbuf, -IP_HLEN)) {
		pbuf_free(pbuf);
		ret = EIO;
		goto write_err;
	}

	if ((ret = raw_sendto((struct raw_pcb *)sock->pcb, pbuf,
				(ip_addr_t *) &ip_hdr->dest)) != OK) {
		debug_print("raw_sendto failed %d", ret);
		ret = EIO;
	} else
		ret = m->COUNT;
	

	pbuf_free(pbuf);
	
write_err:
	sock_reply(sock, ret);
}
Пример #6
0
/**
 * Send some data on a RAW or UDP pcb contained in a netconn
 * Called from netconn_send
 *
 * @param msg the api_msg_msg pointing to the connection
 */
void
do_send(struct api_msg_msg *msg)
{
    if (ERR_IS_FATAL(msg->conn->last_err)) {
        msg->err = msg->conn->last_err;
    } else {
        msg->err = ERR_CONN;
        if (msg->conn->pcb.tcp != NULL) {
            switch (NETCONNTYPE_GROUP(msg->conn->type)) {
#if LWIP_RAW
            case NETCONN_RAW:
                if (ip_addr_isany(&msg->msg.b->addr)) {
                    msg->err = raw_send(msg->conn->pcb.raw, msg->msg.b->p);
                } else {
                    msg->err = raw_sendto(msg->conn->pcb.raw, msg->msg.b->p, &msg->msg.b->addr);
                }
                break;
#endif
#if LWIP_UDP
            case NETCONN_UDP:
#if LWIP_CHECKSUM_ON_COPY
                if (ip_addr_isany(&msg->msg.b->addr)) {
                    msg->err = udp_send_chksum(msg->conn->pcb.udp, msg->msg.b->p,
                                               msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum);
                } else {
                    msg->err = udp_sendto_chksum(msg->conn->pcb.udp, msg->msg.b->p,
                                                 &msg->msg.b->addr, msg->msg.b->port,
                                                 msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum);
                }
#else /* LWIP_CHECKSUM_ON_COPY */
                if (ip_addr_isany(&msg->msg.b->addr)) {
                    msg->err = udp_send(msg->conn->pcb.udp, msg->msg.b->p);
                } else {
                    msg->err = udp_sendto(msg->conn->pcb.udp, msg->msg.b->p, &msg->msg.b->addr, msg->msg.b->port);
                }
#endif /* LWIP_CHECKSUM_ON_COPY */
                break;
#endif /* LWIP_UDP */
            default:
                break;
            }
        }
    }
    TCPIP_APIMSG_ACK(msg);
}
Пример #7
0
static void ping_send(struct raw_pcb *raw, struct ping_info_t* ping_info)
{
        struct pbuf *p;
        struct icmp_echo_hdr *iecho;

        if (!(p = pbuf_alloc(PBUF_IP, ping_info->size, PBUF_RAM))) {
                return;
        }
        if ((p->len == p->tot_len) && (p->next == NULL)) {
                iecho = p->payload;

                ping_prepare_echo(iecho, ping_info);
                raw_sendto(raw, p, &ping_info->destination);

                if (!ping_info->first_tx_tm)
                        ping_info->first_tx_tm = timer_get_ms();
                ping_info->last_tx_tm = timer_get_ms();
                ping_info->num_tx++;
        }
        pbuf_free(p);
}
Пример #8
0
 int32_t MTD_FLASHMEM ICMP::ping(IPAddress const& dest)
 {       
     static uint32_t const TIMEOUT        = 4000;
     static int32_t const TIMEOUT_RESULT  = -1;
 
     uint32_t result = TIMEOUT_RESULT;
             
     // generate seq
     m_waitingSeq++;
     
     // prepare packet to send
     pbuf* hdrbuf = pbuf_alloc(PBUF_IP, sizeof(icmp_echo_hdr), PBUF_RAM);
     icmp_echo_hdr* hdr = (icmp_echo_hdr*)hdrbuf->payload;
     hdr->type   = ICMP_ECHO;
     hdr->code   = 0;
     hdr->chksum = 0;
     hdr->id     = htons(m_waitingID);
     hdr->seqno  = htons(m_waitingSeq);
     hdr->chksum = inet_chksum((uint16_t*)hdr, sizeof(icmp_echo_hdr));
     
     // send Echo request
     raw_pcb* pcb = raw_new(IP_PROTO_ICMP);
     raw_recv(pcb, ICMP::raw_recv_fn, this);
     raw_bind(pcb, IP_ADDR_ANY);            
     
     ip_addr_t addr = dest.get_ip_addr_t();
     raw_sendto(pcb, hdrbuf, &addr);
     pbuf_free(hdrbuf);
     
     uint32_t t1 = micros();
     if (m_queue.receive(TIMEOUT))
         result = (micros() - t1);
             
     raw_remove(pcb);
     
     return result;            
 }
Пример #9
0
/**
 * Send the raw IP packet to the address given by raw_connect()
 *
 * @param pcb the raw pcb which to send
 * @param p the IP payload to send
 *
 */
err_t
raw_send(struct raw_pcb *pcb, struct pbuf *p)
{
  return raw_sendto(pcb, p, &pcb->remote_ip);
}
Пример #10
0
/**
 * Send the raw IP packet to the address given by raw_connect()
 *
 * @param pcb the raw pcb which to send
 * @param p the IP payload to send
 *
 */
err_t ICACHE_FLASH_ATTR
raw_send(struct raw_pcb *pcb, struct pbuf *p)
{
  return raw_sendto(pcb, p, ipX_2_ip(&pcb->remote_ip));
}
Пример #11
0
int cmd_ping(FILE * f, int argc, char ** argv)
{
	struct raw_pcb * raw;
	uint8_t buf[BUF_LEN];
	in_addr_t ip_addr;
	struct sockaddr_in sin;
	struct iphdr * ip;
	struct icmphdr * icmp;
	uint8_t * data;
	int iphdrlen;
	int datalen;
	char s[16];
	int len;
	int id;
	int seq;
	int32_t dt;
	uint32_t ts;
	uint32_t now;
	int i;
	int n;
	int ret = 0;

	if (argc < 2) {
		fprintf(f, msg_ping_usage);
		return SHELL_ERR_ARG_MISSING;
	}

	if (argc > 3) {
		fprintf(f, msg_ping_usage);
		return SHELL_ERR_EXTRA_ARGS;
	}

	if (strcmp(argv[1], "help") == 0) {
		fprintf(f, "ping - send ICMP ECHO_REQUEST to network host\n");
		fprintf(f, msg_ping_usage);
		return 0;
	}

	if (inet_aton(argv[1], (struct in_addr *)&ip_addr) == 0) {
		fprintf(f, "ip address invalid.\n");
		return SHELL_ERR_ARG_INVALID;
	}

	if (argc > 2) {
		n = strtol(argv[2], NULL, 0);
	} else {
		n = 5;
	}

	raw = raw_pcb_new(IPPROTO_ICMP);

	id = thinkos_thread_self();	
	datalen = DATA_LEN;

	fprintf(f, "PING %s: %d octets data.\n", 
			inet_ntop(AF_INET, (void *)&ip_addr, s, 16), datalen);

	for (seq = 1; seq <= n; seq++) {
		icmp = (struct icmphdr *)(void *)buf;
		icmp->type = ICMP_ECHO;
		icmp->un.echo.id = id;
		icmp->un.echo.sequence = seq;
		data = buf + sizeof(struct icmphdr);
		for (i = 0; i < datalen; i++) {
			data[i] = i;
		}
		len = datalen + sizeof(struct icmphdr);

		sin.sin_addr.s_addr = ip_addr;
		sin.sin_family = AF_INET;

		ts = thinkos_clock();
//		gettimeofday(&tv, NULL);
		memcpy(data, &ts, sizeof(uint32_t));

		icmp->chksum = 0;
		icmp->chksum = ~in_chksum(0, icmp, len);

		raw_sendto(raw, buf, len, (struct sockaddr_in *)&sin);

		len = raw_recvfrom_tmo(raw, buf, BUF_LEN, 
							   (struct sockaddr_in *)&sin, 1000);

		if (len < 0) {
			if (len != -ETIMEDOUT) {
				ret = -1;
				break;
			}
			fprintf(f, "timed out.\n");
			continue;
		}

		now = thinkos_clock();

		ip = (struct iphdr *)buf;
		iphdrlen = ip->hlen * 4;
		icmp = (struct icmphdr *)(buf + iphdrlen);

		if ((icmp->type == ICMP_ECHOREPLY) && 
			(icmp->un.echo.id == id)) {

			memcpy(&ts, buf + iphdrlen + sizeof(struct icmphdr), 
				   sizeof(uint32_t));

			len -= iphdrlen + sizeof(struct icmphdr);

			dt = (int32_t)(now - ts);

			fprintf(f, "%d octets from %s: icmp_seq=%d "
					"ttl=%d time=%d ms\n",
					len, inet_ntop(AF_INET, (void *)&sin.sin_addr, s, 16), 
					icmp->un.echo.sequence, ip->ttl, dt);
		} else {
			fprintf(f, "icmp: %d\n", icmp->type);
		}

		thinkos_sleep(250);
	}

	raw_close(raw);

	return ret;
}
Пример #12
0
int netstack_send_echo(u8 *ripaddr, u16 size, u16 seqno, 
			struct netstack_echo_reply *reply)
{
	int i, rc;
	u64 timeout = PING_DELAY_NS;
	struct pbuf *p;
	struct icmp_echo_hdr *iecho;
	size_t len = sizeof(struct icmp_echo_hdr) + size;

	LWIP_ASSERT("ping_size <= 0xffff", len <= 0xffff);

	/* Lock ping context for atomicity */
	vmm_mutex_lock(&lns.ping_lock);

	/* Alloc ping pbuf */
	p = pbuf_alloc(PBUF_IP, (u16_t)len, PBUF_RAM);
	if (!p) {
		vmm_mutex_unlock(&lns.ping_lock);
		return VMM_ENOMEM;
	}
	if ((p->len != p->tot_len) || (p->next != NULL)) {
		pbuf_free(p);
		vmm_mutex_unlock(&lns.ping_lock);
		return VMM_EFAIL;
	}

	/* Prepare ECHO request */
	iecho = (struct icmp_echo_hdr *)p->payload;
	ICMPH_TYPE_SET(iecho, ICMP_ECHO);
	ICMPH_CODE_SET(iecho, 0);
	iecho->chksum = 0;
	iecho->id     = PING_ID;
	iecho->seqno  = htons(seqno);
	for (i = 0; i < size; i++) {
		((char*)iecho)[sizeof(struct icmp_echo_hdr) + i] = (char)i;
	}
	iecho->chksum = inet_chksum(iecho, len);

	/* Prepare target address */
	IP4_ADDR(&lns.ping_addr, ripaddr[0],ripaddr[1],ripaddr[2],ripaddr[3]);

	/* Save ping info */
	lns.ping_seq_num = seqno;
	lns.ping_reply = reply;
	lns.ping_recv_tstamp = 0;
	lns.ping_send_tstamp = vmm_timer_timestamp();
	lns.ping_recv_tstamp = lns.ping_send_tstamp + PING_DELAY_NS;

	/* Send ping packet */
	raw_sendto(lns.ping_pcb, p, &lns.ping_addr);

	/* Wait for ping to complete with timeout */
	timeout = lns.ping_recv_tstamp - lns.ping_send_tstamp;
	rc = vmm_completion_wait_timeout(&lns.ping_done, &timeout);
	timeout = lns.ping_recv_tstamp - lns.ping_send_tstamp;
	lns.ping_reply->rtt = udiv64(timeout, 1000);

	/* Free ping pbuf */
	pbuf_free(p);

	/* Clear ping reply pointer */
	lns.ping_reply = NULL;

	/* Unloack ping context */
	vmm_mutex_unlock(&lns.ping_lock);

	return rc;
}