/** * Calculate a checksum over a chain of pbufs (without pseudo-header, much like * lwip.inet_chksum only pbufs are used). * * @param p pbuf chain over that the checksum should be calculated * @return checksum (as ushort) to be saved directly in the protocol header */ public static ushort inet_chksum_pbuf(pbuf p) { uint acc; pbuf q; byte swapped; acc = 0; swapped = 0; for (q = p; q != null; q = q.next) { acc += LWIP_CHKSUM(q.payload, q.len); acc = FOLD_U32T(acc); if (q.len % 2 != 0) { swapped = (byte)(1 - swapped); acc = SWAP_BYTES_IN_WORD((ushort)acc); } } if (swapped != 0) { acc = SWAP_BYTES_IN_WORD((ushort)acc); } return((ushort)~(acc & 0xffffUL)); }
internal void input(pointer packet, int length, ip_addr srcn, ip_addr destn, byte proto) { ip_addr src = new ip_addr(lwip.lwip_htonl(srcn.addr)); ip_addr dest = new ip_addr(lwip.lwip_htonl(destn.addr)); pbuf p = pbuf_alloc(pbuf_layer.PBUF_RAW, (ushort)length, pbuf_type.PBUF_POOL); int pos = 0, rest = length; for (pbuf q = p; q != null; q = q.next) { int len = rest; if (len > q.len) { len = q.len; } pointer.memcpy(q.payload, new pointer(packet, pos), len); pos += len; rest -= len; } if (ip_input(p, src, dest, proto) != err_t.ERR_OK) { pbuf_free(p); } }
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); }
internal void input(byte[] packet, ip_addr srcn, ip_addr destn, byte proto) { ip_addr src = new ip_addr(lwip.lwip_htonl(srcn.addr)); ip_addr dest = new ip_addr(lwip.lwip_htonl(destn.addr)); pbuf p = lwip.pbuf_alloc(pbuf_layer.PBUF_RAW, (ushort)packet.Length, pbuf_type.PBUF_POOL); int pos = 0, rest = packet.Length; for (pbuf q = p; q != null; q = q.next) { int len = rest; if (len > q.len) { len = q.len; } Buffer.BlockCopy(packet, pos, q.payload.data, q.payload.offset, len); pos += len; rest -= len; } if (lwip.ip.ip_input(p, src, dest, proto, this) != err_t.ERR_OK) { lwip.pbuf_free(p); } }
public ER NetworkToHost(pbuf pk_data) { if (pk_data == null) { return(ER.E_PAR); } m_lwIP.pbuf_ref(pk_data); m_RecvDataQueue.Enqueue(pk_data); if (m_RecvTaskQueue.First != null) { Task task = m_RecvTaskQueue.First.Value; m_RecvTaskQueue.RemoveFirst(); if (!task.ReleaseWait()) { return(ER.E_RLWAI); } } else { m_ctcp.callback(m_CepID, FN.TFN_TCP_RCV_DAT, null); } return(ER.E_OK); }
/** * Simple interface to ip_output_if. It finds the outgoing network * interface and calls upon ip_output_if to do the actual work. * * @param p the packet to send (p.payload points to the data, e.g. next * protocol header; if dest == ip.IP_HDRINCL, p already includes an IP * header and p.payload points to that IP header) * @param src the source IP address to send from (if src == IP_ADDR_ANY, the * IP address of the netif used to send is used as source address) * @param dest the destination IP address to send the packet to * @param ttl the TTL value to be set in the IP header * @param tos the TOS value to be set in the IP header * @param proto the PROTOCOL to be set in the IP header * * @return err_t.ERR_RTE if no route is found * see ip_output_if() for more return values */ public err_t ip_output(pbuf p, ip_addr src, ip_addr dest, byte ttl, byte tos, byte proto) { /* pbufs passed to IP must have a @ref-count of 1 as their payload pointer * gets altered as the packet is passed down the stack */ lwip.LWIP_ASSERT("p.ref == 1", p.@ref == 1); return(ip_output_if(p, src, dest, ttl, tos, proto)); }
/* lwip.inet_chksum_pseudo: * * Calculates the pseudo Internet checksum used by TCP and UDP for a pbuf chain. * IP addresses are expected to be in network byte order. * * @param p chain of pbufs over that a checksum should be calculated (ip data part) * @param src source ip address (used for checksum of pseudo header) * @param dst destination ip address (used for checksum of pseudo header) * @param proto ip protocol (used for checksum of pseudo header) * @param proto_len length of the ip data part (used for checksum of pseudo header) * @return checksum (as ushort) to be saved directly in the protocol header */ public static ushort inet_chksum_pseudo_partial(pbuf p, ip_addr src, ip_addr dest, byte proto, ushort proto_len, ushort chksum_len) { uint acc; uint addr; pbuf q; byte swapped; ushort chklen; acc = 0; swapped = 0; /* iterate through all pbuf in chain */ for (q = p; (q != null) && (chksum_len > 0); q = q.next) { lwip.LWIP_DEBUGF(opt.INET_DEBUG, "inet_chksum_pseudo(): checksumming pbuf {0} (has next {1}) \n", q, q.next); chklen = q.len; if (chklen > chksum_len) { chklen = chksum_len; } acc += LWIP_CHKSUM(q.payload, chklen); chksum_len -= chklen; lwip.LWIP_ASSERT("delete me", chksum_len < 0x7fff); /*lwip.LWIP_DEBUGF(opt.INET_DEBUG, "inet_chksum_pseudo(): unwrapped lwip_chksum()={0} \n", acc);*/ /* fold the upper bit down */ acc = FOLD_U32T(acc); if (q.len % 2 != 0) { swapped = (byte)(1 - swapped); acc = SWAP_BYTES_IN_WORD((ushort)acc); } /*lwip.LWIP_DEBUGF(opt.INET_DEBUG, "inet_chksum_pseudo(): wrapped lwip_chksum()={0} \n", acc);*/ } if (swapped != 0) { acc = SWAP_BYTES_IN_WORD((ushort)acc); } addr = ip_addr.ip4_addr_get_u32(src); acc += (addr & 0xffffU); acc += ((addr >> 16) & 0xffffU); addr = ip_addr.ip4_addr_get_u32(dest); acc += (addr & 0xffffU); acc += ((addr >> 16) & 0xffffU); acc += (uint)lwip.lwip_htons((ushort)proto); acc += (uint)lwip.lwip_htons(proto_len); /* Fold 32-bit sum to 16 bits * calling this twice is propably faster than if statements... */ acc = FOLD_U32T(acc); acc = FOLD_U32T(acc); lwip.LWIP_DEBUGF(opt.INET_DEBUG, "inet_chksum_pseudo(): pbuf chain lwip_chksum()={0}\n", acc); return((ushort)~(acc & 0xffffUL)); }
private int CopyRecvData(pointer p_data, int len) { int spos = 0, rest = len; int dpos = m_RecvPos; pbuf buf = m_RecvPBuf; pbuf p = m_RecvPBufPos, q; do { for (q = p; q != null; q = q.next, dpos = 0) { int tmp = dpos + rest; if (tmp > q.len) { tmp = q.len; } tmp -= dpos; pointer.memcpy(p_data + spos, q.payload + dpos, tmp); spos += tmp; dpos += tmp; rest -= tmp; if (rest == 0) { if (dpos == q.len) { q = q.next; dpos = 0; if (q == null) { if (buf != null) { m_lwIP.pbuf_free(buf); } buf = p = (m_RecvDataQueue.Count > 0) ? m_RecvDataQueue.Dequeue() : null; } } goto end; } } if (buf != null) { m_lwIP.pbuf_free(buf); } buf = p = (m_RecvDataQueue.Count > 0) ? m_RecvDataQueue.Dequeue() : null; } while (p != null); end: m_RecvPBuf = buf; m_RecvPBufPos = p; m_RecvPos = dpos; return(spos); }
public static ushort inet6_chksum_pseudo(pbuf p, ip6_addr src, ip6_addr dest, byte proto, ushort proto_len) { uint acc; pbuf q; byte swapped; acc = 0; swapped = 0; /* iterate through all pbuf in chain */ for (q = p; q != null; q = q.next) { lwip.LWIP_DEBUGF(opt.INET_DEBUG, "_inet_chksum.inet_chksum_pseudo(): checksumming pbuf {0} (has next {1}) \n", q.GetHashCode(), q.next == null ? 0 : q.next.GetHashCode()); acc += LWIP_CHKSUM(q, q.len); /*lwip.LWIP_DEBUGF(opt.INET_DEBUG, "_inet_chksum.inet_chksum_pseudo(): unwrapped lwip_chksum()={0} \n", acc);*/ /* just executing this next line is probably faster that the if statement needed * to check whether we really need to execute it, and does no harm */ acc = FOLD_U32T(acc); if (q.len % 2 != 0) { swapped = (byte)(1 - swapped); acc = SWAP_BYTES_IN_WORD((ushort)acc); } /*lwip.LWIP_DEBUGF(opt.INET_DEBUG, "_inet_chksum.inet_chksum_pseudo(): wrapped lwip_chksum()={0} \n", acc);*/ } if (swapped != 0) { acc = SWAP_BYTES_IN_WORD((ushort)acc); } for (int i = 0; i < 8; i++) { acc += lwip_htons(src.saddr[i]); acc += lwip_htons(dest.saddr[i]); while ((acc >> 16) != 0) { acc = (acc & 0xffff) + (acc >> 16); } } acc += (uint)lwip_htons((ushort)proto); acc += (uint)lwip_htons(proto_len); /* Fold 32-bit sum to 16 bits * calling this twice is propably faster than if statements... */ acc = FOLD_U32T(acc); acc = FOLD_U32T(acc); lwip.LWIP_DEBUGF(opt.INET_DEBUG, "_inet_chksum.inet_chksum_pseudo(): pbuf chain lwip_chksum()={0}\n", acc); return((ushort)~(acc & 0xffffU)); }
/* lwip.inet_chksum_pseudo: * * Calculates the pseudo Internet checksum used by TCP and UDP for a pbuf chain. * IP addresses are expected to be in network byte order. * * @param p chain of pbufs over that a checksum should be calculated (ip data part) * @param src source ip address (used for checksum of pseudo header) * @param dst destination ip address (used for checksum of pseudo header) * @param proto ip protocol (used for checksum of pseudo header) * @param proto_len length of the ip data part (used for checksum of pseudo header) * @return checksum (as ushort) to be saved directly in the protocol header */ public static ushort inet_chksum_pseudo(pbuf p, ip_addr src, ip_addr dest, byte proto, ushort proto_len) { uint acc; uint addr; pbuf q; byte swapped; acc = 0; swapped = 0; /* iterate through all pbuf in chain */ for (q = p; q != null; q = q.next) { lwip.LWIP_DEBUGF(opt.INET_DEBUG, "inet_chksum_pseudo(): checksumming pbuf {0} (has next {1}) \n", q, q.next); acc += LWIP_CHKSUM(q.payload, q.len); /*lwip.LWIP_DEBUGF(opt.INET_DEBUG, "inet_chksum_pseudo(): unwrapped lwip_chksum()={0} \n", acc);*/ /* just executing this next line is probably faster that the if statement needed * to check whether we really need to execute it, and does no harm */ acc = FOLD_U32T(acc); if (q.len % 2 != 0) { swapped = (byte)(1 - swapped); acc = SWAP_BYTES_IN_WORD((ushort)acc); } /*lwip.LWIP_DEBUGF(opt.INET_DEBUG, "inet_chksum_pseudo(): wrapped lwip_chksum()={0} \n", acc);*/ } if (swapped != 0) { acc = SWAP_BYTES_IN_WORD((ushort)acc); } addr = ip_addr.ip4_addr_get_u32(src); acc += (addr & 0xffffU); acc += ((addr >> 16) & 0xffffU); addr = ip_addr.ip4_addr_get_u32(dest); acc += (addr & 0xffffU); acc += ((addr >> 16) & 0xffffU); acc += (uint)lwip.lwip_htons((ushort)proto); acc += (uint)lwip.lwip_htons(proto_len); /* Fold 32-bit sum to 16 bits * calling this twice is propably faster than if statements... */ acc = FOLD_U32T(acc); acc = FOLD_U32T(acc); lwip.LWIP_DEBUGF(opt.INET_DEBUG, "inet_chksum_pseudo(): pbuf chain lwip_chksum()={0}\n", acc); return((ushort)~(acc & 0xffffU)); }
internal void copy_from(tcp_seg seg) { this.next = seg.next; this.p = seg.p; this.len = seg.len; #if TCP_OVERSIZE_DBGCHECK this.oversize_left = seg.oversize_left; #endif // TCP_OVERSIZE_DBGCHECK #if TCP_CHECKSUM_ON_COPY this.chksum = seg.chksum; this.chksum_swapped = seg.chksum_swapped; #endif // TCP_CHECKSUM_ON_COPY this.flags = seg.flags; this.tcphdr = seg.tcphdr; }
private static int CopyToPBuf(pbuf dst, pointer src, int len) { int pos = 0, rest = len; for (pbuf q = dst; q != null; q = q.next) { int tmp = rest; if (tmp > q.len) { tmp = q.len; } pointer.memcpy(q.payload, src + pos, tmp); pos += tmp; rest -= tmp; } return(pos); }
private static err_t RecvData(object arg, tcp_pcb tpcb, pbuf p, err_t err) { TcpCep _this = (TcpCep)arg; if (p == null) { _this.NetworkToHost(null); return(err_t.ERR_OK); } if (err != err_t.ERR_OK) { _this.m_lwIP.pbuf_free(p); return(err); } _this.NetworkToHost(p); _this.m_lwIP.tcp.tcp_recved(tpcb, p.tot_len); return(err_t.ERR_OK); }
private void recv(object arg, udp_pcb pcb, pbuf p, ip6_addr addr, ushort port) { System.Diagnostics.Debug.Assert((arg == this) && (pcb == m_Pcb)); pointer data = new pointer(new byte[sizeof(ushort) + T_IPV6EP.length + p.tot_len], 0); T_IPV6EP p_dstaddr = new T_IPV6EP(data, sizeof(ushort)); pointer p_dat = new pointer(data, sizeof(ushort) + T_IPV6EP.length); data.SetValue(p.tot_len); pointer.memcpy(p_dstaddr.ipaddr, addr, T_IPV6ADDR.length); p_dstaddr.portno = lwip.lwip_ntohs(port); for (pbuf q = p; q != null; q = q.next) { pointer.memcpy(p_dat, q.payload, q.len); p_dat += q.len; } lock (m_CallBack) { m_CallBack.Enqueue(data); } SetState(true, TMO.TMO_POL, null, OnTimeOut); }
public ER SendData(T_IPV6EP p_dstaddr, pointer p_dat, int len, TMO tmout) { pbuf buf; ip6_addr addr = new ip6_addr(p_dstaddr.ipaddr); buf = m_lwIP.pbuf_alloc(pbuf_layer.PBUF_TRANSPORT, (ushort)len, pbuf_type.PBUF_POOL); if (buf == null) { return(ER.E_NOMEM); } int pos = 0; for (pbuf q = buf; q != null; q = q.next) { pointer.memcpy(q.payload, new pointer(p_dat, pos), q.len); pos += q.len; } //m_lwIP.udp.udp_sendto(m_Pcb, buf, addr, p_dstaddr.portno); return(ER.E_OK); }
internal err_t ip_input(pbuf p, ip_addr src, ip_addr dest, byte proto) { ++lwip_stats.ip.recv; /* copy IP addresses to aligned ip_addr */ ip_addr.ip_addr_copy(current_iphdr_dest, dest); ip_addr.ip_addr_copy(current_iphdr_src, src); /* broadcast or multicast packet source address? Compliant with RFC 1122: 3.2.1.3 */ #if IP_ACCEPT_LINK_LAYER_ADDRESSING /* DHCP servers need 0.0.0.0 to be allowed as source address (RFC 1.1.2.2: 3.2.1.3/a) */ if (check_ip_src != 0 && !ip_addr.ip_addr_isany(ip.current_iphdr_src)) #endif // IP_ACCEPT_LINK_LAYER_ADDRESSING { if ((ip_addr.ip_addr_isbroadcast(current_iphdr_src, this)) || (ip_addr.ip_addr_ismulticast(current_iphdr_src))) { /* packet source is not valid */ lwip.LWIP_DEBUGF(opt.IP_DEBUG | lwip.LWIP_DBG_TRACE | lwip.LWIP_DBG_LEVEL_WARNING, "ip_input: packet source is not valid.\n"); /* free (drop) packet pbufs */ pbuf_free(p); ++lwip_stats.ip.drop; //snmp.snmp_inc_ipinaddrerrors(); //snmp.snmp_inc_ipindiscards(); return(err_t.ERR_OK); } } /* send to upper layers */ lwip.LWIP_DEBUGF(opt.IP_DEBUG, "ip_input: \n"); #if IP_DEBUG ip_debug_print(p); #endif lwip.LWIP_DEBUGF(opt.IP_DEBUG, "ip_input: p.len {0} p.tot_len {1}\n", p.len, p.tot_len); //lwip.current_header = iphdr; #if LWIP_RAW /* raw input did not eat the packet? */ if (raw.raw_input(p, inp) == 0) #endif // LWIP_RAW { switch (proto) { #if LWIP_UDP case lwip.IP_PROTO_UDP: #if LWIP_UDPLITE case lwip.IP_PROTO_UDPLITE: #endif // LWIP_UDPLITE //snmp.snmp_inc_ipindelivers(); udp.udp_input(p, this, proto == lwip.IP_PROTO_UDPLITE); break; #endif // LWIP_UDP #if LWIP_TCP case lwip.IP_PROTO_TCP: //snmp.snmp_inc_ipindelivers(); tcp.tcp_input(p, this); break; #endif // LWIP_TCP #if LWIP_ICMP case lwip.IP_PROTO_ICMP: //snmp.snmp_inc_ipindelivers(); lwip.icmp.icmp_input(p, inp); break; #endif // LWIP_ICMP #if LWIP_IGMP case lwip.IP_PROTO_IGMP: lwip.igmp.igmp_input(p, inp, lwip.current_iphdr_dest); break; #endif // LWIP_IGMP default: #if LWIP_ICMP /* send ICMP destination protocol unreachable unless is was a broadcast */ if (!ip_addr.ip_addr_isbroadcast(lwip.current_iphdr_dest, inp) && !ip_addr.ip_addr_ismulticast(lwip.current_iphdr_dest)) { p.payload = iphdr; lwip.icmp.icmp_dest_unreach(p, icmp_dur_type.ICMP_DUR_PROTO); } #endif // LWIP_ICMP pbuf_free(p); LWIP_DEBUGF(opt.IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, "Unsupported transport protocol {0}\n", proto); ++lwip_stats.ip.proterr; ++lwip_stats.ip.drop; //snmp.snmp_inc_ipinunknownprotos(); break; } } //lwip.current_header = null; ip_addr.ip_addr_set_any(current_iphdr_src); ip_addr.ip_addr_set_any(current_iphdr_dest); return(err_t.ERR_OK); }
internal static err_t output(netif netif, pbuf p, ip_addr src, ip_addr dest, byte proto) { int pos = 0, rest = p.tot_len; byte[] packet = new byte[rest]; ip_addr srch = new ip_addr(lwip.lwip_ntohl(src.addr)); ip_addr desth = new ip_addr(lwip.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; } netif.m_output(netif, packet, srch, desth, proto); return err_t.ERR_OK; }