/** * 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); }
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); }
/** * 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); }
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); }
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); }
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; }
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); }
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; }
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"); }