Ejemplo n.º 1
0
/**
 * Bind a pcb contained in a netconn
 * Called from netconn_bind.
 *
 * @param msg the api_msg_msg pointing to the connection and containing
 *            the IP address and port to bind to
 */
void
do_bind(struct api_msg_msg *msg)
{
    if (ERR_IS_FATAL(msg->conn->last_err)) {
        msg->err = msg->conn->last_err;
    } else {
        msg->err = ERR_VAL;
        if (msg->conn->pcb.tcp != NULL) {
            switch (NETCONNTYPE_GROUP(msg->conn->type)) {
#if LWIP_RAW
            case NETCONN_RAW:
                msg->err = raw_bind(msg->conn->pcb.raw, msg->msg.bc.ipaddr);
                break;
#endif /* LWIP_RAW */
#if LWIP_UDP
            case NETCONN_UDP:
                msg->err = udp_bind(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port);
                break;
#endif /* LWIP_UDP */
#if LWIP_TCP
            case NETCONN_TCP:
                msg->err = tcp_bind(msg->conn->pcb.tcp, msg->msg.bc.ipaddr, msg->msg.bc.port);
                break;
#endif /* LWIP_TCP */
            default:
                break;
            }
        }
    }
    TCPIP_APIMSG_ACK(msg);
}
Ejemplo n.º 2
0
static void ping_raw_init(void)
{
    ping_pcb = raw_new(IP_PROTO_ICMP);
    LWIP_ASSERT("ping_pcb != NULL", ping_pcb != NULL);

    raw_recv(ping_pcb, ping_recv, NULL);
    raw_bind(ping_pcb, IP_ADDR_ANY);
    sys_timeout(PING_DELAY, ping_timeout, ping_pcb);
}
Ejemplo n.º 3
0
/**
 * Bind a pcb contained in a netconn
 * Called from netconn_bind.
 *
 * @param msg the api_msg_msg pointing to the connection and containing
 *            the IP address and port to bind to
 */
void
do_bind(struct api_msg_msg *msg)
{
  if (!ERR_IS_FATAL(msg->conn->err)) {
    if (msg->conn->pcb.tcp != NULL) {
      //[MS_CHANGE] - make sure we are binding to a valid address
      u8_t validAddr = ip_addr_isany(msg->msg.bc.ipaddr);

      if(!validAddr) {
        struct netif *netif;
        for(netif = netif_list; netif != NULL; netif = netif->next) {
          /* network mask matches? */
          if (netif_is_up(netif)) {
            if(ip_addr_cmp(msg->msg.bc.ipaddr, &netif->ip_addr)) {
                validAddr = 1;
                break;
            }
          }
        }
      }

      //[MS_CHANGE] - make sure we are binding to a valid address
      if(validAddr) 
      {
        switch (NETCONNTYPE_GROUP(msg->conn->type)) {
  #if LWIP_RAW
        case NETCONN_RAW:
          msg->conn->err = raw_bind(msg->conn->pcb.raw, msg->msg.bc.ipaddr);
          break;
  #endif /* LWIP_RAW */
  #if LWIP_UDP
        case NETCONN_UDP:
          msg->conn->err = udp_bind(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port);
          break;
  #endif /* LWIP_UDP */
  #if LWIP_TCP
        case NETCONN_TCP:
          msg->conn->err = tcp_bind(msg->conn->pcb.tcp, msg->msg.bc.ipaddr, msg->msg.bc.port);
          break;
  #endif /* LWIP_TCP */
        default:
          break;
        }
      }
      else {
          msg->conn->err = ERR_VAL;        
      }
    } else {
      /* msg->conn->pcb is NULL */
      msg->conn->err = ERR_VAL;
    }
  }
  TCPIP_APIMSG_ACK(msg);
}
Ejemplo n.º 4
0
static void raw_ip_set_opt(struct socket * sock, message * m)
{
	int err;
	nwio_ipopt_t ipopt;
	struct raw_pcb * pcb;

	err = copy_from_user(m->m_source, &ipopt, sizeof(ipopt),
				(cp_grant_id_t) m->IO_GRANT, 0);

	if (err != OK)
		sock_reply(sock, err);

	debug_print("ipopt.nwio_flags = 0x%lx", ipopt.nwio_flags);
	debug_print("ipopt.nwio_proto = 0x%x", ipopt.nwio_proto);
	debug_print("ipopt.nwio_rem = 0x%x",
				(unsigned int) ipopt.nwio_rem);

	if (sock->pcb == NULL) {
		if (!(pcb = raw_new(ipopt.nwio_proto))) {
			raw_ip_close(sock);
			sock_reply(sock, ENOMEM);
			return;
		}

		sock->pcb = pcb;
	} else
		pcb = (struct raw_pcb *) sock->pcb;

	if (pcb->protocol != ipopt.nwio_proto) {
		debug_print("conflicting ip socket protocols\n");
		sock_reply(sock, EBADIOCTL);
	}

	sock->usr_flags = ipopt.nwio_flags;

#if 0
	if (raw_bind(pcb, (ip_addr_t *)&ipopt.nwio_rem) == ERR_USE) {
		raw_ip_close(sock);
		sock_reply(sock, EADDRINUSE);
		return;
	}
#endif

	/* register a receive hook */
	raw_recv((struct raw_pcb *) sock->pcb, raw_ip_op_receive, sock);

	sock_reply(sock, OK);
}
Ejemplo n.º 5
0
static void ping_raw_init(void)
{
	INIT_MUTEX(&lns.ping_lock);

	lns.ping_seq_num = 0;
	lns.ping_send_tstamp = 0;
	lns.ping_recv_tstamp = 0;

	lns.ping_pcb = raw_new(IP_PROTO_ICMP);
	LWIP_ASSERT("ping_pcb != NULL", lns.ping_pcb != NULL);
	raw_recv(lns.ping_pcb, ping_recv, NULL);
	raw_bind(lns.ping_pcb, IP_ADDR_ANY);

	lns.ping_reply = NULL;

	INIT_COMPLETION(&lns.ping_done);
}
Ejemplo n.º 6
0
static bool ICACHE_FLASH_ATTR
ping_raw_init(struct ping_msg *pingmsg)
{
	if (pingmsg == NULL)
		return false;

	ip_addr_t ping_target;
	pingmsg->ping_pcb = raw_new(IP_PROTO_ICMP);
	LWIP_ASSERT("ping_pcb != NULL", pingmsg->ping_pcb != NULL);

	raw_recv(pingmsg->ping_pcb, ping_recv, pingmsg);
	raw_bind(pingmsg->ping_pcb, IP_ADDR_ANY);

	ping_target.addr = pingmsg->ping_opt->ip;
	pingmsg ->ping_sent = system_get_time();
	ping_send(pingmsg->ping_pcb, &ping_target);

	sys_timeout(PING_TIMEOUT_MS, ping_timeout, pingmsg);
	sys_timeout(pingmsg->coarse_time, ping_coarse_tmr, pingmsg);
	return true;
}
Ejemplo n.º 7
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;            
 }
static void
do_bind(struct api_msg_msg *msg)
{
  if (msg->conn->pcb.tcp == NULL) {
    switch (msg->conn->type) {
#if LWIP_RAW
    case NETCONN_RAW:
      msg->conn->pcb.raw = raw_new(msg->msg.bc.port); /* misusing the port field as protocol */
      raw_recv(msg->conn->pcb.raw, recv_raw, msg->conn);
      break;
#endif
#if LWIP_UDP
    case NETCONN_UDPLITE:
      msg->conn->pcb.udp = udp_new();
      udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_UDPLITE);
      udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
      break;
    case NETCONN_UDPNOCHKSUM:
      msg->conn->pcb.udp = udp_new();
      udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM);
      udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
      break;
    case NETCONN_UDP:
      msg->conn->pcb.udp = udp_new();
      udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
      break;
#endif /* LWIP_UDP */
#if LWIP_TCP      
    case NETCONN_TCP:
      msg->conn->pcb.tcp = tcp_new();
      setup_tcp(msg->conn);
#endif /* LWIP_TCP */
    default:  
    break;
    }
  }
  switch (msg->conn->type) {
#if LWIP_RAW
  case NETCONN_RAW:
    msg->conn->err = raw_bind(msg->conn->pcb.raw,msg->msg.bc.ipaddr);
    break;
#endif
#if LWIP_UDP
  case NETCONN_UDPLITE:
    /* FALLTHROUGH */
  case NETCONN_UDPNOCHKSUM:
    /* FALLTHROUGH */
  case NETCONN_UDP:
    msg->conn->err = udp_bind(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port);
    break;
#endif /* LWIP_UDP */
#if LWIP_TCP
  case NETCONN_TCP:
    msg->conn->err = tcp_bind(msg->conn->pcb.tcp,
            msg->msg.bc.ipaddr, msg->msg.bc.port);
#endif /* LWIP_TCP */
  default:
    break;
  }
  sys_mbox_post(msg->conn->mbox, NULL);
}
Ejemplo n.º 9
0
cmd_state_t cmd_ping(int argc, char* argv[], void* ctx)
{
        static enum {
                INIT,
                PING,
                WAIT_REPLY
        } state = INIT;

        struct ping_info_t *ping_info = &INFO;
        static struct raw_pcb *pcb;

        switch (state) {
        case INIT:
                if (init_ping_info(argc, argv, ping_info) != 0) {
                        printk("Usage: ping [-c count] [-i interval] "  \
                               "[-s packetsize]\n            " \
                               "[-w deadline] [-q] destination\n");
                        return CMD_DONE;
                }

                if (!(pcb = raw_new(IP_PROTO_ICMP))) {
                        printk("could not allocate pcb\n");
                        state = INIT;
                        return CMD_DONE;
                }
                raw_recv(pcb, ping_recv, ping_info);
                raw_bind(pcb, IP_ADDR_ANY);

                printk("PING %s %d(%d) bytes of data\n",
                       ip2str(ping_info->destination),
                       ping_info->data_size,
                       ping_info->size);
                state = PING;
                /* fall through */

        case PING:
                if (!netif_is_up(netif_default)) {
                        printk("netif is down\n");
                        raw_remove(pcb);
                        state = INIT;
                        return CMD_DONE;
                }

                if (ping_info->count && ping_info->num_tx == ping_info->count) {
                        ping_finalize(ping_info);
                        raw_remove(pcb);
                        state = INIT;
                        return CMD_DONE;
                }


                if (timer_get_ms() < ping_info->last_rx_tm + ping_info->interval) {
                        return CMD_INPROGRESS;
                }
                ping_send(pcb, ping_info);

                state = WAIT_REPLY;
                return CMD_INPROGRESS;

        case WAIT_REPLY:
                if (ping_info->flags & PING_REPLY) {
                        ping_info->flags &= (~PING_REPLY);
                        state = PING;
                        return CMD_INPROGRESS;
                }

                if (timer_get_ms() >
                    ping_info->last_tx_tm + ping_info->timeout) {
                        if (!ping_info->quiet)
                                printk("timeout from %s\n",
                                       ip2str(ping_info->destination));
                        state = PING;
                        return CMD_INPROGRESS;
                }

                if (ping_info->deadline &&
                    timer_get_ms() >
                    ping_info->first_tx_tm + ping_info->deadline * 1000) {
                        ping_finalize(ping_info);
                        raw_remove(pcb);
                        state = INIT;
                        return CMD_DONE;
                }

                return CMD_INPROGRESS;
        }

        /* unreachable */
        assert(0);
	return CMD_DONE;
}
Ejemplo n.º 10
0
int
raw_usrreq(struct socket *so,
	   int req,
	   struct mbuf *m,
	   struct mbuf *nam,
	   struct mbuf *control)
{
	register struct rawcb *rp = sotorawcb(so);
	register int error = 0;
	int len;

	if (req == PRU_CONTROL)
		return (EOPNOTSUPP);
	if (control && control->m_len) {
		error = EOPNOTSUPP;
		goto release;
	}
	if (rp == 0) {
		error = EINVAL;
		goto release;
	}
	switch (req) {

	/*
	 * Allocate a raw control block and fill in the
	 * necessary info to allow packets to be routed to
	 * the appropriate raw interface routine.
	 */
	case PRU_ATTACH:
		if ((so->so_state & SS_PRIV) == 0) {
			error = EACCES;
			break;
		}
		error = raw_attach(so, (int)nam);
		break;

	/*
	 * Destroy state just before socket deallocation.
	 * Flush data or not depending on the options.
	 */
	case PRU_DETACH:
		if (rp == 0) {
			error = ENOTCONN;
			break;
		}
		raw_detach(rp);
		break;

#ifdef notdef
	/*
	 * If a socket isn't bound to a single address,
	 * the raw input routine will hand it anything
	 * within that protocol family (assuming there's
	 * nothing else around it should go to). 
	 */
	case PRU_CONNECT:
		if (rp->rcb_faddr) {
			error = EISCONN;
			break;
		}
		nam = m_copym(nam, 0, M_COPYALL, M_WAIT);
		rp->rcb_faddr = mtod(nam, struct sockaddr *);
		soisconnected(so);
		break;

	case PRU_BIND:
		if (rp->rcb_laddr) {
			error = EINVAL;			/* XXX */
			break;
		}
		error = raw_bind(so, nam);
		break;
#endif

	case PRU_CONNECT2:
		error = EOPNOTSUPP;
		goto release;

	case PRU_DISCONNECT:
		if (rp->rcb_faddr == 0) {
			error = ENOTCONN;
			break;
		}
		raw_disconnect(rp);
		soisdisconnected(so);
		break;

	/*
	 * Mark the connection as being incapable of further input.
	 */
	case PRU_SHUTDOWN:
		socantsendmore(so);
		break;

	/*
	 * Ship a packet out.  The appropriate raw output
	 * routine handles any massaging necessary.
	 */
	case PRU_SEND:
		if (nam) {
			if (rp->rcb_faddr) {
				error = EISCONN;
				break;
			}
			rp->rcb_faddr = mtod(nam, struct sockaddr *);
		} else if (rp->rcb_faddr == 0) {
			error = ENOTCONN;
			break;
		}
		error = (*so->so_proto->pr_output)(m, so);
		m = NULL;
		if (nam)
			rp->rcb_faddr = 0;
		break;

	case PRU_ABORT:
		raw_disconnect(rp);
		sofree(so);
		soisdisconnected(so);
		break;

	case PRU_SENSE:
		/*
		 * stat: don't bother with a blocksize.
		 */
		return (0);

	/*
	 * Not supported.
	 */
	case PRU_RCVOOB:
	case PRU_RCVD:
		return(EOPNOTSUPP);

	case PRU_LISTEN:
	case PRU_ACCEPT:
	case PRU_SENDOOB:
		error = EOPNOTSUPP;
		break;

	case PRU_SOCKADDR:
		if (rp->rcb_laddr == 0) {
			error = EINVAL;
			break;
		}
		len = rp->rcb_laddr->sa_len;
		aligned_bcopy((caddr_t)rp->rcb_laddr, mtod(nam, caddr_t), (unsigned)len);
		nam->m_len = len;
		break;

	case PRU_PEERADDR:
		if (rp->rcb_faddr == 0) {
			error = ENOTCONN;
			break;
		}
		len = rp->rcb_faddr->sa_len;
		aligned_bcopy((caddr_t)rp->rcb_faddr, mtod(nam, caddr_t), (unsigned)len);
		nam->m_len = len;
		break;

	default:
		panic("raw_usrreq");
	}