Ethereal-dev: [ethereal-dev] patch for X.25 dissector and nettl file format
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: Olivier Abad <abad@xxxxxxxxxxxxx>
Date: Sun, 17 Oct 1999 21:23:56 +0200
Hi, Here is a new patch. It adds : - more display filters for X.25 - no LCN in RESTART / DIAGNOSTIC / REGISTRATION packets - support for nettl file format (nettl is a trace tool for HP-UX). For now, it only supports traces for X.25 interfaces (tested with HP-UX 10.20). Olivier diff -Nru ethereal/packet-x25.c ethereal.local/packet-x25.c --- ethereal/packet-x25.c Tue Oct 12 18:28:35 1999 +++ ethereal.local/packet-x25.c Sun Oct 17 21:11:36 1999 @@ -85,8 +85,50 @@ #define X25_FAC_CALL_DEFLECT 0xD1 int proto_x25 = -1; +int hf_x25_qbit = -1; +int hf_x25_dbit = -1; +int hf_x25_mod = -1; int hf_x25_lcn = -1; int hf_x25_type = -1; +int hf_x25_p_r = -1; +int hf_x25_mbit = -1; +int hf_x25_p_s = -1; +int proto_ex25 = -1; +int hf_ex25_qbit = -1; +int hf_ex25_dbit = -1; +int hf_ex25_mod = -1; +int hf_ex25_lcn = -1; +int hf_ex25_type = -1; +int hf_ex25_p_r = -1; +int hf_ex25_mbit = -1; +int hf_ex25_p_s = -1; + +static const value_string vals_modulo[] = { + { 1, "8" }, + { 2, "128" }, + { 0, NULL} +}; + +static const value_string vals_x25_type[] = { + { X25_CALL_REQUEST, "Call" }, + { X25_CALL_ACCEPTED, "Call Accepted" }, + { X25_CLEAR_REQUEST, "Clear" }, + { X25_CLEAR_CONFIRMATION, "Clear Confirmation" }, + { X25_INTERRUPT, "Interrupt" }, + { X25_INTERRUPT_CONFIRMATION, "Interrupt Confirmation" }, + { X25_RESET_REQUEST, "Reset" }, + { X25_RESET_CONFIRMATION, "Reset Confirmation" }, + { X25_RESTART_REQUEST, "Restart" }, + { X25_RESTART_CONFIRMATION, "Restart Confirmation" }, + { X25_REGISTRATION_REQUEST, "Registration" }, + { X25_REGISTRATION_CONFIRMATION, "Registration Confirmation" }, + { X25_DIAGNOSTIC, "Diagnostic" }, + { X25_RR, "RR" }, + { X25_RNR, "RNR" }, + { X25_REJ, "REJ" }, + { X25_DATA, "DATA" }, + { 0, NULL} +}; /* * each vc_info node contains : @@ -1017,41 +1059,44 @@ if (check_col(fd, COL_INFO)) col_add_str(fd, COL_INFO, "Invalid/short X.25 packet"); if (tree) - proto_tree_add_item_format(tree, proto_x25, localoffset, - fd->cap_len - offset, NULL, "Invalid/short X.25 packet"); + proto_tree_add_item_format(tree, (modulo == 8 ? proto_x25 : proto_ex25), + localoffset, fd->cap_len - offset, NULL, + "Invalid/short X.25 packet"); return; } - vc = (int)(pd[localoffset] & 0x0F) + (int)pd[localoffset+1]; + vc = (int)(pd[localoffset] & 0x0F)*256 + (int)pd[localoffset+1]; if (tree) { - ti = proto_tree_add_item(tree, proto_x25, localoffset, x25_pkt_len, - NULL); + ti = proto_tree_add_item(tree, (modulo == 8) ? proto_x25 : proto_ex25, + localoffset, x25_pkt_len, NULL); x25_tree = proto_item_add_subtree(ti, ETT_X25); - proto_tree_add_text(x25_tree, localoffset, 1, - "GFI : Q: %d, D: %d, Mod: %d", - (pd[localoffset] & 0x80) ? 1 : 0, - (pd[localoffset] & 0x40) ? 1 : 0, - modulo); - proto_tree_add_item_format(x25_tree, hf_x25_lcn, localoffset, 2, - (int)(pd[localoffset] & 0x0F) + - (int)pd[localoffset+1], - "Logical channel : %3.3X", - vc); + if (pd[localoffset] & 0x80) + proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_qbit : hf_ex25_qbit, + localoffset, 2, pd[localoffset]*256+pd[localoffset+1]); + if (pd[localoffset] & 0x40) + proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_dbit : hf_ex25_dbit, + localoffset, 2, pd[localoffset]*256+pd[localoffset+1]); + proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_mod : hf_ex25_mod, + localoffset, 2, pd[localoffset]*256+pd[localoffset+1]); } switch (pd[localoffset+2]) { case X25_CALL_REQUEST: if (pd[localoffset+2] & 0x80) /* TOA/NPI address format */ toa = TRUE; - if(check_col(fd, COL_INFO)) + if (check_col(fd, COL_INFO)) col_add_fstr(fd, COL_INFO, "%s VC:%d", (fd->pseudo_header.x25.flags & FROM_DCE) ? "Inc. call" : "Call req." , vc); - if (x25_tree) - proto_tree_add_item_format(x25_tree, hf_x25_type, localoffset+2, 1, - "CALL", + if (x25_tree) { + proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_lcn : hf_ex25_lcn, + localoffset, 2, pd[localoffset]*256+pd[localoffset+1]); + proto_tree_add_item_format(x25_tree, + (modulo == 8) ? hf_x25_type : hf_ex25_type, + localoffset+2, 1, X25_CALL_REQUEST, (fd->pseudo_header.x25.flags & FROM_DCE) ? "Incoming call" : "Call request"); + } localoffset += 3; if (localoffset < x25_pkt_len+offset) /* calling/called addresses */ x25_ntoa(x25_tree, &localoffset, &pd[localoffset], fd, toa); @@ -1099,11 +1144,15 @@ (fd->pseudo_header.x25.flags & FROM_DCE) ? "Call conn." : "Call acc." , vc); - if (x25_tree) - proto_tree_add_item_format(x25_tree, hf_x25_type, localoffset+2, 1, - "CALL ACC", + if (x25_tree) { + proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_lcn : hf_ex25_lcn, + localoffset, 2, pd[localoffset]*256+pd[localoffset+1]); + proto_tree_add_item_format(x25_tree, + (modulo == 8) ? hf_x25_type : hf_ex25_type, + localoffset+2, 1, X25_CALL_ACCEPTED, (fd->pseudo_header.x25.flags & FROM_DCE) ? "Call connected" : "Call accepted"); + } localoffset += 3; if (localoffset < x25_pkt_len+offset) /* calling/called addresses */ x25_ntoa(x25_tree, &localoffset, &pd[localoffset], fd, toa); @@ -1128,8 +1177,11 @@ } x25_hash_add_proto_end(vc, fd->abs_secs, fd->abs_usecs); if (x25_tree) { - proto_tree_add_item_format(x25_tree, hf_x25_type, localoffset+2, 1, - "CLEAR", + proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_lcn : hf_ex25_lcn, + localoffset, 2, pd[localoffset]*256+pd[localoffset+1]); + proto_tree_add_item_format(x25_tree, + (modulo == 8) ? hf_x25_type : hf_ex25_type, + localoffset+2, 1, X25_CLEAR_REQUEST, (fd->pseudo_header.x25.flags & FROM_DCE) ? "Clear indication" : "Clear request"); if (localoffset+3 < x25_pkt_len+offset) @@ -1148,9 +1200,12 @@ if(check_col(fd, COL_INFO)) col_add_fstr(fd, COL_INFO, "Clear Conf. VC:%d", vc); - if (x25_tree) - proto_tree_add_item_format(x25_tree, hf_x25_type, localoffset+2, 1, - "CLEAR CONF", "Clear confirmation"); + if (x25_tree) { + proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_lcn : hf_ex25_lcn, + localoffset, 2, pd[localoffset]*256+pd[localoffset+1]); + proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_type : hf_ex25_type, + localoffset+2, 1, X25_CLEAR_CONFIRMATION); + } localoffset += x25_pkt_len; if (localoffset < fd->cap_len) /* extended clear conf format */ @@ -1161,12 +1216,11 @@ break; case X25_DIAGNOSTIC: if(check_col(fd, COL_INFO)) { - col_add_fstr(fd, COL_INFO, "Diag. VC:%d %d", - vc, (int)pd[localoffset+3]); + col_add_fstr(fd, COL_INFO, "Diag. %d", (int)pd[localoffset+3]); } if (x25_tree) { - proto_tree_add_item_format(x25_tree, hf_x25_type, localoffset+2, 1, - "DIAG", "Diagnostic"); + proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_type : hf_ex25_type, + localoffset+2, 1, X25_DIAGNOSTIC); if (localoffset+3 < x25_pkt_len+offset) proto_tree_add_text(x25_tree, localoffset+3, 1, "Diagnostic : %d", (int)pd[localoffset+3]); @@ -1176,17 +1230,23 @@ case X25_INTERRUPT: if(check_col(fd, COL_INFO)) col_add_fstr(fd, COL_INFO, "Interrupt VC:%d", vc); - if (x25_tree) - proto_tree_add_item_format(x25_tree, hf_x25_type, localoffset+2, 1, - "INTR", "Interrupt"); + if (x25_tree) { + proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_lcn : hf_ex25_lcn, + localoffset, 2, pd[localoffset]*256+pd[localoffset+1]); + proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_type : hf_ex25_type, + localoffset+2, 1, X25_INTERRUPT); + } localoffset += x25_pkt_len; break; case X25_INTERRUPT_CONFIRMATION: if(check_col(fd, COL_INFO)) col_add_fstr(fd, COL_INFO, "Interrupt Conf. VC:%d", vc); - if (x25_tree) - proto_tree_add_item_format(x25_tree, hf_x25_type, localoffset+2, 1, - "INTR CONF", "Interrupt confirmation"); + if (x25_tree) { + proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_lcn : hf_ex25_lcn, + localoffset, 2, pd[localoffset]*256+pd[localoffset+1]); + proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_type : hf_ex25_type, + localoffset+2, 1, X25_INTERRUPT_CONFIRMATION); + } localoffset += x25_pkt_len; break; case X25_RESET_REQUEST: @@ -1199,8 +1259,11 @@ } x25_hash_add_proto_end(vc, fd->abs_secs, fd->abs_usecs); if (x25_tree) { - proto_tree_add_item_format(x25_tree, hf_x25_type, localoffset+2, 1, - "RESET", + proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_lcn : hf_ex25_lcn, + localoffset, 2, pd[localoffset]*256+pd[localoffset+1]); + proto_tree_add_item_format(x25_tree, + (modulo == 8) ? hf_x25_type : hf_ex25_type, localoffset+2, 1, + X25_RESET_REQUEST, (fd->pseudo_header.x25.flags & FROM_DCE) ? "Reset indication" : "Reset request"); if (localoffset+3 < x25_pkt_len+offset) @@ -1215,23 +1278,26 @@ case X25_RESET_CONFIRMATION: if(check_col(fd, COL_INFO)) col_add_fstr(fd, COL_INFO, "Reset conf. VC:%d", vc); - if (x25_tree) - proto_tree_add_item_format(x25_tree, hf_x25_type, localoffset+2, 1, - "RESET CONF", "Reset confirmation"); + if (x25_tree) { + proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_lcn : hf_ex25_lcn, + localoffset, 2, pd[localoffset]*256+pd[localoffset+1]); + proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_type : hf_ex25_type, + localoffset+2, 1, X25_RESET_CONFIRMATION); + } localoffset += x25_pkt_len; break; case X25_RESTART_REQUEST: if(check_col(fd, COL_INFO)) { - col_add_fstr(fd, COL_INFO, "%s VC:%d %s - Diag.:%d", + col_add_fstr(fd, COL_INFO, "%s %s - Diag.:%d", (fd->pseudo_header.x25.flags & FROM_DCE) ? "Restart ind." : "Restart req.", - vc, restart_code(pd[localoffset+3]), + restart_code(pd[localoffset+3]), (int)pd[localoffset+4]); } - x25_hash_add_proto_end(vc, fd->abs_secs, fd->abs_usecs); if (x25_tree) { - proto_tree_add_item_format(x25_tree, hf_x25_type, localoffset+2, 1, - "RESTART", + proto_tree_add_item_format(x25_tree, + (modulo == 8) ? hf_x25_type : hf_ex25_type, localoffset+2, 1, + X25_RESTART_REQUEST, (fd->pseudo_header.x25.flags & FROM_DCE) ? "Restart indication" : "Restart request"); if (localoffset+3 < x25_pkt_len+offset) @@ -1245,18 +1311,18 @@ break; case X25_RESTART_CONFIRMATION: if(check_col(fd, COL_INFO)) - col_add_fstr(fd, COL_INFO, "Restart conf. VC:%d", vc); + col_add_str(fd, COL_INFO, "Restart conf."); if (x25_tree) - proto_tree_add_item_format(x25_tree, hf_x25_type, localoffset+2, 1, - "RESTART CONF", "Restart confirmation"); + proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_type : hf_ex25_type, + localoffset+2, 1, X25_RESTART_CONFIRMATION); localoffset += x25_pkt_len; break; case X25_REGISTRATION_REQUEST: if(check_col(fd, COL_INFO)) - col_add_fstr(fd, COL_INFO, "Registration req. VC:%d", vc); + col_add_str(fd, COL_INFO, "Registration req."); if (x25_tree) - proto_tree_add_item_format(x25_tree, hf_x25_type, localoffset+2, 1, - "REG REQ", "Registration request"); + proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_type : hf_ex25_type, + localoffset+2, 1, X25_REGISTRATION_REQUEST); localoffset += 3; if (localoffset < x25_pkt_len+offset) x25_ntoa(x25_tree, &localoffset, &pd[localoffset], fd, FALSE); @@ -1273,10 +1339,10 @@ break; case X25_REGISTRATION_CONFIRMATION: if(check_col(fd, COL_INFO)) - col_add_fstr(fd, COL_INFO, "Registration conf. VC:%d", vc); + col_add_str(fd, COL_INFO, "Registration conf."); if (x25_tree) { - proto_tree_add_item_format(x25_tree, hf_x25_type, localoffset+2, 1, - "REG CONF", "Registration confirmation"); + proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_type : hf_ex25_type, + localoffset+2, 1, X25_REGISTRATION_CONFIRMATION); if (localoffset+3 < x25_pkt_len+offset) proto_tree_add_text(x25_tree, localoffset+3, 1, "Cause: %s", registration_code(pd[localoffset+3])); @@ -1317,41 +1383,32 @@ (pd[localoffset+1] & 0x01) ? " M" : ""); } if (x25_tree) { - proto_tree_add_item_format(x25_tree, hf_x25_type, localoffset, - 1, "DATA", "X.25 Data"); + proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_lcn : hf_ex25_lcn, + localoffset-2, 2, pd[localoffset-2]*256+pd[localoffset-1]); if (modulo == 8) { + proto_tree_add_item_hidden(x25_tree, hf_x25_type, localoffset, 1, + X25_DATA); + proto_tree_add_item(x25_tree, hf_x25_p_r, localoffset, 1, + pd[localoffset]); + if (pd[localoffset] & 0x10) + proto_tree_add_item(x25_tree, hf_x25_mbit, localoffset, 1, + pd[localoffset]); + proto_tree_add_item(x25_tree, hf_x25_p_s, localoffset, 1, + pd[localoffset]); proto_tree_add_text(x25_tree, localoffset, 1, - " %d%d%d..... : P(R) = %d", - (pd[localoffset] >> 7) & 0x01, - (pd[localoffset] >> 6) & 0x01, - (pd[localoffset] >> 5) & 0x01, - (pd[localoffset] >> 5) & 0x07); - proto_tree_add_text(x25_tree, localoffset, 1, - " ...%d.... : More bit", - (pd[localoffset] >> 4) & 0x01); - proto_tree_add_text(x25_tree, localoffset, 1, - " ....%d%d%d. : P(S) = %d", - (pd[localoffset] >> 3) & 0x01, - (pd[localoffset] >> 2) & 0x01, - (pd[localoffset] >> 1) & 0x01, - (pd[localoffset] >> 1) & 0x07); - proto_tree_add_text(x25_tree, localoffset, 1, - " .......0 : Packet type id = DATA"); + decode_boolean_bitfield(pd[localoffset], 0x01, 1*8, + NULL, "DATA")); } else { - proto_tree_add_text(x25_tree, localoffset+1, 1, - " %d%d%d%d%d%d%d. : P(S) = %d", - (pd[localoffset+1] >> 7) & 0x01, - (pd[localoffset+1] >> 6) & 0x01, - (pd[localoffset+1] >> 5) & 0x01, - (pd[localoffset+1] >> 4) & 0x01, - (pd[localoffset+1] >> 3) & 0x01, - (pd[localoffset+1] >> 2) & 0x01, - (pd[localoffset+1] >> 1) & 0x01, - pd[localoffset+1] >> 1); - proto_tree_add_text(x25_tree, localoffset, 1, - " .......%d : More bit", - pd[localoffset+1] & 0x01); + proto_tree_add_item_hidden(x25_tree, hf_ex25_type, localoffset, 1, + X25_DATA); + proto_tree_add_item(x25_tree, hf_x25_p_r, localoffset, 1, + pd[localoffset]); + proto_tree_add_item(x25_tree, hf_x25_p_s, localoffset+1, 1, + pd[localoffset+1]); + if (pd[localoffset+1] & 0x01) + proto_tree_add_item(x25_tree, hf_ex25_mbit, localoffset+1, 1, + pd[localoffset+1]); } } localoffset += (modulo == 8) ? 1 : 2; @@ -1369,14 +1426,18 @@ vc, pd[localoffset+1] >> 1); } if (x25_tree) { - if (modulo == 8) - proto_tree_add_item_format(x25_tree, hf_x25_type, - localoffset, 1, "RR", "RR P(R):%d", - (pd[localoffset] >> 5) & 0x07); - else - proto_tree_add_item_format(x25_tree, hf_x25_type, - localoffset, 2, "RR", "RR P(R):%d", - pd[localoffset+1] >> 1); + proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_lcn : hf_ex25_lcn, + localoffset-2, 2, pd[localoffset-2]*256+pd[localoffset-1]); + if (modulo == 8) { + proto_tree_add_item(x25_tree, hf_x25_p_r, + localoffset, 1, pd[localoffset]); + proto_tree_add_item(x25_tree, hf_x25_type, localoffset, 1, X25_RR); + } + else { + proto_tree_add_item(x25_tree, hf_ex25_type, localoffset, 1, X25_RR); + proto_tree_add_item(x25_tree, hf_ex25_p_r, + localoffset+1, 1, pd[localoffset+1]); + } } break; @@ -1390,14 +1451,18 @@ vc, pd[localoffset+1] >> 1); } if (x25_tree) { - if (modulo == 8) - proto_tree_add_item_format(x25_tree, hf_x25_type, - localoffset, 1, "RNR", "RNR P(R):%d", - (pd[localoffset] >> 5) & 0x07); - else - proto_tree_add_item_format(x25_tree, hf_x25_type, - localoffset, 2, "RNR", "RNR P(R):%d", - pd[localoffset+1] >> 1); + proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_lcn : hf_ex25_lcn, + localoffset-2, 2, pd[localoffset-2]*256+pd[localoffset-1]); + if (modulo == 8) { + proto_tree_add_item(x25_tree, hf_x25_p_r, + localoffset, 1, pd[localoffset]); + proto_tree_add_item(x25_tree, hf_x25_type, localoffset, 1, X25_RNR); + } + else { + proto_tree_add_item(x25_tree, hf_ex25_type, localoffset, 1, X25_RNR); + proto_tree_add_item(x25_tree, hf_ex25_p_r, + localoffset+1, 1, pd[localoffset+1]); + } } break; @@ -1411,14 +1476,18 @@ vc, pd[localoffset+1] >> 1); } if (x25_tree) { - if (modulo == 8) - proto_tree_add_item_format(x25_tree, hf_x25_type, - localoffset, 1, "REJ", "REJ P(R):%d", - (pd[localoffset] >> 5) & 0x07); - else - proto_tree_add_item_format(x25_tree, hf_x25_type, - localoffset, 2, "REJ", "REJ P(R):%d", - pd[localoffset+1] >> 1); + proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_lcn : hf_ex25_lcn, + localoffset-2, 2, pd[localoffset-2]*256+pd[localoffset-1]); + if (modulo == 8) { + proto_tree_add_item(x25_tree, hf_x25_p_r, + localoffset, 1, pd[localoffset]); + proto_tree_add_item(x25_tree, hf_x25_type, localoffset, 1, X25_REJ); + } + else { + proto_tree_add_item(x25_tree, hf_ex25_type, localoffset, 1, X25_REJ); + proto_tree_add_item(x25_tree, hf_ex25_p_r, + localoffset+1, 1, pd[localoffset+1]); + } } } localoffset += (modulo == 8) ? 1 : 2; @@ -1446,16 +1515,62 @@ void proto_register_x25(void) { - static hf_register_info hf[] = { + static hf_register_info hf8[] = { + { &hf_x25_qbit, + { "Q Bit", "x25.q", FT_BOOLEAN, 2, NULL, 0x8000, + "Qualifier Bit" } }, + { &hf_x25_qbit, + { "D Bit", "x25.d", FT_BOOLEAN, 2, NULL, 0x4000, + "Delivery Confirmation Bit" } }, + { &hf_x25_mod, + { "Modulo", "x25.mod", FT_UINT16, BASE_DEC, VALS(vals_modulo), 0x3000, + "Specifies whether the frame is modulo 8 or 128" } }, { &hf_x25_lcn, - { "Logical Channel", "x25.lcn", FT_UINT16, BASE_DEC, NULL, 0x0, - "" } }, - + { "Logical Channel", "x25.lcn", FT_UINT16, BASE_HEX, NULL, 0x0FFF, + "Logical Channel Number" } }, { &hf_x25_type, - { "Packet Type", "x25.type", FT_STRING, BASE_NONE, NULL, 0x0, - "" } }, + { "Packet Type", "x25.type", FT_UINT8, BASE_HEX, VALS(vals_x25_type), 0x0, + "Packet Type" } }, + { &hf_x25_p_r, + { "P(R)", "x25.p_r", FT_UINT8, BASE_HEX, NULL, 0xE0, + "Packet Receive Sequence Number" } }, + { &hf_x25_mbit, + { "M Bit", "x25.m", FT_BOOLEAN, 1, NULL, 0x10, + "More Bit" } }, + { &hf_x25_p_s, + { "P(S)", "x25.p_s", FT_UINT8, BASE_HEX, NULL, 0x0E, + "Packet Send Sequence Number" } }, + }; + + static hf_register_info hf128[] = { + { &hf_ex25_qbit, + { "Q Bit", "ex25.q", FT_BOOLEAN, 2, NULL, 0x8000, + "Qualifier Bit" } }, + { &hf_ex25_qbit, + { "D Bit", "ex25.d", FT_BOOLEAN, 2, NULL, 0x4000, + "Delivery Confirmation Bit" } }, + { &hf_ex25_mod, + { "Modulo", "ex25.mod", FT_UINT16, BASE_DEC, VALS(vals_modulo), 0x3000, + "Specifies whether the frame is modulo 8 or 128" } }, + { &hf_ex25_lcn, + { "Logical Channel", "ex25.lcn", FT_UINT16, BASE_HEX, NULL, 0x0FFF, + "Logical Channel Number" } }, + { &hf_ex25_type, + { "Packet Type", "ex25.type", FT_UINT8, BASE_HEX, VALS(vals_x25_type), 0x0, + "Packet Type" } }, + { &hf_ex25_p_r, + { "P(R)", "ex25.p_r", FT_UINT8, BASE_HEX, NULL, 0xFE, + "Packet Receive Sequence Number" } }, + { &hf_ex25_mbit, + { "M Bit", "ex25.m", FT_BOOLEAN, 1, NULL, 0x01, + "More Bit" } }, + { &hf_ex25_p_s, + { "P(S)", "ex25.p_s", FT_UINT8, BASE_HEX, NULL, 0xFE, + "Packet Send Sequence Number" } }, }; proto_x25 = proto_register_protocol ("X.25", "x25"); - proto_register_field_array (proto_x25, hf, array_length(hf)); + proto_ex25 = proto_register_protocol ("Extended X.25 (modulo 128)", "ex25"); + proto_register_field_array (proto_x25, hf8, array_length(hf8)); + proto_register_field_array (proto_ex25, hf128, array_length(hf128)); } diff -Nru ethereal/wiretap/Makefile.am ethereal.local/wiretap/Makefile.am --- ethereal/wiretap/Makefile.am Sat Oct 9 15:46:53 1999 +++ ethereal.local/wiretap/Makefile.am Sun Oct 17 21:11:43 1999 @@ -48,6 +48,8 @@ libpcap.h \ netmon.c \ netmon.h \ + nettl.c \ + nettl.h \ netxray.c \ netxray.h \ ngsniffer.c \ diff -Nru ethereal/wiretap/file.c ethereal.local/wiretap/file.c --- ethereal/wiretap/file.c Tue Oct 5 23:26:09 1999 +++ ethereal.local/wiretap/file.c Sun Oct 17 21:11:43 1999 @@ -36,6 +36,7 @@ #include "ngsniffer.h" #include "radcom.h" #include "ascend.h" +#include "nettl.h" #include "libpcap.h" #include "snoop.h" #include "iptrace.h" @@ -68,7 +69,8 @@ netmon_open, netxray_open, radcom_open, - ascend_open + ascend_open, + nettl_open }; int wtap_def_seek_read (FILE *fh, int seek_off, guint8 *pd, int len) diff -Nru ethereal/wiretap/nettl.c ethereal.local/wiretap/nettl.c --- ethereal/wiretap/nettl.c Thu Jan 1 01:00:00 1970 +++ ethereal.local/wiretap/nettl.c Sun Oct 17 21:11:52 1999 @@ -0,0 +1,147 @@ +/* nettl.c + * + * Wiretap Library + * Copyright (c) 1998 by Gilbert Ramirez <gram@xxxxxxxxxxxxxxxxxxx> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdlib.h> +#include <errno.h> +#include <time.h> +#include "wtap.h" +#include "file.h" +#include "buffer.h" +#include "nettl.h" + +static char nettl_magic[5] = { + 0x54, 0x52, 0x00, 0x64, 0x00 +}; + +/* HP nettl record header - The FCS is not included in the file. */ +struct nettlrec_hdr { + char xxa[12]; + char from_dce; + char xxb[55]; + guint16 length; + guint16 length2; /* don't know which one is captured length / real length */ + char xxc[4]; + char sec[4]; + char usec[4]; + char xxd[4]; +}; + +/* header is followed by data and once again the total length (2 bytes) ! */ + +static int nettl_read(wtap *wth, int *err); + +int nettl_open(wtap *wth, int *err) +{ + char magic[5]; + int bytes_read; + + /* Read in the string that should be at the start of a HP file */ + file_seek(wth->fh, 0, SEEK_SET); + errno = WTAP_ERR_CANT_READ; + bytes_read = file_read(magic, 1, 5, wth->fh); + if (bytes_read != 5) { + if (file_error(wth->fh)) { + *err = errno; + return -1; + } + return 0; + } + + if (memcmp(magic, nettl_magic, 5)) { + return 0; + } + + file_seek(wth->fh, 0x80, SEEK_SET); + wth->data_offset = 0x80; + + /* This is an nettl file */ + wth->file_type = WTAP_FILE_NETTL; + wth->capture.nettl = g_malloc(sizeof(nettl_t)); + wth->subtype_read = nettl_read; + wth->snapshot_length = 16384; /* not available in header, only in frame */ + + wth->capture.nettl->start = 0; + + wth->file_encap = WTAP_ENCAP_LAPB; + + return 1; +} + +/* Read the next packet */ +static int nettl_read(wtap *wth, int *err) +{ + int bytes_read; + struct nettlrec_hdr hdr; + guint16 length; + int data_offset; + + /* Read record header. */ + errno = WTAP_ERR_CANT_READ; + bytes_read = file_read(&hdr, 1, sizeof hdr, wth->fh); + if (bytes_read != sizeof hdr) { + if (file_error(wth->fh)) { + *err = errno; + return -1; + } + if (bytes_read != 0) { + *err = WTAP_ERR_SHORT_READ; + return -1; + } + return 0; + } + wth->data_offset += sizeof hdr; + length = pntohs(&hdr.length); + if (length <= 0) return 0; + + wth->phdr.len = length; + wth->phdr.caplen = length; + + wth->phdr.ts.tv_sec = pntohl(&hdr.sec); + wth->phdr.ts.tv_usec = pntohl(&hdr.usec); + if (wth->capture.nettl->start == 0) + wth->capture.nettl->start = wth->phdr.ts.tv_sec; + wth->phdr.pseudo_header.x25.flags = (hdr.from_dce & 0x20 ? 0x80 : 0x00); + + /* + * Read the packet data. + */ + buffer_assure_space(wth->frame_buffer, length); + data_offset = wth->data_offset; + errno = WTAP_ERR_CANT_READ; + bytes_read = file_read(buffer_start_ptr(wth->frame_buffer), 1, + length, wth->fh); + + if (bytes_read != length) { + if (file_error(wth->fh)) + *err = errno; + else + *err = WTAP_ERR_SHORT_READ; + return -1; + } + wth->data_offset += length; + + wth->phdr.pkt_encap = wth->file_encap; + + return data_offset; +} diff -Nru ethereal/wiretap/nettl.h ethereal.local/wiretap/nettl.h --- ethereal/wiretap/nettl.h Thu Jan 1 01:00:00 1970 +++ ethereal.local/wiretap/nettl.h Sun Oct 17 21:11:52 1999 @@ -0,0 +1,22 @@ +/* nettl.h + * + * Wiretap Library + * Copyright (c) 1998 by Gilbert Ramirez <gram@xxxxxxxxxxxxxxxxxxx> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +int nettl_open(wtap *wth, int *err); diff -Nru ethereal/wiretap/wtap.c ethereal.local/wiretap/wtap.c --- ethereal/wiretap/wtap.c Thu Oct 7 20:29:50 1999 +++ ethereal.local/wiretap/wtap.c Sun Oct 17 21:11:43 1999 @@ -98,6 +98,9 @@ case WTAP_FILE_ASCEND: return "Lucent/Ascend access server trace"; + case WTAP_FILE_NETTL: + return "HP-UX nettl traces"; + default: g_error("Unknown capture file type %d", wth->file_type); return NULL; @@ -182,6 +185,10 @@ case WTAP_FILE_ASCEND: g_free(wth->capture.ascend); + break; + + case WTAP_FILE_NETTL: + g_free(wth->capture.nettl); break; /* default: diff -Nru ethereal/wiretap/wtap.h ethereal.local/wiretap/wtap.h --- ethereal/wiretap/wtap.h Thu Oct 7 20:29:51 1999 +++ ethereal.local/wiretap/wtap.h Sun Oct 17 21:11:43 1999 @@ -93,7 +93,7 @@ #define WTAP_ENCAP_ASCEND 14 /* last WTAP_ENCAP_ value + 1 */ -#define WTAP_NUM_ENCAP_TYPES 15 +#define WTAP_NUM_ENCAP_TYPES 16 /* File types that can be read by wiretap. We may eventually support writing some or all of these file types, @@ -112,6 +112,7 @@ #define WTAP_FILE_NETXRAY_2_001 12 #define WTAP_FILE_RADCOM 13 #define WTAP_FILE_ASCEND 14 +#define WTAP_FILE_NETTL 15 /* * Maximum packet size we'll support. @@ -150,6 +151,10 @@ typedef struct { time_t start; +} nettl_t; + +typedef struct { + time_t start; } lanalyzer_t; typedef struct { @@ -305,6 +310,7 @@ lanalyzer_t *lanalyzer; ngsniffer_t *ngsniffer; radcom_t *radcom; + nettl_t *nettl; netmon_t *netmon; netxray_t *netxray; ascend_t *ascend; -- There's such a thing as too much point on a pencil. -- H. Allen Smith, "Let the Crabgrass Grow"
- Follow-Ups:
- Re: [ethereal-dev] patch for X.25 dissector and nettl file format
- From: Guy Harris
- Re: [ethereal-dev] patch for X.25 dissector and nettl file format
- Prev by Date: Re: [ethereal-dev] display filters with decimal values
- Next by Date: Re: [ethereal-dev] patch for X.25 dissector and nettl file format
- Previous by thread: Re: [ethereal-dev] display filters with decimal values
- Next by thread: Re: [ethereal-dev] patch for X.25 dissector and nettl file format
- Index(es):