/** the famous ping. */ private void doICMP(Packet p) { int type_code = p.buf[5] >>> 16; if (Logging.LOG) Logging.wr('P'); if (Logging.LOG) Logging.hexVal(type_code); if (type_code == 0x0800) { // TODO check received ICMP checksum p.buf[5] = 0; // echo replay plus clear checksum, p.buf[5] = Ip.chkSum(p.buf, 5, p.len - 20); // echo replay (0x0000) // plus checksum } else { p.len = 0; } }
/** * Set data from String into the packet * * @param p packet * @param off offset in 32-bit words * @param s String source */ public static void setData(Packet p, int off, String s) { int[] buf = p.buf; int cnt = s.length(); // copy buffer int k = 0; for (int i = 0; i < cnt; i += 4) { for (int j = 0; j < 4; ++j) { k <<= 8; if (i + j < cnt) k += s.charAt(i + j); } buf[off + (i >>> 2)] = k; } p.len = (off << 2) + cnt; }
/** * Process one IP packet. Change buffer and set length to get a packet sent back. called from * Net.loop(). */ public void receive(Packet p) { int i; int[] buf = p.buf; int len; i = buf[0]; len = i & 0xffff; // length from IP header // NO options are assumed in ICMP/TCP/IP... // => copy if options present // but we just drop it now - too lazy if (len > p.len || (i >>> 24 != 0x45)) { if (Logging.LOG) Logging.wr("IP options -> discard"); ejip.returnPacket(p); // packet to short or ip options => drop it return; } else { p.len = len; // correct for to long packets } // TODO fragmentation if (Ip.chkSum(buf, 0, 20) != 0) { ejip.returnPacket(p); if (Logging.LOG) Logging.wr("wrong IP checksum "); return; } int prot = (buf[2] >> 16) & 0xff; // protocol if (prot == PROT_ICMP) { doICMP(p); ip.doIp(p, prot); } else if (prot == Tcp.PROTOCOL) { if (Ejip.TCP_ENABLED) { // that's the new TCP processing tcp.process(p); } else { ejip.returnPacket(p); // mark packet free } } else if (prot == Udp.PROTOCOL) { udp.process(p); // Udp generates the reply } else { ejip.returnPacket(p); // mark packet free } }