public Nucleus(IKernel kernel, int sysTmrIntNo, TMO sysTmrIntv) { m_Kernel = kernel; m_SysTmrIntNo = sysTmrIntNo; m_SysTmrIntv = sysTmrIntv; m_rsys.sysstat = SYSSTAT.TTS_INDP; for (int i = 0; i < m_ReadyQueue.Length; i++) m_ReadyQueue[i] = new LinkedList<Task>(); m_SysTime.Value = 0; m_CurrentTask = null; m_lwIP = new lwip(ip_output); #if LWIP_STATS stats.stats_init(); #endif sys.sys_init(m_lwIP, this); m_lwIP.mem_init(); lwip.memp_init(); pbuf.pbuf_init(m_lwIP); udp.udp_init(m_lwIP); tcp.tcp_init(m_lwIP); }
public Nucleus(IKernel kernel, int sysTmrIntNo, TMO sysTmrIntv) { m_Kernel = kernel; m_SysTmrIntNo = sysTmrIntNo; m_SysTmrIntv = sysTmrIntv; m_rsys.sysstat = SYSSTAT.TTS_INDP; for (int i = 0; i < m_ReadyQueue.Length; i++) { m_ReadyQueue[i] = new LinkedList <Task>(); } m_SysTime.Value = 0; m_CurrentTask = null; m_lwIP = new lwip(ip_output); #if LWIP_STATS stats.stats_init(); #endif sys.sys_init(m_lwIP, this); m_lwIP.mem_init(); lwip.memp_init(); pbuf.pbuf_init(m_lwIP); udp.udp_init(m_lwIP); tcp.tcp_init(m_lwIP); }
public TcpRep(ID tcpid, ref T_TCP_CREP pk_ctcp, Nucleus pNucleus, lwip lwip) { m_RepID = tcpid; m_ctcp = pk_ctcp; m_Nucleus = pNucleus; m_lwIP = lwip; }
internal err_t output(lwip ip, pbuf p, ip_addr src, ip_addr dest, byte ttl, byte tos, byte proto) { int pos = 0, rest = p.tot_len; byte[] packet = new byte[rest]; ip_addr srch = new ip_addr(lwip_ntohl(src.addr)); ip_addr desth = new ip_addr(lwip_ntohl(dest.addr)); for (pbuf q = p; q != null; q = q.next) { int len = rest; if (len > q.len) { len = q.len; } Buffer.BlockCopy(q.payload.data, q.payload.offset, packet, pos, len); pos += len; rest -= len; } m_output(ip, packet, srch, desth, proto); return(err_t.ERR_OK); }
private mem(lwip lwip, byte[] buffer, int offset) : base(buffer, offset) { this.lwip = lwip; _next = new pointer(buffer, offset + 0); _prev = new pointer(buffer, offset + 4); _used = new pointer(buffer, offset + 8); }
private void ip_output(lwip netif, byte[] packet, ip_addr src, ip_addr dest, byte proto) { if (m_IPPacketBridge == null) { return; } byte[] data = Itron.GetIp4Packet(new pointer(packet, 0), packet.Length, src, dest, proto); m_IPPacketBridge.OutputData(data); }
public TcpCep(ID tcpid, ref T_TCP_CCEP pk_ctcp, Nucleus pNucleus, lwip lwip) { m_CepID = tcpid; m_ctcp = pk_ctcp; m_Nucleus = pNucleus; m_lwIP = lwip; m_Pcb = m_lwIP.tcp.tcp_new(); tcp.tcp_arg(m_Pcb, this); tcp.tcp_err(m_Pcb, Error); }
public Udp6Cep(ID udpid, ref T_UDP6_CCEP pk_cudp, Nucleus pNucleus, lwip lwip) { m_CepID = udpid; m_cudp = pk_cudp; m_Nucleus = pNucleus; m_lwIP = lwip; ip6_addr addr = new ip6_addr(pk_cudp.myaddr.ipaddr); m_Pcb = m_lwIP.udp.udp_new(); //m_lwIP.udp.udp_bind(m_Pcb, addr, pk_cudp.myaddr.portno); //udp.udp_recv(m_Pcb, recv, this); }
/** * Determine if an address is a broadcast address on a network interface * * @param addr address to be checked * @param netif the network interface against which the address is checked * @return returns non-zero if the address is a broadcast address */ public static bool ip4_addr_isbroadcast(uint addr, lwip netif) { ip_addr ipaddr = new ip_addr(0); ip_addr.ip4_addr_set_u32(ipaddr, addr); /* all ones (broadcast) or all zeroes (old skool broadcast) */ if ((~addr == IPADDR_ANY) || (addr == IPADDR_ANY)) { return(true); /* no broadcast support on this network interface? */ } else if ((netif.flags & lwip.NETIF_FLAG_BROADCAST) == 0) { /* the given address cannot be a broadcast address * nor can we check against any broadcast addresses */ return(false); /* address matches network interface address exactly? => no broadcast */ } else if (addr == ip_addr.ip4_addr_get_u32(netif.ip_addr)) { return(false); /* on the same (sub) network... */ } else if (ip_addr.ip_addr_netcmp(ipaddr, netif.ip_addr, netif.netmask) /* ...and host identifier bits are all ones? =>... */ && ((addr & ~ip_addr.ip4_addr_get_u32(netif.netmask)) == (IPADDR_BROADCAST & ~ip_addr.ip4_addr_get_u32(netif.netmask)))) { /* => network broadcast address */ return(true); } else { return(false); } }
public udp_pcb(lwip lwip) : base(lwip) { }
public sys(lwip lwip, Nucleus nucleus) { this.lwip = lwip; m_Nucleus = nucleus; }
public tcp_state state; /* TCP state */ #endregion Fields #region Constructors public tcp_pcb_common(lwip lwip) : base(lwip) { }
internal err_t output(lwip ip, pbuf p, ip_addr src, ip_addr dest, byte ttl, byte tos, byte proto) { int pos = 0, rest = p.tot_len; byte[] packet = new byte[rest]; ip_addr srch = new ip_addr(lwip_ntohl(src.addr)); ip_addr desth = new ip_addr(lwip_ntohl(dest.addr)); for (pbuf q = p; q != null; q = q.next) { int len = rest; if (len > q.len) len = q.len; Buffer.BlockCopy(q.payload.data, q.payload.offset, packet, pos, len); pos += len; rest -= len; } m_output(ip, packet, srch, desth, proto); return err_t.ERR_OK; }
public pbuf(lwip lwip, byte[] data) : this(lwip, data, 0) { }
/** * The initial input processing of TCP. It verifies the TCP header, demultiplexes * the segment between the PCBs and passes it on to tcp_process(), which implements * the TCP finite state machine. This function is called by the IP layer (in * ip_input()). * * @param p received TCP segment to process (p.payload pointing to the IP header) * @param inp network interface on which this segment was received */ public void tcp_input(pbuf p, lwip inp) { tcp_pcb pcb, prev; tcp_pcb_listen lpcb; #if SO_REUSE tcp_pcb_listen lpcb_prev = null; tcp_pcb_listen lpcb_any = null; #endif // SO_REUSE byte hdrlen; err_t err; //PERF_START; ++lwip.lwip_stats.tcp.recv; ////snmp.snmp_inc_tcpinsegs(); tcphdr = new tcp_hdr(p.payload); #if TCP_INPUT_DEBUG tcp_debug_print(tcphdr); #endif /* Don't even process incoming broadcasts/multicasts. */ if (ip_addr.ip_addr_isbroadcast(lwip.current_iphdr_dest, inp) || ip_addr.ip_addr_ismulticast(lwip.current_iphdr_dest)) { ++lwip.lwip_stats.tcp.proterr; goto dropped; } #if CHECKSUM_CHECK_TCP /* Verify TCP checksum. */ if (lwip.inet_chksum_pseudo(p, lwip.ip_current_src_addr(), lwip.ip_current_dest_addr(), lwip.IP_PROTO_TCP, p.tot_len) != 0) { lwip.LWIP_DEBUGF(opt.TCP_INPUT_DEBUG, "tcp_input: packet discarded due to failing checksum 0x{0:X4}\n", lwip.inet_chksum_pseudo(p, lwip.ip_current_src_addr(), lwip.ip_current_dest_addr(), lwip.IP_PROTO_TCP, p.tot_len)); #if TCP_DEBUG tcp_debug_print(tcphdr); #endif // TCP_DEBUG ++lwip.lwip_stats.tcp.chkerr; goto dropped; } #endif /* Move the payload pointer in the pbuf so that it points to the TCP data instead of the TCP header. */ hdrlen = (byte)tcp_hdr.TCPH_HDRLEN(tcphdr); if (lwip.pbuf_header(p, (short)-(hdrlen * 4)) != 0) { /* drop short packets */ lwip.LWIP_DEBUGF(opt.TCP_INPUT_DEBUG, "tcp_input: short packet\n"); ++lwip.lwip_stats.tcp.lenerr; goto dropped; } /* Convert fields in TCP header to host byte order. */ tcphdr.src = lwip.lwip_ntohs(tcphdr.src); tcphdr.dest = lwip.lwip_ntohs(tcphdr.dest); seqno = tcphdr.seqno = lwip.lwip_ntohl(tcphdr.seqno); ackno = tcphdr.ackno = lwip.lwip_ntohl(tcphdr.ackno); tcphdr.wnd = lwip.lwip_ntohs(tcphdr.wnd); flags = tcp_hdr.TCPH_FLAGS(tcphdr); tcplen = (ushort)(p.tot_len + (((flags & (tcp.TCP_FIN | tcp.TCP_SYN)) != 0) ? 1 : 0)); /* Demultiplex an incoming segment. First, we check if it is destined for an active connection. */ prev = null; for (pcb = tcp_active_pcbs; pcb != null; pcb = (tcp_pcb)pcb.next) { lwip.LWIP_ASSERT("tcp_input: active pcb.state != tcp_state.CLOSED", pcb.state != tcp_state.CLOSED); lwip.LWIP_ASSERT("tcp_input: active pcb.state != TIME-WAIT", pcb.state != tcp_state.TIME_WAIT); lwip.LWIP_ASSERT("tcp_input: active pcb.state != tcp_state.LISTEN", pcb.state != tcp_state.LISTEN); if (pcb.remote_port == tcphdr.src && pcb.local_port == tcphdr.dest && ip_addr.ip_addr_cmp(pcb.remote_ip, lwip.current_iphdr_src) && ip_addr.ip_addr_cmp(pcb.local_ip, lwip.current_iphdr_dest)) { /* Move this PCB to the front of the list so that subsequent lookups will be faster (we exploit locality in TCP segment arrivals). */ lwip.LWIP_ASSERT("tcp_input: pcb.next != pcb (before cache)", pcb.next != pcb); if (prev != null) { prev.next = pcb.next; pcb.next = tcp_active_pcbs; tcp_active_pcbs = pcb; } lwip.LWIP_ASSERT("tcp_input: pcb.next != pcb (after cache)", pcb.next != pcb); break; } prev = pcb; } if (pcb == null) { /* If it did not go to an active connection, we check the connections in the TIME-WAIT state. */ for (pcb = tcp_tw_pcbs; pcb != null; pcb = (tcp_pcb)pcb.next) { lwip.LWIP_ASSERT("tcp_input: TIME-WAIT pcb.state == TIME-WAIT", pcb.state == tcp_state.TIME_WAIT); if (pcb.remote_port == tcphdr.src && pcb.local_port == tcphdr.dest && ip_addr.ip_addr_cmp(pcb.remote_ip, lwip.current_iphdr_src) && ip_addr.ip_addr_cmp(pcb.local_ip, lwip.current_iphdr_dest)) { /* We don't really care enough to move this PCB to the front of the list since we are not very likely to receive that many segments for connections in TIME-WAIT. */ lwip.LWIP_DEBUGF(opt.TCP_INPUT_DEBUG, "tcp_input: packed for tcp_state.TIME_WAITing connection.\n"); tcp_timewait_input(pcb); lwip.pbuf_free(p); return; } } /* Finally, if we still did not get a match, we check all PCBs that are tcp_state.LISTENing for incoming connections. */ tcp_pcb_listen lprev = null; for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != null; lpcb = (tcp_pcb_listen)lpcb.next) { if (lpcb.local_port == tcphdr.dest) { #if SO_REUSE if (ip_addr.ip_addr_cmp(lpcb.local_ip, lwip.current_iphdr_dest)) { /* found an exact match */ break; } else if (ip_addr.ip_addr_isany(lpcb.local_ip)) { /* found an ANY-match */ lpcb_any = lpcb; lpcb_prev = lprev; } #else // SO_REUSE if (ip_addr.ip_addr_cmp(lpcb.local_ip, lwip.current_iphdr_dest) || ip_addr.ip_addr_isany(lpcb.local_ip)) { /* found a match */ break; } #endif // SO_REUSE } lprev = lpcb; } #if SO_REUSE /* first try specific local IP */ if (lpcb == null) { /* only pass to ANY if no specific local IP has been found */ lpcb = lpcb_any; lprev = lpcb_prev; } #endif // SO_REUSE if (lpcb != null) { /* Move this PCB to the front of the list so that subsequent lookups will be faster (we exploit locality in TCP segment arrivals). */ if (lprev != null) { ((tcp_pcb_listen)lprev).next = lpcb.next; /* our successor is the remainder of the listening list */ lpcb.next = tcp_listen_pcbs.listen_pcbs; /* put this listening pcb at the head of the listening list */ tcp_listen_pcbs.listen_pcbs = lpcb; } lwip.LWIP_DEBUGF(opt.TCP_INPUT_DEBUG, "tcp_input: packed for tcp_state.LISTENing connection.\n"); tcp_listen_input(lpcb); lwip.pbuf_free(p); return; } } #if TCP_INPUT_DEBUG lwip.LWIP_DEBUGF(opt.TCP_INPUT_DEBUG, "+-+-+-+-+-+-+-+-+-+-+-+-+-+- tcp_input: flags "); tcp_debug_print_flags(tcp_hdr.TCPH_FLAGS(tcphdr)); lwip.LWIP_DEBUGF(opt.TCP_INPUT_DEBUG, "-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n"); #endif // TCP_INPUT_DEBUG if (pcb != null) { /* The incoming segment belongs to a connection. */ #if TCP_INPUT_DEBUG #if TCP_DEBUG tcp_debug_print_state(pcb.state); #endif // TCP_DEBUG #endif // TCP_INPUT_DEBUG /* Set up a tcp_seg structure. */ inseg.next = null; inseg.len = p.tot_len; inseg.p = p; inseg.tcphdr = tcphdr; recv_data = null; recv_flags = 0; if ((flags & tcp.TCP_PSH) != 0) { p.flags |= pbuf.PBUF_FLAG_PUSH; } /* If there is data which was previously "refused" by upper layer */ if (pcb.refused_data != null) { if ((tcp_process_refused_data(pcb) == err_t.ERR_ABRT) || ((pcb.refused_data != null) && (tcplen > 0))) { /* pcb has been aborted or refused data is still refused and the new segment contains data */ ++lwip.lwip_stats.tcp.drop; //snmp.snmp_inc_tcpinerrs(); goto aborted; } } tcp_input_pcb = pcb; err = tcp_process(pcb); /* A return value of err_t.ERR_ABRT means that tcp.tcp_abort() was called and that the pcb has been freed. If so, we don't do anything. */ if (err != err_t.ERR_ABRT) { if ((recv_flags & tcp.TF_RESET) != 0) { /* TF_RESET means that the connection was reset by the other end. We then call the error callback to inform the application that the connection is dead before we deallocate the PCB. */ TCP_EVENT_ERR(pcb.errf, pcb.callback_arg, err_t.ERR_RST); tcp_pcb_remove(tcp_active_pcbs, pcb); lwip.memp_free(memp_t.MEMP_TCP_PCB, pcb); } else if ((recv_flags & tcp.TF_CLOSED) != 0) { /* The connection has been closed and we will deallocate the PCB. */ if ((pcb.flags & tcp_pcb.TF_RXCLOSED) == 0) { /* Connection closed although the application has only shut down the tx side: call the PCB's err callback and indicate the closure to ensure the application doesn't continue using the PCB. */ TCP_EVENT_ERR(pcb.errf, pcb.callback_arg, err_t.ERR_CLSD); } tcp_pcb_remove(tcp_active_pcbs, pcb); lwip.memp_free(memp_t.MEMP_TCP_PCB, pcb); } else { err = err_t.ERR_OK; /* If the application has registered a "sent" function to be called when new send buffer space is available, we call it now. */ if (pcb.acked > 0) { TCP_EVENT_SENT(pcb, pcb.acked, out err); if (err == err_t.ERR_ABRT) { goto aborted; } } if (recv_data != null) { lwip.LWIP_ASSERT("pcb.refused_data == null", pcb.refused_data == null); if ((pcb.flags & tcp_pcb.TF_RXCLOSED) != 0) { /* received data although already closed . abort (send RST) to notify the remote host that not all data has been processed */ lwip.pbuf_free(recv_data); tcp_abort(pcb); goto aborted; } /* Notify application that data has been received. */ TCP_EVENT_RECV(pcb, recv_data, err_t.ERR_OK, out err); if (err == err_t.ERR_ABRT) { goto aborted; } /* If the upper layer can't receive this data, store it */ if (err != err_t.ERR_OK) { pcb.refused_data = recv_data; lwip.LWIP_DEBUGF(opt.TCP_INPUT_DEBUG, "tcp_input: keep incoming packet, because pcb is \"full\"\n"); } } /* If a FIN segment was received, we call the callback function with a null buffer to indicate EOF. */ if ((recv_flags & TF_GOT_FIN) != 0) { if (pcb.refused_data != null) { /* Delay this if we have refused data. */ pcb.refused_data.flags |= pbuf.PBUF_FLAG_TCP_FIN; } else { /* correct rcv_wnd as the application won't call tcp_recved() for the FIN's seqno */ if (pcb.rcv_wnd != opt.TCP_WND) { pcb.rcv_wnd++; } TCP_EVENT_CLOSED(pcb, out err); if (err == err_t.ERR_ABRT) { goto aborted; } } } tcp_input_pcb = null; /* Try to send something out. */ tcp_output(pcb); #if TCP_INPUT_DEBUG #if TCP_DEBUG tcp_debug_print_state(pcb.state); #endif // TCP_DEBUG #endif // TCP_INPUT_DEBUG } } /* Jump target if pcb has been aborted in a callback (by calling tcp.tcp_abort()). Below this line, 'pcb' may not be dereferenced! */ aborted: tcp_input_pcb = null; recv_data = null; /* give up our reference to inseg.p */ if (inseg.p != null) { lwip.pbuf_free(inseg.p); inseg.p = null; } } else { /* If no matching PCB was found, send a TCP RST (reset) to the sender. */ lwip.LWIP_DEBUGF(opt.TCP_RST_DEBUG, "tcp_input: no PCB match found, resetting.\n"); if ((tcp_hdr.TCPH_FLAGS(tcphdr) & tcp.TCP_RST) == 0) { ++lwip.lwip_stats.tcp.proterr; ++lwip.lwip_stats.tcp.drop; tcp_rst(ackno, seqno + tcplen, lwip.ip_current_dest_addr(), lwip.ip_current_src_addr(), tcphdr.dest, tcphdr.src); } lwip.pbuf_free(p); } lwip.LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane() != 0); //PERF_STOP("tcp_input"); return; dropped: ++lwip.lwip_stats.tcp.drop; //snmp.snmp_inc_tcpinerrs(); lwip.pbuf_free(p); }
public tcp_hdr tcphdr; /* the TCP header */ #endregion Fields #region Constructors public tcp_seg(lwip lwip) : base(lwip) { }
public mem(lwip lwip, pointer buffer) : this(lwip, buffer.data, buffer.offset) { }
public static bool ip_addr_isbroadcast(ip_addr ipaddr, lwip netif) { return(ip_addr.ip4_addr_isbroadcast(ipaddr.addr, netif)); }
public memp(lwip lwip) { this.lwip = lwip; }
public udp(lwip lwip) { this.lwip = lwip; }
public tcp_pcb_listen(lwip lwip) : base(lwip) { }
/** * Determine if an address is a broadcast address on a network interface * * @param addr address to be checked * @param netif the network interface against which the address is checked * @return returns non-zero if the address is a broadcast address */ public static bool ip4_addr_isbroadcast(uint addr, lwip netif) { ip_addr ipaddr = new ip_addr(0); ip_addr.ip4_addr_set_u32(ipaddr, addr); /* all ones (broadcast) or all zeroes (old skool broadcast) */ if ((~addr == IPADDR_ANY) || (addr == IPADDR_ANY)) { return true; /* no broadcast support on this network interface? */ } else if ((netif.flags & lwip.NETIF_FLAG_BROADCAST) == 0) { /* the given address cannot be a broadcast address * nor can we check against any broadcast addresses */ return false; /* address matches network interface address exactly? => no broadcast */ } else if (addr == ip_addr.ip4_addr_get_u32(netif.ip_addr)) { return false; /* on the same (sub) network... */ } else if (ip_addr.ip_addr_netcmp(ipaddr, netif.ip_addr, netif.netmask) /* ...and host identifier bits are all ones? =>... */ && ((addr & ~ip_addr.ip4_addr_get_u32(netif.netmask)) == (IPADDR_BROADCAST & ~ip_addr.ip4_addr_get_u32(netif.netmask)))) { /* => network broadcast address */ return true; } else { return false; } }
public tcp_seg(lwip lwip) : base(lwip) { }
public tcp(lwip lwip) { this.lwip = lwip; inseg = new tcp_seg(lwip); tcp_pcb_lists = new tcp_pcb_common[]{ tcp_listen_pcbs.pcbs, tcp_bound_pcbs, tcp_active_pcbs, tcp_tw_pcbs}; }
public pbuf(lwip lwip, pointer data) : this(lwip, data.data, data.offset) { }
private void ip_output(lwip netif, byte[] packet, ip_addr src, ip_addr dest, byte proto) { if (m_IPPacketBridge == null) return; byte[] data = Itron.GetIp4Packet(new pointer(packet, 0), packet.Length, src, dest, proto); m_IPPacketBridge.OutputData(data); }
internal static void sys_init(lwip lwip, Nucleus nucleus) { lwip.sys = new sys(lwip, nucleus); }
public ip_pcb(lwip lwip) : base(lwip) { }
/* Initializes the pbuf module. This call is empty for now, but may not be in future. */ public static void pbuf_init(lwip lwip) { }
public pbuf(lwip lwip, byte[] data, int offset) : base(data, offset) { this.lwip = lwip; }
public tcp_seg unsent; /* Unsent (queued) segments. */ #endregion Fields #region Constructors public tcp_pcb(lwip lwip) : base(lwip) { }
public static bool ip_addr_isbroadcast(ip_addr ipaddr, lwip netif) { return ip_addr.ip4_addr_isbroadcast(ipaddr.addr, netif); }
public sys_timeo(lwip lwip) : base(lwip) { }