// Write the IPv4 headers char *write_ipv4(char *bufferptr, unsigned short identifier, unsigned char *local_ip, unsigned char *dest_ip) { // Grab a reference to the beggining of the header so we can come back and // calculate the checksum char *start = bufferptr; // IP version 4 and 20 bytes header APPEND_BYTE(bufferptr, 0x45); // Set services field to zero APPEND_BYTE(bufferptr, 0); // Length of the packet (28 bytes) APPEND_SHORT(bufferptr, IP_LEN); // ID APPEND_SHORT(bufferptr, identifier); // Flags (don't fragment) APPEND_BYTE(bufferptr, 0x40); // Offset (zero) APPEND_BYTE(bufferptr, 0); // TTL APPEND_BYTE(bufferptr, TTL); // ICMP APPEND_BYTE(bufferptr, 1); // Zeroed checksum char *checksumstart = bufferptr; APPEND_SHORT(bufferptr, 0); // Source IP APPEND_BYTES(bufferptr, local_ip, IP_ADDR_LEN); // Destination IP APPEND_BYTES(bufferptr, dest_ip, IP_ADDR_LEN); // Calculate the checksum unsigned short checksum = in_cksum((short unsigned int *)start, IP_HEADER_LEN); memcpy(checksumstart, &checksum, 2); return bufferptr; }
*/ void Crash(REBINT id, ...) /* ** Print a failure message and abort. ** ** LATIN1 ONLY!! (For now) ** ** The error is identified by id number, which can reference an ** error message string in the boot strings block. ** ** Note that lower level error messages should not attempt to ** use the %r (mold value) format (uses higher level functions). ** ** See panics.h for list of crash errors. ** ***********************************************************************/ { va_list args; REBYTE buf[CRASH_BUF_SIZE]; REBYTE *msg; REBINT n = 0; va_start(args, id); DISABLE_GC; if (Reb_Opts->crash_dump) { Dump_Info(); Dump_Stack(0, 0); } // "REBOL PANIC #nnn:" COPY_BYTES(buf, Crash_Msgs[CM_ERROR], CRASH_BUF_SIZE); APPEND_BYTES(buf, " #", CRASH_BUF_SIZE); Form_Int(buf + LEN_BYTES(buf), id); APPEND_BYTES(buf, ": ", CRASH_BUF_SIZE); // "REBOL PANIC #nnn: put error message here" // The first few error types only print general error message. // Those errors > RP_STR_BASE have specific error messages (from boot.r). if (id < RP_BOOT_DATA) n = CM_DEBUG; else if (id < RP_INTERNAL) n = CM_BOOT; else if (id < RP_ASSERTS) n = CM_INTERNAL; else if (id < RP_DATATYPE) n = CM_ASSERT; else if (id < RP_STR_BASE) n = CM_DATATYPE; else if (id > RP_STR_BASE + RS_MAX - RS_ERROR) n = CM_DEBUG; // Use the above string or the boot string for the error (in boot.r): msg = (REBYTE*)(n >= 0 ? Crash_Msgs[n] : BOOT_STR(RS_ERROR, id - RP_STR_BASE - 1)); Form_Var_Args(buf + LEN_BYTES(buf), CRASH_BUF_SIZE - 1 - LEN_BYTES(buf), msg, args); n = LEN_BYTES(Crash_Msgs[CM_CONTACT]); if ((LEN_BYTES(buf) + n) < (CRASH_BUF_SIZE - 1)) APPEND_BYTES(buf, Crash_Msgs[CM_CONTACT], n); // Convert to OS-specific char-type: #ifdef disable_for_now //OS_WIDE_CHAR /// win98 does not support it { REBCHR s1[512]; REBCHR s2[2000]; n = TO_OS_STR(s1, Crash_Msgs[CM_ERROR], LEN_BYTES(Crash_Msgs[CM_ERROR])); if (n > 0) s1[n] = 0; // terminate else OS_EXIT(200); // bad conversion n = TO_OS_STR(s2, buf, LEN_BYTES(buf)); if (n > 0) s2[n] = 0; else OS_EXIT(200); OS_CRASH(s1, s2); } #else OS_CRASH(Crash_Msgs[CM_ERROR], buf); #endif }