void slirp_input(const uint8_t *pkt, int pkt_len) { struct mbuf *m; int proto; if (pkt_len < ETH_HLEN) return; proto = ntohs(*(uint16_t *)(pkt + 12)); switch(proto) { case ETH_P_ARP: arp_input(pkt, pkt_len); break; case ETH_P_IP: m = m_get(); if (!m) return; if (M_FREEROOM(m) < pkt_len + 2) { m_inc(m, pkt_len + 2); } m->m_len = pkt_len + 2; memcpy(m->m_data + 2, pkt, pkt_len); m->m_data += 2 + ETH_HLEN; m->m_len -= 2 + ETH_HLEN; ip_input(m); break; default: break; } }
/* * IP software interrupt routine */ void ipintr(void) { int s; struct mbuf *m; struct ifqueue lcl_intrq; memset(&lcl_intrq, 0, sizeof(lcl_intrq)); mutex_enter(softnet_lock); KERNEL_LOCK(1, NULL); if (!IF_IS_EMPTY(&ipintrq)) { s = splnet(); /* Take existing queue onto stack */ lcl_intrq = ipintrq; /* Zero out global queue, preserving maxlen and drops */ ipintrq.ifq_head = NULL; ipintrq.ifq_tail = NULL; ipintrq.ifq_len = 0; ipintrq.ifq_maxlen = lcl_intrq.ifq_maxlen; ipintrq.ifq_drops = lcl_intrq.ifq_drops; splx(s); } KERNEL_UNLOCK_ONE(NULL); while (!IF_IS_EMPTY(&lcl_intrq)) { IF_DEQUEUE(&lcl_intrq, m); if (m == NULL) break; ip_input(m); } mutex_exit(softnet_lock); }
void slirp_input(const uint8_t *pkt, int pkt_len) { struct mbuf *m; int proto; if (pkt_len < ETH_HLEN) return; proto = (pkt[12] << 8) | pkt[13]; switch(proto) { case ETH_P_ARP: arp_input(pkt, pkt_len); break; case ETH_P_IP: m = m_get(); if (!m) return; /* Note: we add to align the IP header */ m->m_len = pkt_len + 2; memcpy(m->m_data + 2, pkt, pkt_len); m->m_data += 2 + ETH_HLEN; m->m_len -= 2 + ETH_HLEN; ip_input(m); break; default: break; } }
/** * Call netif_poll() in the main loop of your application. This is to prevent * reentering non-reentrant functions like tcp_input(). Packets passed to * netif_loop_output() are put on a list that is passed to netif->input() by * netif_poll(). */ void netif_poll(struct netif *netif) { struct pbuf *in; /* If we have a loopif, SNMP counters are adjusted for it, * if not they are adjusted for 'netif'. */ #if LWIP_SNMP #if LWIP_HAVE_LOOPIF struct netif *stats_if = &loop_netif; #else /* LWIP_HAVE_LOOPIF */ struct netif *stats_if = netif; #endif /* LWIP_HAVE_LOOPIF */ #endif /* LWIP_SNMP */ SYS_ARCH_DECL_PROTECT(lev); do { /* Get a packet from the list. With SYS_LIGHTWEIGHT_PROT=1, this is protected */ SYS_ARCH_PROTECT(lev); in = netif->loop_first; if (in != NULL) { struct pbuf *in_end = in; #if LWIP_LOOPBACK_MAX_PBUFS u8_t clen = pbuf_clen(in); /* adjust the number of pbufs on queue */ LWIP_ASSERT("netif->loop_cnt_current underflow", ((netif->loop_cnt_current - clen) < netif->loop_cnt_current)); netif->loop_cnt_current -= clen; #endif /* LWIP_LOOPBACK_MAX_PBUFS */ while (in_end->len != in_end->tot_len) { LWIP_ASSERT("bogus pbuf: len != tot_len but next == NULL!", in_end->next != NULL); in_end = in_end->next; } /* 'in_end' now points to the last pbuf from 'in' */ if (in_end == netif->loop_last) { /* this was the last pbuf in the list */ netif->loop_first = netif->loop_last = NULL; } else { /* pop the pbuf off the list */ netif->loop_first = in_end->next; LWIP_ASSERT("should not be null since first != last!", netif->loop_first != NULL); } /* De-queue the pbuf from its successors on the 'loop_' list. */ in_end->next = NULL; } SYS_ARCH_UNPROTECT(lev); if (in != NULL) { LINK_STATS_INC(link.recv); snmp_add_ifinoctets(stats_if, in->tot_len); snmp_inc_ifinucastpkts(stats_if); /* loopback packets are always IP packets! */ if (ip_input(in, netif) != ERR_OK) { pbuf_free(in); } /* Don't reference the packet any more! */ in = NULL; } /* go on while there is a packet on the list */ } while (netif->loop_first != NULL); }
void if_loop_input_task (intptr_t exinf) { T_NET_BUF *input; ID tskid; get_tid(&tskid); syslog(LOG_NOTICE, "[LOOP INPUT:%d] started.", tskid); while (true) { if (rcv_dtq(DTQ_LOOP_INPUT, (intptr_t)&input) == E_OK) { NET_COUNT_LOOP(net_count_loop.in_octets, input->len); NET_COUNT_LOOP(net_count_loop.in_packets, 1); #if defined(SUPPORT_INET4) /* IPv4 入力関数を呼び出す */ if (IP4_VHL_V(GET_IP4_HDR(input)->vhl) == IPV4_VERSION) ip_input(input); #endif /* of #if defined(SUPPORT_INET4) */ #if defined(SUPPORT_INET6) /* IPv6 入力関数を呼び出す */ if (IP6_VCF_V(ntohl(GET_IP6_HDR(input)->vcf)) == IPV6_VERSION) ip6_input(input); #endif /* of #if defined(SUPPORT_INET6) */ } } }
void __attribute__((noreturn)) ifnet_input_task(void * arg) { struct ifnet * ifn = NULL; unsigned int proto; unsigned int idx; uint8_t * pkt; uint8_t * src; int ret; int len; for (;;) { DCC_LOG(LOG_INFO, "wait..."); /* wait for an event form a network interface */ idx = thinkos_ev_wait(__ifnet__.evset); #if 0 if (idx < 0) { DCC_LOG1(LOG_ERROR, "thinkos_ev_wait() failed: %d", idx); abort(); } else if (idx > IFNET_INTERFACES_MAX) { DCC_LOG1(LOG_ERROR, "thinkos_ev_wait() invalid event: %d", idx); abort(); } #endif /* lookup the interface */ ifn = &__ifnet__.ifn[idx]; /* get the packet from the network interface */ while ((len = ifn_pkt_recv(ifn, &src, &proto, &pkt)) > 0) { tcpip_net_lock(); NETIF_STAT_ADD(ifn, rx_pkt, 1); if (proto == NTOHS(ETH_P_IP)) { DCC_LOG(LOG_INFO, "IP"); DBG("IFNET: IP packet received."); ret = ip_input(ifn, (struct iphdr *)pkt, len); } else if (proto == NTOHS(ETH_P_ARP)) { DCC_LOG(LOG_INFO, "ARP"); ret = etharp_input(ifn, (struct etharp*)pkt, len); } else { NETIF_STAT_ADD(ifn, rx_drop, 1); DCC_LOG1(LOG_TRACE, "unhandled protocol: %d", proto); WARN("IFNET: unhandled protocol: %d", proto); ret = 0; } tcpip_net_unlock(); if (ret <= 0) { ifn_pkt_free(ifn, pkt); } else { __ifnet__.stats.err++; WARN("IFNET: not releasing packet: %d", pkt); } } } }
static void InputCB(void* pvArg) { //TCPIP input callback. This function has been registered by ps2ip_input and will be invoked in the context of the //tcpip-thread. Hence, only synchronization for the message-queue is required. InputMSG* pMSG=(InputMSG*)pvArg; PBuf* pInput=pMSG->pInput; NetIF* pNetIF=pMSG->pNetIF; int iFlags; //Remove the first message in the message-queue. BTW: pMSG == &aMSGs[u8FirstMSG]. CpuSuspendIntr(&iFlags); u8FirstMSG=GetNextMSGQueueIndex(u8FirstMSG); CpuResumeIntr(iFlags); //What kind of package is it? switch (htons(((struct eth_hdr*)(pInput->payload))->type)) { case ETHTYPE_IP: //IP-packet. Update ARP table, obtain first queued packet. etharp_ip_input(pNetIF,pInput); //Skip Ethernet header. pbuf_header(pInput,-14); //Pass to network layer. ip_input(pInput,pNetIF); //Send out the ARP reply or ARP queued packet. SendARPReply(pNetIF,NULL); break; case ETHTYPE_ARP: //ARP-packet. Pass pInput to ARP module, get ARP reply or ARP queued packet. etharp_arp_input(pNetIF,(struct eth_addr*)&pNetIF->hwaddr,pInput); //Send out the ARP reply or ARP queued packet. SendARPReply(pNetIF,NULL); break; default: //Unsupported ethernet packet-type. Free pInput. pbuf_free(pInput); } }
/** * @ingroup lwip_nosys * Forwards a received packet for input processing with * ethernet_input() or ip_input() depending on netif flags. * Don't call directly, pass to netif_add() and call * netif->input(). * Only works if the netif driver correctly sets * NETIF_FLAG_ETHARP and/or NETIF_FLAG_ETHERNET flag! */ err_t netif_input(struct pbuf *p, struct netif *inp) { #if LWIP_ETHERNET if (inp->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) { return ethernet_input(p, inp); } else #endif /* LWIP_ETHERNET */ return ip_input(p, inp); }
static void tcpip_thread(void *arg) { struct tcpip_msg *msg; (void)arg; ip_init(); #if LWIP_UDP udp_init(); #endif #if LWIP_TCP tcp_init(); #endif #if IP_REASSEMBLY sys_timeout(1000, ip_timer, NULL); #endif if (tcpip_init_done != NULL) { tcpip_init_done(tcpip_init_done_arg); } while (1) { /* MAIN Loop */ sys_mbox_fetch(mbox, (void *)&msg); switch (msg->type) { case TCPIP_MSG_API: LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API message %p\n", (void *)msg)); api_msg_input(msg->msg.apimsg); break; case TCPIP_MSG_INPUT: LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: IP packet %p\n", (void *)msg)); ip_input(msg->msg.inp.p, msg->msg.inp.netif); break; case TCPIP_MSG_CALLBACK: LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK %p\n", (void *)msg)); msg->msg.cb.f(msg->msg.cb.ctx); break; default: break; } #ifdef VBOX if (msg->type == TCPIP_MSG_TERM) { memp_free(MEMP_TCPIP_MSG, msg); break; } #endif memp_free(MEMP_TCPIP_MSG, msg); } #ifdef VBOX if (tcpip_init_done != NULL) { tcpip_init_done(tcpip_init_done_arg); } #endif }
// // Process an incoming IP or ethernet packet. // static err_t simple_input(struct pbuf *p, struct netif *netif) { #if LWIP_ARP if (netif->flags & NETIF_FLAG_ETHARP) { ethernet_input(p, netif); } else #endif { ip_input(p, netif); } return ERR_OK; }
/** * Call netif_poll() in the main loop of your application. This is to prevent * reentering non-reentrant functions like tcp_input(). Packets passed to * netif_loop_output() are put on a list that is passed to netif->input() by * netif_poll(). */ void netif_poll(struct netif *netif) { _printf("<%s>", __func__); struct pbuf *in; SYS_ARCH_DECL_PROTECT(lev); do { /* Get a packet from the list. With SYS_LIGHTWEIGHT_PROT=1, this is protected */ SYS_ARCH_PROTECT(lev); in = netif->loop_first; if(in != NULL) { struct pbuf *in_end = in; #if LWIP_LOOPBACK_MAX_PBUFS u8_t clen = pbuf_clen(in); /* adjust the number of pbufs on queue */ LWIP_ASSERT("netif->loop_cnt_current underflow", ((netif->loop_cnt_current - clen) < netif->loop_cnt_current)); netif->loop_cnt_current -= clen; #endif /* LWIP_LOOPBACK_MAX_PBUFS */ while(in_end->len != in_end->tot_len) { LWIP_ASSERT("bogus pbuf: len != tot_len but next == NULL!", in_end->next != NULL); in_end = in_end->next; } /* 'in_end' now points to the last pbuf from 'in' */ if(in_end == netif->loop_last) { /* this was the last pbuf in the list */ netif->loop_first = netif->loop_last = NULL; } else { /* pop the pbuf off the list */ netif->loop_first = in_end->next; LWIP_ASSERT("should not be null since first != last!", netif->loop_first != NULL); } /* De-queue the pbuf from its successors on the 'loop_' list. */ in_end->next = NULL; } SYS_ARCH_UNPROTECT(lev); if(in != NULL) { /* loopback packets are always IP packets! */ if(ip_input(in, netif) != ERR_OK) { pbuf_free(in); } /* Don't reference the packet any more! */ in = NULL; } /* go on while there is a packet on the list */ } while(netif->loop_first != NULL); }
static void ip_proto_input(protocol_family_t protocol, mbuf_t packet_list) { #pragma unused(protocol) mbuf_t packet; int how_many = 0 ; /* ip_input should handle a list of packets but does not yet */ for (packet = packet_list; packet; packet = packet_list) { how_many++; packet_list = mbuf_nextpkt(packet); mbuf_setnextpkt(packet, NULL); ip_input(packet); } }
static void tcpip_thread(void *arg) { struct tcpip_msg *msg; (void)arg; ip_init(); #if LWIP_UDP udp_init(); #endif #if LWIP_TCP tcp_init(); #endif if (tcpip_init_done != NULL) { tcpip_init_done(tcpip_init_done_arg); } sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); //ZOT716u2 Network_TCPIP_ON = 1; while (1) { /* MAIN Loop */ sys_mbox_fetch(tcp_mbox, (void *)&msg); switch (msg->type) { case TCPIP_MSG_API: LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API message %p\n", (void *)msg)); api_msg_input(msg->msg.apimsg); break; case TCPIP_MSG_INPUT: cli(); Lanrecvcnt --; sti(); LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: IP packet %p\n", (void *)msg)); ip_input(msg->msg.inp.p, msg->msg.inp.netif); break; case TCPIP_MSG_CALLBACK: LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK %p\n", (void *)msg)); msg->msg.cb.f(msg->msg.cb.ctx); break; default: break; } memp_free(MEMP_TCPIP_MSG, msg); } }
/* * Shared implementation for inject via ip_output and ip_input */ static void ip_ni_queue_func_impl(injection_t *inject, boolean_t out) { net_inject_t *packet; ill_t *ill; ip_stack_t *ipst = (ip_stack_t *)inject->inj_ptr; ip_xmit_attr_t ixas; ASSERT(inject != NULL); packet = &inject->inj_data; ASSERT(packet->ni_packet != NULL); if (out == 0) { ill = ill_lookup_on_ifindex((uint_t)packet->ni_physical, inject->inj_isv6, ipst); if (ill == NULL) { kmem_free(inject, sizeof (*inject)); return; } if (inject->inj_isv6) { ip_input_v6(ill, NULL, packet->ni_packet, NULL); } else { ip_input(ill, NULL, packet->ni_packet, NULL); } ill_refrele(ill); } else { bzero(&ixas, sizeof (ixas)); ixas.ixa_ifindex = packet->ni_physical; ixas.ixa_ipst = ipst; if (inject->inj_isv6) { ixas.ixa_flags = IXAF_BASIC_SIMPLE_V6; } else { ixas.ixa_flags = IXAF_BASIC_SIMPLE_V4; } ixas.ixa_flags &= ~IXAF_VERIFY_SOURCE; (void) ip_output_simple(packet->ni_packet, &ixas); ixa_cleanup(&ixas); } kmem_free(inject, sizeof (*inject)); }
/** * Pass a received packet to tcpip_thread for input processing * * @param p the received packet, p->payload pointing to the Ethernet header or * to an IP header (if inp doesn't have NETIF_FLAG_ETHARP or * NETIF_FLAG_ETHERNET flags) * @param inp the network interface on which the packet was received */ err_t tcpip_input(struct pbuf *p, struct netif *inp) { #if LWIP_TCPIP_CORE_LOCKING_INPUT err_t ret; LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_input: PACKET %p/%p\n", (void *)p, (void *)inp)); LOCK_TCPIP_CORE(); #if LWIP_ETHERNET if (inp->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) { ret = ethernet_input(p, inp); } else #endif /* LWIP_ETHERNET */ { ret = ip_input(p, inp); } UNLOCK_TCPIP_CORE(); return ret; #else /* LWIP_TCPIP_CORE_LOCKING_INPUT */ struct tcpip_msg *msg; if (sys_mbox_valid(&mbox)) { msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_INPKT); if (msg == NULL) { return ERR_MEM; } msg->type = TCPIP_MSG_INPKT; #ifdef __ADSPBLACKFIN__ msg->flags = 0; #endif msg->msg.inp.p = p; msg->msg.inp.netif = inp; if (sys_mbox_trypost(&mbox, msg) != ERR_OK) { memp_free(MEMP_TCPIP_MSG_INPKT, msg); return ERR_MEM; } return ERR_OK; } return ERR_VAL; #endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */ }
// Passes the received forward to the appropriate handler void ethernet_recv_frame(char *buf, int len) { ethernet_header *head = (ethernet_header*)buf; dprintf("received frame of length %d\n", len); //printf("type: %02x%02x", head->ether_type[0], head->ether_type[1]); //if ( memcmp(ethernet_opt_address, head->dest_addr, 6) != 0 ) // return; // ARP if ( head->ether_type[0] == 0x08 && head->ether_type[1] == 0x06 ) { arp_recv(buf, len); } // IP else if ( head->ether_type[0] == 0x08 && head->ether_type[1] == 0x00 ) { // Pass over the IP packet without the ethernet header and checksum ip_input(buf+sizeof(ethernet_header), len-sizeof(ethernet_header)-4); } }
static void tcpip_thread(void *arg) { struct tcpip_msg *msg; ip_init(); udp_init(); tcp_init(); sys_timeout(TCP_TMR_INTERVAL, (sys_timeout_handler)tcpip_tcp_timer, NULL); if(tcpip_init_done != NULL) { tcpip_init_done(tcpip_init_done_arg); } while(1) { /* MAIN Loop */ sys_mbox_fetch(mbox, (void *)&msg); switch(msg->type) { case TCPIP_MSG_API: DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API message %p\n", msg)); api_msg_input(msg->msg.apimsg); break; case TCPIP_MSG_INPUT: DEBUGF(TCPIP_DEBUG, ("tcpip_thread: IP packet %p\n", msg)); ip_input(msg->msg.inp.p, msg->msg.inp.netif); break; case TCP_SHIM_MSG_INPUT: DEBUGF(TCPIP_DEBUG, ("tcpip_thread: TCP shim packet %p\n", msg)); tcp_input(msg->msg.inp.p, msg->msg.inp.netif); break; default: break; } memp_freep(MEMP_TCPIP_MSG, msg); } }
void ether_input(IO_Rec *recs, int nr_recs, Net_EtherAddr *mac, iphost_st *host_st) { struct ether_header *header; uint32_t m_flags=0; TRC(printf("flowman: in ether_input\n")); if (recs[0].base == NULL) { printf("flowman ether_input: header failure\n"); goto bad_ether; } if (recs[0].len < ETHER_HDR_LEN) { printf("flowman: ether_input: warning: short first IORec, " "ether hdr corrupted?\n"); goto bad_ether; } /* offset of 0 to get to ether header */ header = (struct ether_header *)recs[0].base; /* check multicast address */ if (header->ether_dhost[0] & 1) { goto bad_addr; /* XXX m_flags |= M_MCAST; printf("ethernet_input received multicast datagram\n"); ip = (struct ip *)(recs[0].base + sizeof(struct ether_header)); printf("addr: %x\n", ntohl(ip->ip_dst.s_addr)); goto for_us; too much overload at the moment */ } /* check ethernet host address */ if (memcmp(header->ether_dhost, mac, 6)) { TRC(unsigned char *p = header->ether_dhost); TRC(printf("flowman ether_input: warning: " "recvd packet with dest (%02x:%02x:%02x:%02x::%02x:%02x) " "!= my addr(%02x:%02x:%02x:%02x:%02x:%02x)!\n", p[0], p[1], p[2], p[3], p[4], p[5], mac->a[0], mac->a[1], mac->a[2], mac->a[3], mac->a[4], mac->a[5])); goto bad_addr; } /*for_us: wait for multicast stuff, then needed*/ /* check for types */ TRC(printf("ntoh16 header etherype: %x\n", ntoh16(header->ether_type))); switch (ntoh16(header->ether_type)) { case ETHERTYPE_IP: TRC(printf("flowman ether_input: OK, type IP\n")); TRC(printf("ether_input dest %x\n", header->ether_dhost)); TRC(printf("ether_input src %x\n", header->ether_shost)); ip_input(recs, nr_recs, host_st, m_flags); break; case ETHERTYPE_ARP: printf("flowman: ether_input Ethernet ARP type: can't happen!\n"); break; } return; bad_ether: printf("flowman: ether_input: error received packet\n"); return; bad_addr: /* packet not for us */ return; }
/** * The main lwIP thread. This thread has exclusive access to lwIP core functions * (unless access to them is not locked). Other threads communicate with this * thread using message boxes. * * It also starts all the timers to make sure they are running in the right * thread context. * * @param arg unused argument */ static void tcpip_thread(void *arg) { struct tcpip_msg *msg; LWIP_UNUSED_ARG(arg); #if IP_REASSEMBLY sys_timeout(IP_TMR_INTERVAL, ip_reass_timer, NULL); #endif /* IP_REASSEMBLY */ #if LWIP_ARP sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); #endif /* LWIP_ARP */ #if LWIP_DHCP sys_timeout(DHCP_COARSE_TIMER_MSECS, dhcp_timer_coarse, NULL); sys_timeout(DHCP_FINE_TIMER_MSECS, dhcp_timer_fine, NULL); #endif /* LWIP_DHCP */ #if LWIP_AUTOIP sys_timeout(AUTOIP_TMR_INTERVAL, autoip_timer, NULL); #endif /* LWIP_AUTOIP */ #if LWIP_IGMP sys_timeout(IGMP_TMR_INTERVAL, igmp_timer, NULL); #endif /* LWIP_IGMP */ #if LWIP_DNS sys_timeout(DNS_TMR_INTERVAL, dns_timer, NULL); #endif /* LWIP_DNS */ if (tcpip_init_done != NULL) { tcpip_init_done(tcpip_init_done_arg); } LOCK_TCPIP_CORE(); while (1) { /* MAIN Loop */ sys_mbox_fetch(mbox, (void *)&msg); // teset by pegasus //if (msg->msg.apimsg->msg.msg.w.dataptr == &htmldata) // acoral_print("\nhtmldata:\n");//*,msg->msg.apimsg->msg.msg.w.dataptr); switch (msg->type) { #if LWIP_NETCONN case TCPIP_MSG_API: //lwip_printf("\r\n1\r\n"); LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API message %p\n", (void *)msg)); msg->msg.apimsg->function(&(msg->msg.apimsg->msg)); //acoral_print("\r\n%x\r\n",msg->msg.apimsg->function); //acoral_print("MSG_API:%s",msg->msg.apimsg->msg.w.dataptr); break; #endif /* LWIP_NETCONN */ case TCPIP_MSG_INPKT: //lwip_printf("\r\n2\r\n"); LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: PACKET %p\n", (void *)msg)); #if LWIP_ARP if (msg->msg.inp.netif->flags & NETIF_FLAG_ETHARP) { ethernet_input(msg->msg.inp.p, msg->msg.inp.netif); } else #endif /* LWIP_ARP */ {//acoral_print("\nip_input:2==2\n"); ip_input(msg->msg.inp.p, msg->msg.inp.netif); } memp_free(MEMP_TCPIP_MSG_INPKT, msg); break; #if LWIP_NETIF_API case TCPIP_MSG_NETIFAPI: //lwip_printf("\r\n3\r\n"); LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: Netif API message %p\n", (void *)msg)); msg->msg.netifapimsg->function(&(msg->msg.netifapimsg->msg)); break; #endif /* LWIP_NETIF_API */ case TCPIP_MSG_CALLBACK: //lwip_printf("\r\n4\r\n"); LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK %p\n", (void *)msg)); msg->msg.cb.f(msg->msg.cb.ctx); memp_free(MEMP_TCPIP_MSG_API, msg); break; case TCPIP_MSG_TIMEOUT: //lwip_printf("\r\n5\r\n"); LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: TIMEOUT %p\n", (void *)msg)); if(msg->msg.tmo.msecs != 0xffffffff) sys_timeout (msg->msg.tmo.msecs, msg->msg.tmo.h, msg->msg.tmo.arg); else sys_untimeout (msg->msg.tmo.h, msg->msg.tmo.arg); memp_free(MEMP_TCPIP_MSG_API, msg); break; default: //lwip_printf("\r\n=======================\r\n"); pbuf_free(msg->msg.inp.p); break; } } }
/** * The main lwIP thread. This thread has exclusive access to lwIP core functions * (unless access to them is not locked). Other threads communicate with this * thread using message boxes. * * It also starts all the timers to make sure they are running in the right * thread context. * * @param arg unused argument */ static void tcpip_thread(void *arg) { struct tcpip_msg *msg; LWIP_UNUSED_ARG(arg); #if IP_REASSEMBLY sys_timeout(IP_TMR_INTERVAL, ip_reass_timer, NULL); #endif /* IP_REASSEMBLY */ #if LWIP_ARP sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); #endif /* LWIP_ARP */ #if LWIP_DHCP sys_timeout(DHCP_COARSE_TIMER_MSECS, dhcp_timer_coarse, NULL); sys_timeout(DHCP_FINE_TIMER_MSECS, dhcp_timer_fine, NULL); #endif /* LWIP_DHCP */ #if LWIP_AUTOIP sys_timeout(AUTOIP_TMR_INTERVAL, autoip_timer, NULL); #endif /* LWIP_AUTOIP */ #if LWIP_IGMP sys_timeout(IGMP_TMR_INTERVAL, igmp_timer, NULL); #endif /* LWIP_IGMP */ #if LWIP_DNS sys_timeout(DNS_TMR_INTERVAL, dns_timer, NULL); #endif /* LWIP_DNS */ if (tcpip_init_done != NULL) { tcpip_init_done(tcpip_init_done_arg); } LOCK_TCPIP_CORE(); while (1) { /* MAIN Loop */ sys_mbox_fetch(mbox, (void *)&msg); switch (msg->type) { #if LWIP_NETCONN case TCPIP_MSG_API: LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API message %p\n", (void *)msg)); msg->msg.apimsg->function(&(msg->msg.apimsg->msg)); break; #endif /* LWIP_NETCONN */ case TCPIP_MSG_INPKT: LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: PACKET %p\n", (void *)msg)); #if LWIP_ARP if (msg->msg.inp.netif->flags & NETIF_FLAG_ETHARP) { ethernet_input(msg->msg.inp.p, msg->msg.inp.netif); } else #endif /* LWIP_ARP */ { ip_input(msg->msg.inp.p, msg->msg.inp.netif); } memp_free(MEMP_TCPIP_MSG_INPKT, msg); break; #if LWIP_NETIF_API case TCPIP_MSG_NETIFAPI: LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: Netif API message %p\n", (void *)msg)); msg->msg.netifapimsg->function(&(msg->msg.netifapimsg->msg)); break; #endif /* LWIP_NETIF_API */ case TCPIP_MSG_CALLBACK: LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK %p\n", (void *)msg)); msg->msg.cb.f(msg->msg.cb.ctx); memp_free(MEMP_TCPIP_MSG_API, msg); break; case TCPIP_MSG_TIMEOUT: LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: TIMEOUT %p\n", (void *)msg)); sys_timeout(msg->msg.tmo.msecs, msg->msg.tmo.h, msg->msg.tmo.arg); memp_free(MEMP_TCPIP_MSG_API, msg); break; case TCPIP_MSG_UNTIMEOUT: LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: UNTIMEOUT %p\n", (void *)msg)); sys_untimeout(msg->msg.tmo.h, msg->msg.tmo.arg); memp_free(MEMP_TCPIP_MSG_API, msg); break; default: break; } } }
/** * The main lwIP thread. This thread has exclusive access to lwIP core functions * (unless access to them is not locked). Other threads communicate with this * thread using message boxes. * * It also starts all the timers to make sure they are running in the right * thread context. * * @param arg unused argument */ static void tcpip_thread(void *arg) { struct tcpip_msg *msg; LWIP_UNUSED_ARG(arg); if (tcpip_init_done != NULL) { tcpip_init_done(tcpip_init_done_arg); } LOCK_TCPIP_CORE(); while (1) { /* MAIN Loop */ UNLOCK_TCPIP_CORE(); LWIP_TCPIP_THREAD_ALIVE(); /* wait for a message, timeouts are processed while waiting */ sys_timeouts_mbox_fetch(&mbox, (void **)&msg); LOCK_TCPIP_CORE(); switch (msg->type) { #if LWIP_NETCONN case TCPIP_MSG_API: LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API message %p\n", (void *)msg)); msg->msg.apimsg->function(&(msg->msg.apimsg->msg)); break; #endif /* LWIP_NETCONN */ #if !LWIP_TCPIP_CORE_LOCKING_INPUT case TCPIP_MSG_INPKT: LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: PACKET %p\n", (void *)msg)); #if LWIP_ETHERNET if (msg->msg.inp.netif->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) { ethernet_input(msg->msg.inp.p, msg->msg.inp.netif); } else #endif /* LWIP_ETHERNET */ { ip_input(msg->msg.inp.p, msg->msg.inp.netif); } memp_free(MEMP_TCPIP_MSG_INPKT, msg); break; #endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */ #if LWIP_NETIF_API case TCPIP_MSG_NETIFAPI: LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: Netif API message %p\n", (void *)msg)); msg->msg.netifapimsg->function(&(msg->msg.netifapimsg->msg)); break; #endif /* LWIP_NETIF_API */ case TCPIP_MSG_CALLBACK: LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK %p\n", (void *)msg)); msg->msg.cb.function(msg->msg.cb.ctx); memp_free(MEMP_TCPIP_MSG_API, msg); break; #if LWIP_TCPIP_TIMEOUT case TCPIP_MSG_TIMEOUT: LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: TIMEOUT %p\n", (void *)msg)); sys_timeout(msg->msg.tmo.msecs, msg->msg.tmo.h, msg->msg.tmo.arg); memp_free(MEMP_TCPIP_MSG_API, msg); break; case TCPIP_MSG_UNTIMEOUT: LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: UNTIMEOUT %p\n", (void *)msg)); sys_untimeout(msg->msg.tmo.h, msg->msg.tmo.arg); memp_free(MEMP_TCPIP_MSG_API, msg); break; #endif /* LWIP_TCPIP_TIMEOUT */ default: LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: %d\n", msg->type)); LWIP_ASSERT("tcpip_thread: invalid message", 0); break; } } }
int ether_input(struct nm_if *nmif, int ring, char *buf, int len) { int err; struct ether_header *eh; struct ether_vlan_header *evl; struct nm_if_vlan *vlan; if (len < ETHER_HDR_LEN) { DPRINTF("%s: discarding packet, too short.\n", __func__); pktcnt.rx_drop++; return (-1); } err = 0; eh = (struct ether_header *)buf; switch (ntohs(eh->ether_type)) { case ETHERTYPE_ARP: pktcnt.rx_arp++; err = arp_input(nmif, ring, buf + ETHER_HDR_LEN, len - ETHER_HDR_LEN); break; case ETHERTYPE_IP: pktcnt.rx_ip++; err = ip_input(nmif, ring, buf + ETHER_HDR_LEN, len - ETHER_HDR_LEN); break; case ETHERTYPE_VLAN: //pktcnt.rx_vlan++; if (len < ETHER_VLAN_ENCAP_LEN) { DPRINTF("%s: discarding vlan packet, too short.\n", __func__); pktcnt.rx_drop++; return (-1); } evl = (struct ether_vlan_header *)buf; vlan = if_find_vlan(nmif, ntohs(evl->evl_tag)); if (vlan == NULL) { pktcnt.rx_drop++; DPRINTF("%s: unknown vlan tag %d, discanding packet.\n", __func__, ntohs(evl->evl_tag)); return (-1); } memmove(buf + ETHER_VLAN_ENCAP_LEN, buf, ETHER_ADDR_LEN * 2); err = ether_input(vlan->nmif, ring, buf + ETHER_VLAN_ENCAP_LEN, len - ETHER_VLAN_ENCAP_LEN); if (!nohostring && err == 1) { memmove(buf, buf + ETHER_VLAN_ENCAP_LEN, ETHER_ADDR_LEN * 2); evl = (struct ether_vlan_header *)buf; evl->evl_encap_proto = htons(ETHERTYPE_VLAN); evl->evl_tag = htons(vlan->nmif->nm_if_vtag); ether_bridge(vlan->nmif, ring, buf, len); return (0); } break; default: pktcnt.rx_drop++; DPRINTF("%s: protocol %#04x not supported, discanding packet.\n", __func__, ntohs(eh->ether_type)); err = -1; } return (err); }
/** * Send an IP packet to be received on the same netif (loopif-like). * The pbuf is simply copied and handed back to netif->input. * In multithreaded mode, this is done directly since netif->input must put * the packet on a queue. * In callback mode, the packet is put on an internal queue and is fed to * netif->input by if_poll(). * * @param netif the lwip network interface structure * @param p the (IP) packet to 'send' * @param ipaddr the ip address to send the packet to (not used) * @return ERR_OK if the packet has been sent * ERR_MEM if the pbuf used to copy the packet couldn't be allocated */ err_t netif_loop_output (struct interface *netif, struct pbuf *p, ip_addr_t * ipaddr) { struct pbuf *r; err_t err; //struct pbuf *last; #if LWIP_LOOPBACK_MAX_PBUFS u8_t clen = 0; #endif /* LWIP_LOOPBACK_MAX_PBUFS */ /* If we have a loopif, SNMP counters are adjusted for it, * if not they are adjusted for 'netif'. */ #if LWIP_SNMP #if LWIP_HAVE_LOOPIF struct interface *stats_if = &loop_if; #else /* LWIP_HAVE_LOOPIF */ struct interface *stats_if = netif; #endif /* LWIP_HAVE_LOOPIF */ #endif /* LWIP_SNMP */ SYS_ARCH_DECL_PROTECT (lev); LWIP_UNUSED_ARG (ipaddr); /* Allocate a new pbuf */ r = pbuf_alloc (PBUF_LINK, p->tot_len, PBUF_RAM); if (r == NULL) { LINK_STATS_INC (link.memerr); LINK_STATS_INC (link.drop); #ifdef CONFIG_OPENSWITCH_TCP_IP snmp_inc_ifoutdiscards (stats_if); #endif return ERR_MEM; } #if 0 #if LWIP_LOOPBACK_MAX_PBUFS clen = pbuf_clen (r); /* check for overflow or too many pbuf on queue */ if (((netif->loop_cnt_current + clen) < netif->loop_cnt_current) || ((netif->loop_cnt_current + clen) > LWIP_LOOPBACK_MAX_PBUFS)) { pbuf_free (r); LINK_STATS_INC (link.memerr); LINK_STATS_INC (link.drop); snmp_inc_ifoutdiscards (stats_if); return ERR_MEM; } netif->loop_cnt_current += clen; #endif /* LWIP_LOOPBACK_MAX_PBUFS */ #endif /* Copy the whole pbuf queue p into the single pbuf r */ if ((err = pbuf_copy (r, p)) != ERR_OK) { pbuf_free (r); LINK_STATS_INC (link.memerr); LINK_STATS_INC (link.drop); #ifdef CONFIG_OPENSWITCH_TCP_IP snmp_inc_ifoutdiscards (stats_if); #endif return err; } #ifdef CONFIG_OPENSWITCH_TCP_IP /* loopback packets are always IP packets! */ if (ip_input (r, netif) != ERR_OK) { pbuf_free (r); } #else #endif #if 0 /* Put the packet on a linked list which gets emptied through calling if_poll(). */ /* let last point to the last pbuf in chain r */ for (last = r; last->next != NULL; last = last->next); SYS_ARCH_PROTECT (lev); if (netif->loop_first != NULL) { LWIP_ASSERT ("if first != NULL, last must also be != NULL", netif->loop_last != NULL); netif->loop_last->next = r; netif->loop_last = last; } else { netif->loop_first = r; netif->loop_last = last; } SYS_ARCH_UNPROTECT (lev); #endif LINK_STATS_INC (link.xmit); #ifdef CONFIG_OPENSWITCH_TCP_IP snmp_add_ifoutoctets (stats_if, p->tot_len); snmp_inc_ifoutucastpkts (stats_if); #endif #if 0 #if LWIP_NETIF_LOOPBACK_MULTITHREADING /* For multithreading environment, schedule a call to if_poll */ tcpip_callback ((tcpip_callback_fn) if_poll, netif); #endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */ #endif return ERR_OK; }