/*===========================================================================* * fill_note_segment_and_entries_hdrs * *===========================================================================*/ static void fill_note_segment_and_entries_hdrs(Elf_Phdr phdrs[], Elf_Nhdr nhdrs[]) { int filesize; const char *note_name = ELF_NOTE_MINIX_ELFCORE_NAME "\0"; int name_len, mei_len, gregs_len; /* Size of notes in the core file is rather fixed: * sizeof(minix_elfcore_info_t) + * 2 * sizeof(Elf_Nhdr) + the size of the padded name of the note * - i.e. "MINIX-CORE\0" padded to 4-byte alignment => 2 * 8 bytes */ name_len = strlen(note_name) + 1; mei_len = sizeof(minix_elfcore_info_t); gregs_len = sizeof(gregset_t); /* Make sure to also count the padding bytes */ filesize = PAD_LEN(mei_len) + PAD_LEN(gregs_len) + 2 * sizeof(Elf_Nhdr) + 2 * PAD_LEN(name_len); fill_prog_header(&phdrs[0], PT_NOTE, 0, 0, PF_R, filesize, 0); /* First note entry header */ nhdrs[0].n_namesz = name_len; nhdrs[0].n_descsz = sizeof(minix_elfcore_info_t); nhdrs[0].n_type = NT_MINIX_ELFCORE_INFO; /* Second note entry header */ nhdrs[1].n_namesz = name_len; nhdrs[1].n_descsz = sizeof(gregset_t); nhdrs[1].n_type = NT_MINIX_ELFCORE_GREGS; }
/* * chirouter_pcap_write_option - Writes a pcapng option * * ctx: Server context * * option_code: Option code * * option_length: Option length * * option_value: Raw binary value of the option * * Returns: 0 on success, -1 if an error happens. * */ int chirouter_pcap_write_option(server_ctx_t *ctx, uint16_t option_code, uint16_t option_length, uint8_t *option_value) { struct pcapng_option opt; uint16_t pad_length; uint32_t pad = 0; opt.option_code = option_code; opt.option_length = option_length; /* Write option code and length */ if (fwrite((char *)&opt, sizeof(opt), 1, ctx->pcap) != 1) return EXIT_FAILURE; if(option_length > 0) { pad_length = PAD_LEN(option_length); assert(pad_length >= 0 && pad_length <= 3); /* Write option value */ if (fwrite(option_value, 1, option_length, ctx->pcap) != option_length) return EXIT_FAILURE; if(pad_length > 0) { /* Write padding */ if (fwrite((char *)&pad, 1, pad_length, ctx->pcap) != pad_length) return EXIT_FAILURE; } } return EXIT_SUCCESS; }
/*===========================================================================* * dump_notes * *===========================================================================*/ PRIVATE void dump_notes(Elf_Nhdr nhdrs[], int csig, char *exe_name) { char *note_name = ELF_NOTE_MINIX_ELFCORE_NAME "\0"; char pad[4]; minix_elfcore_info_t mei; int mei_len = sizeof(minix_elfcore_info_t); int gregs_len = sizeof(gregset_t); struct stackframe_s regs; char proc_name[PROC_NAME_LEN]; /* Get process's name */ if (sys_datacopy(PM_PROC_NR, (vir_bytes) exe_name, VFS_PROC_NR, (vir_bytes) proc_name, PROC_NAME_LEN) != OK) printf("VFS: Cannot get process's name\n"); /* Dump first note entry */ mei.mei_version = MINIX_ELFCORE_VERSION; mei.mei_meisize = mei_len; mei.mei_signo = csig; mei.mei_pid = fp->fp_pid; memcpy(mei.mei_command, proc_name, sizeof(mei.mei_command)); write_buf((char *)&nhdrs[0], sizeof(Elf_Nhdr)); write_buf(note_name, nhdrs[0].n_namesz); write_buf(pad, PAD_LEN(nhdrs[0].n_namesz) - nhdrs[0].n_namesz); write_buf((char *)&mei, mei_len); write_buf(pad, PAD_LEN(mei_len) - mei_len); /* Get registers */ if (sys_getregs(®s, fp->fp_endpoint) != OK) printf("VFS: Could not read registers\n"); if (sizeof(regs) != gregs_len) printf("VFS: Wrong core register structure size\n"); /* Dump second note entry - the general registers */ write_buf((char *)&nhdrs[1], sizeof(Elf_Nhdr)); write_buf(note_name, nhdrs[1].n_namesz); write_buf(pad, PAD_LEN(nhdrs[1].n_namesz) - nhdrs[1].n_namesz); write_buf((char *)®s, gregs_len); write_buf(pad, PAD_LEN(gregs_len) - gregs_len); }
int chirouter_pcap_write_frame(chirouter_ctx_t *ctx, chirouter_interface_t *iface, uint8_t *msg, size_t len, pcap_packet_direction_t dir) { struct pcapng_epb hdr; /* Get nanoseconds since epoch */ uint64_t ns; struct timespec spec; clock_gettime(CLOCK_REALTIME, &spec); ns = (uint64_t) spec.tv_sec * BILLION + (uint64_t) spec.tv_nsec; hdr.block_type = BLOCK_TYPE_EPB; hdr.interface_id = iface->pcap_iface_id; hdr.timestamp_high = ns >> 32; hdr.timestamp_low = ns & 0x00000000FFFFFFFF; hdr.captured_plen = len; hdr.original_plen = len; hdr.block_total_length = sizeof(hdr); hdr.block_total_length += len; hdr.block_total_length += OPTION_HDR_LEN + PADDED_LEN(4); /* Flags */ hdr.block_total_length += OPTION_HDR_LEN; /* End of options */ hdr.block_total_length += 4; /* Trailing length */ if (fwrite((char *)&hdr, sizeof(hdr), 1, ctx->server->pcap) != 1) return EXIT_FAILURE; uint32_t pad_length; uint32_t pad = 0; pad_length = PAD_LEN(len); assert(pad_length >= 0 && pad_length <= 3); if (fwrite(msg, 1, len, ctx->server->pcap) != len) return EXIT_FAILURE; /* Write padding */ if(pad_length > 0) { if (fwrite((char *)&pad, 1, pad_length, ctx->server->pcap) != pad_length) return EXIT_FAILURE; } /* Compute flags */ uint32_t flags; switch(dir) { case PCAP_UNSPECIFIED: flags = 0; break; case PCAP_INBOUND: flags = 1; break; case PCAP_OUTBOUND: flags = 2; break; } if(chirouter_pcap_write_option(ctx->server, OPCODE_EPB_FLAGS, 4, (uint8_t*) &flags)) return EXIT_FAILURE; if(chirouter_pcap_write_option(ctx->server, OPCODE_END, 0, NULL)) return EXIT_FAILURE; if (fwrite((char *)&hdr.block_total_length, sizeof(hdr.block_total_length), 1, ctx->server->pcap) != 1) return EXIT_FAILURE; return EXIT_SUCCESS; }