void egp_print(netdissect_options *ndo, const uint8_t *bp, u_int length) { const struct egp_packet *egp; u_int version; u_int type; u_int code; u_int status; ndo->ndo_protocol = "egp"; egp = (const struct egp_packet *)bp; if (length < sizeof(*egp) || !ND_TTEST_SIZE(egp)) { ND_PRINT("[|egp]"); return; } version = EXTRACT_U_1(egp->egp_version); if (!ndo->ndo_vflag) { ND_PRINT("EGPv%u, AS %u, seq %u, length %u", version, EXTRACT_BE_U_2(egp->egp_as), EXTRACT_BE_U_2(egp->egp_sequence), length); return; } else ND_PRINT("EGPv%u, length %u", version, length); if (version != EGP_VERSION) { ND_PRINT("[version %u]", version); return; } type = EXTRACT_U_1(egp->egp_type); code = EXTRACT_U_1(egp->egp_code); status = EXTRACT_U_1(egp->egp_status); switch (type) { case EGPT_ACQUIRE: ND_PRINT(" acquire"); switch (code) { case EGPC_REQUEST: case EGPC_CONFIRM: ND_PRINT(" %s", egp_acquire_codes[code]); switch (status) { case EGPS_UNSPEC: case EGPS_ACTIVE: case EGPS_PASSIVE: ND_PRINT(" %s", egp_acquire_status[status]); break; default: ND_PRINT(" [status %u]", status); break; } ND_PRINT(" hello:%u poll:%u", EXTRACT_BE_U_2(egp->egp_hello), EXTRACT_BE_U_2(egp->egp_poll)); break; case EGPC_REFUSE: case EGPC_CEASE: case EGPC_CEASEACK: ND_PRINT(" %s", egp_acquire_codes[code]); switch (status ) { case EGPS_UNSPEC: case EGPS_NORES: case EGPS_ADMIN: case EGPS_GODOWN: case EGPS_PARAM: case EGPS_PROTO: ND_PRINT(" %s", egp_acquire_status[status]); break; default: ND_PRINT("[status %u]", status); break; } break; default: ND_PRINT("[code %u]", code); break; } break; case EGPT_REACH: switch (code) { case EGPC_HELLO: case EGPC_HEARDU: ND_PRINT(" %s", egp_reach_codes[code]); if (status <= EGPS_DOWN) ND_PRINT(" state:%s", egp_status_updown[status]); else ND_PRINT(" [status %u]", status); break; default: ND_PRINT("[reach code %u]", code); break; } break; case EGPT_POLL: ND_PRINT(" poll"); if (status <= EGPS_DOWN) ND_PRINT(" state:%s", egp_status_updown[status]); else ND_PRINT(" [status %u]", status); ND_PRINT(" net:%s", ipaddr_string(ndo, egp->egp_sourcenet)); break; case EGPT_UPDATE: ND_PRINT(" update"); if (status & EGPS_UNSOL) { status &= ~EGPS_UNSOL; ND_PRINT(" unsolicited"); } if (status <= EGPS_DOWN) ND_PRINT(" state:%s", egp_status_updown[status]); else ND_PRINT(" [status %u]", status); ND_PRINT(" %s int %u ext %u", ipaddr_string(ndo, egp->egp_sourcenet), EXTRACT_U_1(egp->egp_intgw), EXTRACT_U_1(egp->egp_extgw)); if (ndo->ndo_vflag) egpnrprint(ndo, egp, length); break; case EGPT_ERROR: ND_PRINT(" error"); if (status <= EGPS_DOWN) ND_PRINT(" state:%s", egp_status_updown[status]); else ND_PRINT(" [status %u]", status); if (EXTRACT_BE_U_2(egp->egp_reason) <= EGPR_UVERSION) ND_PRINT(" %s", egp_reasons[EXTRACT_BE_U_2(egp->egp_reason)]); else ND_PRINT(" [reason %u]", EXTRACT_BE_U_2(egp->egp_reason)); break; default: ND_PRINT("[type %u]", type); break; } }
void _egp_print(netdissect_options *ndo, register const uint8_t *bp, register u_int length) { register const struct egp_packet *egp; register int status; register int code; register int type; egp = (struct egp_packet *)bp; if (!ND_TTEST2(*egp, length)) { ND_PRINT((ndo, "[|egp]")); return; } if (!ndo->ndo_vflag) { ND_PRINT((ndo, "EGPv%u, AS %u, seq %u, length %u", egp->egp_version, EXTRACT_16BITS(&egp->egp_as), EXTRACT_16BITS(&egp->egp_sequence), length)); return; } else ND_PRINT((ndo, "EGPv%u, length %u", egp->egp_version, length)); if (egp->egp_version != EGP_VERSION) { ND_PRINT((ndo, "[version %d]", egp->egp_version)); return; } type = egp->egp_type; code = egp->egp_code; status = egp->egp_status; switch (type) { case EGPT_ACQUIRE: ND_PRINT((ndo, " acquire")); switch (code) { case EGPC_REQUEST: case EGPC_CONFIRM: ND_PRINT((ndo, " %s", egp_acquire_codes[code])); switch (status) { case EGPS_UNSPEC: case EGPS_ACTIVE: case EGPS_PASSIVE: ND_PRINT((ndo, " %s", egp_acquire_status[status])); break; default: ND_PRINT((ndo, " [status %d]", status)); break; } ND_PRINT((ndo, " hello:%d poll:%d", EXTRACT_16BITS(&egp->egp_hello), EXTRACT_16BITS(&egp->egp_poll))); break; case EGPC_REFUSE: case EGPC_CEASE: case EGPC_CEASEACK: ND_PRINT((ndo, " %s", egp_acquire_codes[code])); switch (status ) { case EGPS_UNSPEC: case EGPS_NORES: case EGPS_ADMIN: case EGPS_GODOWN: case EGPS_PARAM: case EGPS_PROTO: ND_PRINT((ndo, " %s", egp_acquire_status[status])); break; default: ND_PRINT((ndo, "[status %d]", status)); break; } break; default: ND_PRINT((ndo, "[code %d]", code)); break; } break; case EGPT_REACH: switch (code) { case EGPC_HELLO: case EGPC_HEARDU: ND_PRINT((ndo, " %s", egp_reach_codes[code])); if (status <= EGPS_DOWN) ND_PRINT((ndo, " state:%s", egp_status_updown[status])); else ND_PRINT((ndo, " [status %d]", status)); break; default: ND_PRINT((ndo, "[reach code %d]", code)); break; } break; case EGPT_POLL: ND_PRINT((ndo, " poll")); if (egp->egp_status <= EGPS_DOWN) ND_PRINT((ndo, " state:%s", egp_status_updown[status])); else ND_PRINT((ndo, " [status %d]", status)); ND_PRINT((ndo, " net:%s", ipaddr_string(ndo, &egp->egp_sourcenet))); break; case EGPT_UPDATE: ND_PRINT((ndo, " update")); if (status & EGPS_UNSOL) { status &= ~EGPS_UNSOL; ND_PRINT((ndo, " unsolicited")); } if (status <= EGPS_DOWN) ND_PRINT((ndo, " state:%s", egp_status_updown[status])); else ND_PRINT((ndo, " [status %d]", status)); ND_PRINT((ndo, " %s int %d ext %d", ipaddr_string(ndo, &egp->egp_sourcenet), egp->egp_intgw, egp->egp_extgw)); if (ndo->ndo_vflag) egpnrprint(ndo, egp); break; case EGPT_ERROR: ND_PRINT((ndo, " error")); if (status <= EGPS_DOWN) ND_PRINT((ndo, " state:%s", egp_status_updown[status])); else ND_PRINT((ndo, " [status %d]", status)); if (EXTRACT_16BITS(&egp->egp_reason) <= EGPR_UVERSION) ND_PRINT((ndo, " %s", egp_reasons[EXTRACT_16BITS(&egp->egp_reason)])); else ND_PRINT((ndo, " [reason %d]", EXTRACT_16BITS(&egp->egp_reason))); break; default: ND_PRINT((ndo, "[type %d]", type)); break; } }