/* Fill in ICMPv4 header fields. */ static int set_icmpv4_header(struct icmpv4 *icmpv4, u8 type, u8 code, s64 mtu, char **error) { icmpv4->type = type; icmpv4->code = code; icmpv4->checksum = htons(0); if (mtu >= 0) { if ((type != ICMP_DEST_UNREACH) || (code != ICMP_FRAG_NEEDED)) { asprintf(error, "ICMPv4 MTU is only valid for " "unreachable-frag_needed"); return STATUS_ERR; } if (!is_valid_u16(mtu)) { asprintf(error, "ICMPv4 MTU out of 16-bit range"); return STATUS_ERR; } icmpv4->message.frag.mtu = htons(mtu); } return STATUS_OK; }
void output_atoms(struct membuf *out, struct vec *atoms) { struct vec_iterator i[1]; struct vec_iterator i2[1]; struct atom **atomp; struct atom *atom; struct expr **exprp; struct expr *expr; struct membuf *in; const char *p; i32 value; i32 value2; dump_sym_table(LOG_DEBUG, s->sym_table); vec_get_iterator(atoms, i); while((atomp = vec_iterator_next(i)) != NULL) { atom = *atomp; LOG(LOG_DEBUG, ("yadda\n")); switch(atom->type) { case ATOM_TYPE_OP_ARG_NONE: LOG(LOG_DEBUG, ("output: $%02X\n", atom->u.op.code)); membuf_append_char(out, atom->u.op.code); break; case ATOM_TYPE_OP_ARG_U8: /* op with argument */ value = resolve_expr(atom->u.op.arg); if(!is_valid_u8(value)) { LOG(LOG_ERROR, ("value %d out of range for op $%02X @%p\n", value, atom->u.op.code, (void*)atom)); exit(1); } LOG(LOG_DEBUG, ("output: $%02X $%02X\n", atom->u.op.code, value & 255)); membuf_append_char(out, atom->u.op.code); membuf_append_char(out, value); break; case ATOM_TYPE_OP_ARG_I8: /* op with argument */ value = resolve_expr(atom->u.op.arg); if(!is_valid_i8(value)) { LOG(LOG_ERROR, ("value %d out of range for op $%02X @%p\n", value, atom->u.op.code, (void*)atom)); exit(1); } LOG(LOG_DEBUG, ("output: $%02X $%02X\n", atom->u.op.code, value & 255)); membuf_append_char(out, atom->u.op.code); membuf_append_char(out, value); break; case ATOM_TYPE_OP_ARG_UI8: /* op with argument */ value = resolve_expr(atom->u.op.arg); if(!is_valid_ui8(value)) { LOG(LOG_ERROR, ("value %d out of range for op $%02X @%p\n", value, atom->u.op.code, (void*)atom)); exit(1); } LOG(LOG_DEBUG, ("output: $%02X $%02X\n", atom->u.op.code, value & 255)); membuf_append_char(out, atom->u.op.code); membuf_append_char(out, value); break; case ATOM_TYPE_OP_ARG_U16: /* op with argument */ value = resolve_expr(atom->u.op.arg); if(!is_valid_u16(value)) { LOG(LOG_ERROR, ("value %d out of range for op $%02X @%p\n", value, atom->u.op.code, (void*)atom)); exit(1); } value2 = value / 256; value = value % 256; LOG(LOG_DEBUG, ("output: $%02X $%02X $%02X\n", atom->u.op.code, value, value2)); membuf_append_char(out, atom->u.op.code); membuf_append_char(out, value); membuf_append_char(out, value2); break; case ATOM_TYPE_RES: /* reserve memory statement */ value = resolve_expr(atom->u.res.length); if(!is_valid_u16(value)) { LOG(LOG_ERROR, ("length %d for .res(length, value) " "is out of range\n", value)); exit(1); } value2 = resolve_expr(atom->u.res.value); if(!is_valid_ui8(value2)) { LOG(LOG_ERROR, ("value %d for .res(length, value) " "is out of range\n", value)); exit(1); } LOG(LOG_DEBUG, ("output: .RES %d, %d\n", value, value2)); while(--value >= 0) { membuf_append_char(out, value2); } break; case ATOM_TYPE_BUFFER: /* include binary file statement */ value = atom->u.buffer.skip; if(!is_valid_u16(value)) { LOG(LOG_ERROR, ("value %d for .res(length, value) " "is out of range\n", value)); exit(1); } value2 = atom->u.buffer.length; if(!is_valid_u16(value2)) { LOG(LOG_ERROR, ("length %d for .incbin(name, skip, length) " "is out of range\n", value2)); exit(1); } LOG(LOG_DEBUG, ("output: .INCBIN \"%s\", %d, %d\n", atom->u.buffer.name, value, value2)); in = get_named_buffer(s->named_buffer, atom->u.buffer.name); p = membuf_get(in); p += value; while(--value2 >= 0) { membuf_append_char(out, *p++); } break; case ATOM_TYPE_WORD_EXPRS: vec_get_iterator(atom->u.exprs, i2); while((exprp = vec_iterator_next(i2)) != NULL) { expr = *exprp; value = resolve_expr(expr); if(!is_valid_ui16(value)) { LOG(LOG_ERROR, ("value %d for .word(value, ...) " "is out of range\n", value)); } value2 = value / 256; value = value % 256; membuf_append_char(out, value); membuf_append_char(out, value2); } LOG(LOG_DEBUG, ("output: %d words\n", vec_count(atom->u.exprs))); break; case ATOM_TYPE_BYTE_EXPRS: vec_get_iterator(atom->u.exprs, i2); while((exprp = vec_iterator_next(i2)) != NULL) { expr = *exprp; value = resolve_expr(expr); if(!is_valid_ui8(value)) { LOG(LOG_ERROR, ("value %d for .byte(value, ...) " "is out of range\n", value)); } membuf_append_char(out, value); } LOG(LOG_DEBUG, ("output: %d bytes\n", vec_count(atom->u.exprs))); break; default: LOG(LOG_ERROR, ("invalid atom_type %d @%p\n", atom->type, (void*)atom)); exit(1); } } }