static ENC_STATUS IP4_Encode (EncState* enc, Buffer* in, Buffer* out) { int len; uint32_t start = out->end; IPHdr* hi = (IPHdr*)enc->p->layers[enc->layer-1].start; IPHdr* ho = (IPHdr*)(out->base + out->end); PROTO_ID next = NextEncoder(enc); UPDATE_BOUND(out, sizeof(*ho)); /* IPv4 encoded header is hardcoded 20 bytes */ ho->ip_verhl = 0x45; ho->ip_off = 0; ho->ip_id = IpId_Next(); ho->ip_tos = hi->ip_tos; ho->ip_proto = hi->ip_proto; if ( FORWARD(enc) ) { ho->ip_src.s_addr = hi->ip_src.s_addr; ho->ip_dst.s_addr = hi->ip_dst.s_addr; ho->ip_ttl = FwdTTL(enc, hi->ip_ttl); } else { ho->ip_src.s_addr = hi->ip_dst.s_addr; ho->ip_dst.s_addr = hi->ip_src.s_addr; ho->ip_ttl = RevTTL(enc, hi->ip_ttl); } enc->ip_hdr = (uint8_t*)hi; enc->ip_len = IP_HLEN(hi) << 2; if ( next < PROTO_MAX ) { ENC_STATUS err = encoders[next].fencode(enc, in, out); if ( ENC_OK != err ) return err; } if ( enc->proto ) { ho->ip_proto = enc->proto; enc->proto = 0; } len = out->end - start; ho->ip_len = htons((uint16_t)len); ho->ip_csum = 0; /* IPv4 encoded header is hardcoded 20 bytes, we save some * cycles and use the literal header size for checksum */ ho->ip_csum = in_chksum_ip((const uint16_t *)ho, sizeof *ho); return ENC_OK; }
static ENC_STATUS IP4_Encode (EncState* enc, Buffer* in, Buffer* out) { int len; uint32_t start = out->end; IPHdr* hi = (IPHdr*)enc->p->layers[enc->layer-1].start; IPHdr* ho = (IPHdr*)(out->base + out->end); PROTO_ID next = NextEncoder(enc); UPDATE_BOUND(out, sizeof(*ho)); len = GET_IP_HDR_LEN(hi) - sizeof(*hi); ho->ip_verhl = 0x45; ho->ip_off = 0; ho->ip_id = IpId_Next(); ho->ip_tos = hi->ip_tos; ho->ip_proto = hi->ip_proto; if ( FORWARD(enc) ) { uint8_t ttl = AdjTTL(hi->ip_ttl); ho->ip_src.s_addr = hi->ip_src.s_addr; ho->ip_dst.s_addr = hi->ip_dst.s_addr; if ( enc->p->ssnptr ) ttl = GetTTL(enc); #ifdef NORMALIZER if ( ttl < ScMinTTL() && ScNewTTL() ) ttl = ScNewTTL(); #endif ho->ip_ttl = ttl; } else { uint8_t ttl = MAX_TTL; ho->ip_src.s_addr = hi->ip_dst.s_addr; ho->ip_dst.s_addr = hi->ip_src.s_addr; if ( enc->p->ssnptr ) ttl = GetTTL(enc); #ifdef NORMALIZER if ( ttl < ScMinTTL() && ScNewTTL() ) ttl = ScNewTTL(); #endif ho->ip_ttl = ttl; } enc->ip_hdr = (uint8_t*)hi; enc->ip_len = IP_HLEN(hi) << 2; if ( next < PROTO_MAX ) { int err = encoders[next].fencode(enc, in, out); if ( err ) return err; } if ( enc->proto ) { ho->ip_proto = enc->proto; enc->proto = 0; } len = out->end - start; ho->ip_len = htons((u_int16_t)len); ip_checksum(ho, len); return ENC_OK; }