/** * This is the recommended method to edit a packet. Returns (new) total packet length */ int tcpedit_dlt_process(tcpeditdlt_t *ctx, u_char **packet, int pktlen, tcpr_dir_t direction) { int rcode; assert(ctx); assert(packet); assert(pktlen); assert(direction == TCPR_DIR_C2S || direction == TCPR_DIR_S2C || direction == TCPR_DIR_NOSEND); /* nothing to do here */ if (direction == TCPR_DIR_NOSEND) return pktlen; /* decode packet */ if ((rcode = tcpedit_dlt_decode(ctx, *packet, pktlen)) == TCPEDIT_ERROR) { return TCPEDIT_ERROR; } else if (rcode == TCPEDIT_WARN) { warnx("Warning decoding packet: %s", tcpedit_getwarn(ctx->tcpedit)); } else if (rcode == TCPEDIT_SOFT_ERROR) { return rcode; /* can't edit the packet */ } /* encode packet */ if ((rcode = tcpedit_dlt_encode(ctx, *packet, pktlen, direction)) == TCPEDIT_ERROR) { return TCPEDIT_ERROR; } else if (rcode == TCPEDIT_WARN) { warnx("Warning encoding packet: %s", tcpedit_getwarn(ctx->tcpedit)); } return rcode; }
/* * Function to decode the layer 2 header in the packet. * You need to fill out: * - ctx->l2len * - ctx->srcaddr * - ctx->dstaddr * - ctx->proto * - ctx->decoded_extra * Returns: TCPEDIT_ERROR | TCPEDIT_OK | TCPEDIT_WARN */ int dlt_jnpr_ether_decode(tcpeditdlt_t *ctx, const u_char *packet, const int pktlen) { int jnpr_header_len = 0; const u_char *ethernet = NULL; jnpr_ether_config_t *config; assert(ctx); assert(packet); assert(pktlen > JUNIPER_ETHER_HEADER_LEN); /* MAGIC + Static fields + Extension Length */ config = (jnpr_ether_config_t *)ctx->encoder->config; /* first, verify magic */ if (memcmp(packet, JUNIPER_ETHER_MAGIC, JUNIPER_ETHER_MAGIC_LEN) != 0) { tcpedit_seterr(ctx->tcpedit, "Invalid magic 0x%02X%02X%02X", packet[0], packet[1], packet[2]); return TCPEDIT_ERROR; } /* next make sure the L2 header is present */ if ((packet[JUNIPER_ETHER_OPTIONS_OFFSET] & JUNIPER_ETHER_L2PRESENT) != JUNIPER_ETHER_L2PRESENT) { tcpedit_seterr(ctx->tcpedit, "Frame is missing L2 Header: %x", packet[JUNIPER_ETHER_OPTIONS_OFFSET]); return TCPEDIT_ERROR; } /* then get the Juniper header length */ memcpy(&jnpr_header_len, &packet[JUNIPER_ETHER_EXTLEN_OFFSET], 2); jnpr_header_len = ntohs(jnpr_header_len) + JUNIPER_ETHER_HEADER_LEN; dbgx(1, "jnpr header len: %d", jnpr_header_len); /* make sure the packet is big enough to find the Ethernet Header */ if (pktlen < jnpr_header_len + TCPR_ETH_H) { tcpedit_seterr(ctx->tcpedit, "Frame is too short! %d < %d", pktlen, (jnpr_header_len + TCPR_ETH_H)); return TCPEDIT_ERROR; } ctx->l2len = jnpr_header_len; /* jump to the appropriate offset */ ethernet = packet + jnpr_header_len; /* let the en10mb plugin decode the rest */ if (tcpedit_dlt_decode(config->subctx, ethernet, (pktlen - jnpr_header_len)) == TCPEDIT_ERROR) return TCPEDIT_ERROR; /* copy the subdecoder state to our encoder state */ if (tcpedit_dlt_copy_decoder_state(ctx, config->subctx) == TCPEDIT_ERROR) return TCPEDIT_ERROR; return TCPEDIT_OK; }