📄 packet.c
字号:
pbs->lenfld_desc = NULL;}#ifdef DEBUG/* print a host struct * * This code assumes that the network and host structure * members have the same alignment and size! This requires * that all padding be explicit. */voidDBG_print_struct(const char *label, const void *struct_ptr, struct_desc *sd, bool len_meaningful){ bool immediate = FALSE; const u_int8_t *inp = struct_ptr; field_desc *fp; DBG_log("%s%s:", label, sd->name); for (fp = sd->fields; fp->field_type != ft_end; fp++) { int i = fp->size; u_int32_t n = 0; switch (fp->field_type) { case ft_mbz: /* must be zero */ inp += i; break; case ft_nat: /* natural number (may be 0) */ case ft_len: /* length of this struct and any following crud */ case ft_lv: /* length/value field of attribute */ case ft_enum: /* value from an enumeration */ case ft_loose_enum: /* value from an enumeration with only some names known */ case ft_af_enum: /* Attribute Format + value from an enumeration */ case ft_af_loose_enum: /* Attribute Format + value from an enumeration */ case ft_set: /* bits representing set */ switch (i) { case 8/BITS_PER_BYTE: n = *(const u_int8_t *)inp; break; case 16/BITS_PER_BYTE: n = *(const u_int16_t *)inp; break; case 32/BITS_PER_BYTE: n = *(const u_int32_t *)inp; break; default: bad_case(i); } switch (fp->field_type) { case ft_len: /* length of this struct and any following crud */ case ft_lv: /* length/value field of attribute */ if (!immediate && !len_meaningful) break; /* FALL THROUGH */ case ft_nat: /* natural number (may be 0) */ DBG_log(" %s: %lu", fp->name, (unsigned long)n); break; case ft_af_loose_enum: /* Attribute Format + value from an enumeration */ case ft_af_enum: /* Attribute Format + value from an enumeration */ if ((n & ISAKMP_ATTR_AF_MASK) == ISAKMP_ATTR_AF_TV) immediate = TRUE; /* FALL THROUGH */ case ft_enum: /* value from an enumeration */ case ft_loose_enum: /* value from an enumeration with only some names known */ DBG_log(" %s: %s", fp->name, enum_show(fp->desc, n)); break; case ft_set: /* bits representing set */ DBG_log(" %s: %s", fp->name, bitnamesof(fp->desc, n)); break; default: bad_case(fp->field_type); } inp += i; break; case ft_raw: /* bytes to be left in network-order */ { char m[50]; /* arbitrary limit on name width in log */ snprintf(m, sizeof(m), " %s:", fp->name); DBG_dump(m, inp, i); inp += i; } break; default: bad_case(fp->field_type); } }}static voidDBG_prefix_print_struct(const pb_stream *pbs , const char *label, const void *struct_ptr , struct_desc *sd, bool len_meaningful){ /* print out a title, with a prefix of asterisks to show * the nesting level. */ char space[40]; /* arbitrary limit on label+flock-of-* */ size_t len = strlen(label); if (sizeof(space) <= len) { DBG_print_struct(label, struct_ptr, sd, len_meaningful); } else { const pb_stream *p = pbs; char *pre = &space[sizeof(space) - (len + 1)]; strcpy(pre, label); /* put at least one * out */ for (;;) { if (pre <= space) break; *--pre = '*'; if (p == NULL) break; p = p->container; } DBG_print_struct(pre, struct_ptr, sd, len_meaningful); }}#endif/* "parse" a network struct into a host struct. * * This code assumes that the network and host structure * members have the same alignment and size! This requires * that all padding be explicit. * * If obj_pbs is supplied, a new pb_stream is created for the * variable part of the structure (this depends on their * being one length field in the structure). The cursor of this * new PBS is set to after the parsed part of the struct. * * This routine returns TRUE iff it succeeds. */boolin_struct(void *struct_ptr, struct_desc *sd, pb_stream *ins, pb_stream *obj_pbs){ err_t ugh = NULL; u_int8_t *cur = ins->cur; if (ins->roof - cur < (ptrdiff_t)sd->size) { ugh = builddiag("not enough room in input packet for %s", sd->name); } else { u_int8_t *roof = cur + sd->size; /* may be changed by a length field */ u_int8_t *outp = struct_ptr; bool immediate = FALSE; field_desc *fp; for (fp = sd->fields; ugh == NULL; fp++) { size_t i = fp->size; passert(ins->roof - cur >= (ptrdiff_t)i); passert(cur - ins->cur <= (ptrdiff_t)(sd->size - i)); passert(outp - (cur - ins->cur) == struct_ptr);#if 0 DBG(DBG_PARSING, DBG_log("%d %s" , (int) (cur - ins->cur), fp->name == NULL? "" : fp->name));#endif switch (fp->field_type) { case ft_mbz: /* must be zero */ for (; i != 0; i--) { if (*cur++ != 0) { ugh = builddiag("byte %d of %s must be zero, but is not" , (int) (cur - ins->cur), sd->name); break; } *outp++ = '\0'; /* probably redundant */ } break; case ft_nat: /* natural number (may be 0) */ case ft_len: /* length of this struct and any following crud */ case ft_lv: /* length/value field of attribute */ case ft_enum: /* value from an enumeration */ case ft_loose_enum: /* value from an enumeration with only some names known */ case ft_af_enum: /* Attribute Format + value from an enumeration */ case ft_af_loose_enum: /* Attribute Format + value from an enumeration */ case ft_set: /* bits representing set */ { u_int32_t n = 0; for (; i != 0; i--) n = (n << BITS_PER_BYTE) | *cur++; switch (fp->field_type) { case ft_len: /* length of this struct and any following crud */ case ft_lv: /* length/value field of attribute */ { u_int32_t len = fp->field_type == ft_len? n : immediate? sd->size : n + sd->size; if (len < sd->size) { ugh = builddiag("%s of %s is smaller than minimum" , fp->name, sd->name); } else if (pbs_left(ins) < len) { ugh = builddiag("%s of %s is larger than can fit" , fp->name, sd->name); } else { roof = ins->cur + len; } break; } case ft_af_loose_enum: /* Attribute Format + value from an enumeration */ if ((n & ISAKMP_ATTR_AF_MASK) == ISAKMP_ATTR_AF_TV) immediate = TRUE; break; case ft_af_enum: /* Attribute Format + value from an enumeration */ if ((n & ISAKMP_ATTR_AF_MASK) == ISAKMP_ATTR_AF_TV) immediate = TRUE; /* FALL THROUGH */ case ft_enum: /* value from an enumeration */ if (enum_name(fp->desc, n) == NULL) { ugh = builddiag("%s of %s has an unknown value: %lu" , fp->name, sd->name, (unsigned long)n); } /* FALL THROUGH */ case ft_loose_enum: /* value from an enumeration with only some names known */ break; case ft_set: /* bits representing set */ if (!testset(fp->desc, n)) { ugh = builddiag("bitset %s of %s has unknown member(s): %s" , fp->name, sd->name, bitnamesof(fp->desc, n)); } break; default: break; } i = fp->size; switch (i) { case 8/BITS_PER_BYTE: *(u_int8_t *)outp = n; break; case 16/BITS_PER_BYTE: *(u_int16_t *)outp = n; break; case 32/BITS_PER_BYTE: *(u_int32_t *)outp = n; break; default: bad_case(i); } outp += i; break; } case ft_raw: /* bytes to be left in network-order */ for (; i != 0; i--) { *outp++ = *cur++; } break; case ft_end: /* end of field list */ passert(cur == ins->cur + sd->size); if (obj_pbs != NULL) { init_pbs(obj_pbs, ins->cur, roof - ins->cur, sd->name); obj_pbs->container = ins; obj_pbs->desc = sd; obj_pbs->cur = cur; } ins->cur = roof; DBG(DBG_PARSING , DBG_prefix_print_struct(ins, "parse ", struct_ptr, sd, TRUE)); return TRUE; default: bad_case(fp->field_type); } } } /* some failure got us here: report it */ openswan_loglog(RC_LOG_SERIOUS, ugh); return FALSE;}boolin_raw(void *bytes, size_t len, pb_stream *ins, const char *name){ if (pbs_left(ins) < len) { openswan_loglog(RC_LOG_SERIOUS , "not enough bytes left to get %s from %s" , name, ins->name); return FALSE; } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -