diff -c -r tcpdump-3.7.1/print-ip.c tcpdump-3.7.1-dicom-20020428/print-ip.c *** tcpdump-3.7.1/print-ip.c Mon Sep 17 17:58:03 2001 --- tcpdump-3.7.1-dicom-20020428/print-ip.c Sun Apr 28 10:16:07 2002 *************** *** 1,3 **** --- 1,5 ---- + #define DICOM + /* * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 * The Regents of the University of California. All rights reserved. *************** *** 246,251 **** --- 248,580 ---- return (answer); } + #ifdef DICOM + /* + * print a DICOM command PDV. + */ + static void + print_dicom_command_pdv(const u_char *dp,long dlen,int indent) + { + char msg[65]; + char *indentstring; + switch (indent) { + case 0: indentstring=""; break; + case 1: indentstring="\t"; break; + case 2: indentstring="\t\t"; break; + case 3: indentstring="\t\t\t"; break; + default: indentstring="\t\t\t\t"; break; + } + + /* default_print_unaligned(dp,dlen); */ + ascii_print(dp,dlen); + + while (dlen > 0) { + unsigned short group; + unsigned short element; + unsigned long vl; + + if (dlen < 8) { + if (dlen == 1) + (void)printf("\n--DICOM-- %sMessage PDV one byte of trailing padding",indentstring,dlen); + else + (void)printf("\n--DICOM-- %sMessage PDV too short (%lu left) - incomplete attribute",indentstring,dlen); + break; + } + + #define EXTRACT16_DICOM_LE(p,i) (((unsigned short)p[i+1]<<8)+p[i]) + #define EXTRACT32_DICOM_LE(p,i) (((((((unsigned long)p[i+3]<<8)+p[i+2])<<8)+p[i+1])<<8)+p[i]) + + group=EXTRACT16_DICOM_LE(dp,0); + element=EXTRACT16_DICOM_LE(dp,2); + vl=EXTRACT32_DICOM_LE(dp,4); + + (void)printf("\n--DICOM-- %s(%04x,%04x) VL=%lu (0x%lx)\t",indentstring,group,element,vl,vl); + + if (group != 0) { + (void)printf(" non-command attribute - giving up parsing message",indentstring); + break; + } + else { + switch (element) { + case 0x0000: (void)printf(" Group Length"); + if (vl == 4) (void)printf(" = %lu",EXTRACT32_DICOM_LE(dp,8)); + else (void)printf(" bad length"); + break; + case 0x0002: (void)printf(" Affected SOP Class UID"); + if (vl > 0 && vl <= 64) { + strncpy(msg,dp+8,vl); + msg[vl]=0; + (void)printf(" = <%s>",msg); + } + else (void)printf(" bad length"); + break; + case 0x0003: (void)printf(" Requested SOP Class UID"); + if (vl > 0 && vl <= 64) { + strncpy(msg,dp+8,vl); + msg[vl]=0; + (void)printf(" = <%s>",msg); + } + else (void)printf(" bad length"); + break; + case 0x0100: (void)printf(" Command Field"); + if (vl == 2) { + unsigned short cmd=EXTRACT16_DICOM_LE(dp,8); + (void)printf(" = 0x%04x",cmd); + if (cmd == 0x0fff) + (void)printf(" C-CANCEL-xxxx-RQ"); + else { + switch(cmd & 0x7fff) { + case 0x0001: (void)printf(" C-STORE"); break; + case 0x0010: (void)printf(" C-GET"); break; + case 0x0020: (void)printf(" C-FIND"); break; + case 0x0021: (void)printf(" C-MOVE"); break; + case 0x0030: (void)printf(" C-ECHO"); break; + case 0x0100: (void)printf(" N-EVENT-REPORT"); break; + case 0x0110: (void)printf(" N-GET"); break; + case 0x0120: (void)printf(" N-SET"); break; + case 0x0130: (void)printf(" N-ACTION"); break; + case 0x0140: (void)printf(" N-CREATE"); break; + case 0x0150: (void)printf(" N-DELETE"); break; + } + (void)printf("-%s",(cmd&0x8000) ? "RSP" : "RQ"); + } + } + else (void)printf(" bad length"); + break; + case 0x0110: (void)printf(" Message ID"); + if (vl == 2) (void)printf(" = %u",EXTRACT16_DICOM_LE(dp,8)); + else (void)printf(" bad length"); + break; + case 0x0120: (void)printf(" Message ID Being Responded To"); + if (vl == 2) (void)printf(" = %u",EXTRACT16_DICOM_LE(dp,8)); + else (void)printf(" bad length"); + break; + case 0x0600: (void)printf(" Move Destination"); + if (vl > 0 && vl <= 16) { + strncpy(msg,dp+8,vl); + msg[vl]=0; + (void)printf(" = <%s>",msg); + } + else (void)printf(" bad length"); + break; + case 0x0700: (void)printf(" Priority"); + if (vl == 2) (void)printf(" = %u",EXTRACT16_DICOM_LE(dp,8)); + else (void)printf(" bad length"); + break; + case 0x0800: (void)printf(" Data Set Type"); + if (vl == 2) (void)printf(" = 0x%04x",EXTRACT16_DICOM_LE(dp,8)); + else (void)printf(" bad length"); + break; + case 0x0900: (void)printf(" Status"); + if (vl == 2) (void)printf(" = 0x%04x",EXTRACT16_DICOM_LE(dp,8)); + else (void)printf(" bad length"); + break; + case 0x1000: (void)printf(" Affected SOP Instance UID"); + if (vl > 0 && vl <= 64) { + strncpy(msg,dp+8,vl); + msg[vl]=0; + (void)printf(" = <%s>",msg); + } + else (void)printf(" bad length"); + break; + case 0x1001: (void)printf(" Requested SOP Instance UID"); + if (vl > 0 && vl <= 64) { + strncpy(msg,dp+8,vl); + msg[vl]=0; + (void)printf(" = <%s>",msg); + } + else (void)printf(" bad length"); + break; + case 0x1002: (void)printf(" Event Type ID"); + if (vl == 2) (void)printf(" = 0x%04x",EXTRACT16_DICOM_LE(dp,8)); + else (void)printf(" bad length"); + break; + case 0x1005: (void)printf(" Attribute Identifier List"); + break; + case 0x1020: (void)printf(" Number Of Remaining Suboperations"); + if (vl == 2) (void)printf(" = %u",EXTRACT16_DICOM_LE(dp,8)); + else (void)printf(" bad length"); + break; + case 0x1021: (void)printf(" Number Of Completed Suboperations"); + if (vl == 2) (void)printf(" = %u",EXTRACT16_DICOM_LE(dp,8)); + else (void)printf(" bad length"); + break; + case 0x1022: (void)printf(" Number Of Failed Suboperations"); + if (vl == 2) (void)printf(" = %u",EXTRACT16_DICOM_LE(dp,8)); + else (void)printf(" bad length"); + break; + case 0x1023: (void)printf(" Number Of Warning Suboperations"); + if (vl == 2) (void)printf(" = %u",EXTRACT16_DICOM_LE(dp,8)); + else (void)printf(" bad length"); + break; + case 0x1030: (void)printf(" Move Originator Application Entity Title"); + if (vl > 0 && vl <= 16) { + strncpy(msg,dp+8,vl); + msg[vl]=0; + (void)printf(" = <%s>",msg); + } + else (void)printf(" bad length"); + break; + case 0x1031: (void)printf(" Move Originator Message ID"); + if (vl == 2) (void)printf(" = %u",EXTRACT16_DICOM_LE(dp,8)); + else (void)printf(" bad length"); + break; + default: + break; + } + } + + dlen-=(vl+8); + dp+=(vl+8); + } + } + #endif + + #ifdef DICOM + /* + * print a DICOM associate request/response item list. + */ + static void + print_dicom_associate_pdu(const u_char *dp,long dlen,int indent) + { + char msg[65]; + int msglen; + char *indentstring; + switch (indent) { + case 0: indentstring=""; break; + case 1: indentstring="\t"; break; + case 2: indentstring="\t\t"; break; + case 3: indentstring="\t\t\t"; break; + default: indentstring="\t\t\t\t"; break; + } + + while (dlen > 0) { + unsigned short ilen; + if (dlen < 4) { + (void)printf("\n--DICOM-- %sItem too short - no length",indentstring); + break; + } + else { + ilen=EXTRACT_16BITS(dp+2); + } + + (void)printf("\n--DICOM-- %sItem %02x (length %u)",indentstring,(unsigned short)*dp,ilen); + + if (ilen+4 > dlen) { + (void)printf("\n--DICOM-- %sItem too long - greater than what is left in PDU",indentstring); + break; + } + + switch (*dp) { /* Item Type */ + case 0x10: (void)printf(" Application Context"); + msglen=ilen > 64 ? 64 : ilen; + if (ilen) { + strncpy(msg,dp+4,msglen); + msg[msglen]=0; + (void)printf("\n--DICOM-- %s\tApplication Context Name=%s",indentstring,msg); + } + break; + case 0x20: (void)printf(" Presentation Context (offered)"); + (void)printf("\n--DICOM-- %s\tPresentation Context ID=%u",indentstring,(unsigned short)dp[4]); + if (!(dp[4] & 0x01)) + (void)printf("\n--DICOM-- %sPresentation Context ID should not be even :(",indentstring); + if (ilen > 4) + print_dicom_associate_pdu(dp+8,ilen-4,indent+1); + break; + case 0x21: (void)printf(" Presentation Context (accepted)"); + (void)printf("\n--DICOM-- %s\tPresentation Context ID=%u",indentstring,(unsigned short)dp[4]); + if (!(dp[4] & 0x01)) + (void)printf("\n--DICOM-- %sPresentation Context ID should not be even :(",indentstring); + (void)printf("\n--DICOM-- %s\tResult/Reason=%u",indentstring,(unsigned short)*(dp+6)); + switch(*(dp+6)) { + case 0: (void)printf(" (acceptance)"); break; + case 1: (void)printf(" (user rejection)"); break; + case 2: (void)printf(" (no reason - provider rejection)"); break; + case 3: (void)printf(" (Abstract Syntax not supported - provider rejection)"); break; + case 4: (void)printf(" (Transfer Syntaxes not supported - provider rejection)"); break; + default: (void)printf(" (unrecognized)"); break; + } + if (ilen > 4) + print_dicom_associate_pdu(dp+8,ilen-4,indent+1); + break; + case 0x30: (void)printf(" Abstract Syntax"); + msglen=ilen > 64 ? 64 : ilen; + if (ilen) { + strncpy(msg,dp+4,msglen); + msg[msglen]=0; + (void)printf("\n--DICOM-- %s\tAbstract Syntax Name=%s",indentstring,msg); + } + break; + case 0x40: (void)printf(" Transfer Syntax"); + msglen=ilen > 64 ? 64 : ilen; + if (ilen) { + strncpy(msg,dp+4,msglen); + msg[msglen]=0; + (void)printf("\n--DICOM-- %s\tTransfer Syntax Name=%s",indentstring,msg); + } + break; + case 0x50: (void)printf(" User"); + if (ilen > 4) + print_dicom_associate_pdu(dp+4,ilen,indent+1); + break; + case 0x51: (void)printf(" Maximum Length"); + if (ilen != 4) + (void)printf("\n--DICOM-- %sbad length :(",indentstring); + else + (void)printf("\n--DICOM-- %s\tMaximum Length Received=%lu",indentstring,EXTRACT_32BITS(dp+4)); + break; + case 0x52: (void)printf(" Implementation Class UID"); + msglen=ilen > 64 ? 64 : ilen; + if (ilen) { + strncpy(msg,dp+4,msglen); + msg[msglen]=0; + (void)printf("\n--DICOM-- %s\tImplementation Class UID=%s",indentstring,msg); + } + break; + case 0x53: (void)printf(" Asynchronous Operations Window"); + if (ilen != 4) + (void)printf("\n--DICOM-- %sbad length :(",indentstring); + else { + (void)printf("\n--DICOM-- %s\tMaximum Number of Operations Invoked=%u",indentstring,EXTRACT_16BITS(dp+4)); + (void)printf("\n--DICOM-- %s\tMaximum Number of Operations Performed=%u",indentstring,EXTRACT_16BITS(dp+6)); + } + break; + case 0x54: (void)printf(" SCP/SCU Role Selection"); + if (ilen < 8) + (void)printf("\n--DICOM-- %sbad length :(",indentstring); + else { + u_char role; + unsigned short uidlen=EXTRACT_16BITS(dp+4); + (void)printf("\n--DICOM-- %s\tUID Length=%u",indentstring,uidlen); + msglen=uidlen > 64 ? 64 : uidlen; + if (uidlen) { + strncpy(msg,dp+6,msglen); + msg[msglen]=0; + (void)printf("\n--DICOM-- %s\tSOP Class UID=%s",indentstring,msg); + } + role=EXTRACT_16BITS(dp+6+uidlen); + (void)printf("\n--DICOM-- %s\tSCU Role=%u (%s)",indentstring,role,role ? "accept" : "reject"); + role=EXTRACT_16BITS(dp+6+uidlen+1); + (void)printf("\n--DICOM-- %s\tSCP Role=%u (%s)",indentstring,role,role ? "accept" : "reject"); + } + break; + case 0x55: (void)printf(" Implementation Version Name"); + msglen=ilen > 16 ? 16 : ilen; + if (ilen) { + strncpy(msg,dp+4,msglen); + msg[msglen]=0; + (void)printf("\n--DICOM-- %s\tImplementation Version Name=%s",indentstring,msg); + } + break; + default: (void)printf(" unrecognized"); + break; + } + dp+=(ilen+4); + dlen-=(ilen+4); + } + } + #endif + /* * print an IP datagram. */ *************** *** 548,553 **** --- 877,1035 ---- } printf(")"); } + #ifdef DICOM + if ((off & 0x1fff) == 0 && ip->ip_p == IPPROTO_TCP) { + unsigned short thlen; + unsigned short tlen; + const u_char *dp; + cp = (const u_char *)ip + hlen; + thlen=((cp[12] >> 4) & 0xf)*4; + tlen=len-thlen; + /* (void)printf("\n--DICOM-- TCP Header Length=%d",thlen); */ + /* (void)printf("\n--DICOM-- TCP Data Length=%d",tlen); */ + if (tlen) { + dp = (const u_char *)cp + thlen; + /* (void)printf("\n--DICOM-- PDU Type=0x%02x",dp[0]); */ + switch (dp[0]) { + case 1: { + /* Try to sure it is really a ASSOCIATE-RQ (and not a later packet + in a P-DATA-TF PDU) by sanity check on lengths */ + if (EXTRACT_32BITS(dp+2) + 6 >= tlen /* not == because may continue in next packet :( */ + && (unsigned long)(EXTRACT_32BITS(dp+2) + 6) <= 10000 /* arbitrary, but for sanity */ + && EXTRACT_32BITS(dp+2) >= 68 ) { + char msg[17]; + (void)printf("\n--DICOM-- PDU Type=0x%02x",dp[0]); + (void)printf(" ASSOCIATE-RQ"); + (void)printf("\n--DICOM-- \tPDU Length=%lu",EXTRACT_32BITS(dp+2)); + (void)printf("\n--DICOM-- \tProtocol Version=%u",EXTRACT_16BITS(dp+6)); + strncpy(msg,dp+10,16); msg[16]=0; + (void)printf("\n--DICOM-- \tCalled AE Title=%16s",msg); + strncpy(msg,dp+26,16); msg[16]=0; + (void)printf("\n--DICOM-- \tCalling AE Title=%16s",msg); + print_dicom_associate_pdu(dp+74,tlen-74,1); + } + } + break; + case 2: { + /* Try to sure it is really a ASSOCIATE-AC (and not a later packet + in a P-DATA-TF PDU) by sanity check on lengths */ + if (EXTRACT_32BITS(dp+2) + 6 >= tlen /* not == because may continue in next packet :( */ + && (unsigned long)(EXTRACT_32BITS(dp+2) + 6) <= 10000 /* arbitrary, but for sanity */ + && EXTRACT_32BITS(dp+2) >= 68 ) { + (void)printf("\n--DICOM-- PDU Type=0x%02x",dp[0]); + (void)printf(" ASSOCIATE-AC"); + (void)printf("\n--DICOM-- \tPDU Length=%lu",EXTRACT_32BITS(dp+2)); + (void)printf("\n--DICOM-- \tProtocol Version=%u",EXTRACT_16BITS(dp+6)); + print_dicom_associate_pdu(dp+74,tlen-74,1); + } + } + break; + case 3: { + /* Try to sure it is really a ASSOCIATE-RJ (and not a later packet + in a P-DATA-TF PDU) by sanity check on lengths */ + if (EXTRACT_32BITS(dp+2) + 6 == tlen + && EXTRACT_32BITS(dp+2) == 4 ) { + (void)printf("\n--DICOM-- PDU Type=0x%02x",dp[0]); + (void)printf(" ASSOCIATE-RJ"); + (void)printf("\n--DICOM-- \tPDU Length=%lu",EXTRACT_32BITS(dp+2)); + (void)printf("\n--DICOM-- \tResult=%u (%s)",(u_char)*(dp+7), + (*(dp+7) == 1 ? "permanent" : + (*(dp+7) == 2 ? "transient" : "unrecognized" ) ) ); + (void)printf("\n--DICOM-- \tSource of rejection=%u",(u_char)*(dp+8)); + switch (*(dp+8)) { + case 0: (void)printf(" (user)"); + (void)printf("\n--DICOM-- \tReason=%u",(u_char)*(dp+9)); + switch(*(dp+9)) { + case 1: (void)printf(" (no reason given)"); break; + case 2: (void)printf(" (ACN unsupported)"); break; + case 3: (void)printf(" (Calling AET unrecognized)"); break; + case 7: (void)printf(" (Called AET unrecognized)"); break; + default: (void)printf(" (reserved or unrecognized)"); break; + } + break; + case 1: (void)printf(" (provider - ACSE)"); + (void)printf("\n--DICOM-- \tReason=%u",(u_char)*(dp+9)); + switch(*(dp+9)) { + case 1: (void)printf(" (no reason given)"); break; + case 2: (void)printf(" (protocol version unsupported)"); break; + default: (void)printf(" (reserved or unrecognized)"); break; + } + break; + case 2: (void)printf(" (provider - Presentation)"); + (void)printf("\n--DICOM-- \tReason=%u",(u_char)*(dp+9)); + switch(*(dp+9)) { + case 1: (void)printf(" (temporary congestion)"); break; + case 2: (void)printf(" (local limit exceeded)"); break; + default: (void)printf(" (reserved or unrecognized)"); break; + } + break; + default: (void)printf(" (unrecognized)"); + (void)printf("\n--DICOM-- \tReason=%u",(u_char)*(dp+9)); + break; + } + } + } + break; + case 4: { + /* Try to sure it is really a first P-DATA-TF (and not a later packet + in a P-DATA-TF PDU) by sanity check on lengths */ + if (EXTRACT_32BITS(dp+2) + 6 >= tlen /* not == because may continue in next packet :( */ + && EXTRACT_32BITS(dp+6) + 4 <= EXTRACT_32BITS(dp+2) ) { + (void)printf("\n--DICOM-- PDU Type=0x%02x",dp[0]); + (void)printf(" P-DATA-TF"); + (void)printf("\n--DICOM-- \tPDU Length=%lu",EXTRACT_32BITS(dp+2)); + (void)printf("\n--DICOM-- \tFirst PDV Item Length=%lu",EXTRACT_32BITS(dp+6)); + (void)printf("\n--DICOM-- \tFirst PDV Pres Ctx ID=%u",(u_char)*(dp+10)); + (void)printf("\n--DICOM-- \tFirst PDV Message Control Header=%02x (%s,%s)", + (u_char)*(dp+11), + (*(dp+11) & 0x01) ? "Command" : "Data", + (*(dp+11) & 0x02) ? "Last" : "Not Last"); + if (*(dp+11) & 0x01) print_dicom_command_pdv(dp+12,min(EXTRACT_32BITS(dp+6)-2,tlen-12),1); + } + } + break; + case 5: { + /* Try to sure it is really a A-RELEASE-RQ (and not a later packet + in a P-DATA-TF PDU) by sanity check on lengths */ + if (EXTRACT_32BITS(dp+2) + 6 == tlen + && EXTRACT_32BITS(dp+2) == 4 ) { + (void)printf("\n--DICOM-- PDU Type=0x%02x",dp[0]); + (void)printf(" A-RELEASE-RQ"); + (void)printf("\n--DICOM-- \tPDU Length=%lu",EXTRACT_32BITS(dp+2)); + } + } + break; + case 6: { + /* Try to sure it is really a A-RELEASE-RP (and not a later packet + in a P-DATA-TF PDU) by sanity check on lengths */ + if (EXTRACT_32BITS(dp+2) + 6 == tlen + && EXTRACT_32BITS(dp+2) == 4 ) { + (void)printf("\n--DICOM-- PDU Type=0x%02x",dp[0]); + (void)printf(" A-RELEASE-RP"); + (void)printf("\n--DICOM-- \tPDU Length=%lu",EXTRACT_32BITS(dp+2)); + } + } + break; + case 7: { + /* Try to sure it is really a A-ABORT (and not a later packet + in a P-DATA-TF PDU) by sanity check on lengths */ + if (EXTRACT_32BITS(dp+2) + 6 == tlen + && EXTRACT_32BITS(dp+2) == 4 ) { + (void)printf("\n--DICOM-- PDU Type=0x%02x",dp[0]); + (void)printf(" A-ABORT"); + (void)printf("\n--DICOM-- \tPDU Length=%lu",EXTRACT_32BITS(dp+2)); + (void)printf("\n--DICOM-- \tSource of abort=%u (%s)",(u_char)*(dp+8), + (*(dp+8) == 0 ? "user" : + (*(dp+8) == 1 ? "rsvd" : + (*(dp+8) == 2 ? "provider" : "unrecognized" ) ) ) ); + } + } + break; + default: break; + } + } + } + #endif } void *************** *** 575,577 **** --- 1057,1062 ---- return; } } + + + diff -c -r tcpdump-3.7.1/tcpdump.dicom.README tcpdump-3.7.1-dicom-20020428/tcpdump.dicom.README *** tcpdump-3.7.1/tcpdump.dicom.README Sun Apr 28 10:29:22 2002 --- tcpdump-3.7.1-dicom-20020428/tcpdump.dicom.README Sun Apr 28 10:25:48 2002 *************** *** 0 **** --- 1,156 ---- + 20020428 DAC. + + Patches to print-ip.c to (always) try to detect DICOM + packets, identify and parse them (to a limited extent). + + This is no substitute for CTN dcm_snoop, but does not rely + on the DICOM FSM to maintain synchronization, and does have + the advantage of all the other tcpdump goodies, as well as + its extreme portability to almost every Unix system. + + No command line option to turn this on or off yet. + + Note that there is no DICOM "protocol identifier" in each TCP/IP + packet ... one has to guess that the packet is the first of + a series of packets that may be written (without IP fragmentation) + as a consequence of having a long DICOM PDU size ... the data + just runs over into the next packet without any DICOM "header". + + Blech. Who missed this one ? + + Anyway, guestimates are made based on the possible PDU Types and + the corresponding sane combinations of lengths to identify + packets. Sometimes this errs and tries to describe a packet + that is a non-first packet of a P-DATA-TF PDU ... this is + usually pretty obvious from the resulting garbage. + + The parsing effort is pretty modest, but helpful, and is easily + extended. So far there is no effort to parse the DICOM dataset + in data (rather than command) PDVs, partly due to reluctance + to deal with the transfer syntax perumtations, although I + guess there aren't that many. + + The DICOM stuff is (mostly) identifiable by the "--DICOM--" + prefix ... the output is interspersed with all the normal + tcpdump output and all the usual tcpdump options still work. + + Note that if the snaplength is too short the parser will get + lost in each packet quickly ... the default is too short + for most commands and the ASSOCIATE-RQ. 1500 is a good value + and works on both Irix 6.2 and Solaris 5.5.1 as far as + I have tested. + + Note that even so, particularly long ASSOCIATE-RQ (and even + ASSOCIATE-AC) will sometimes span two packets, so you will + only see the first packet parsed and then truncated :( + + Nothing can be done about his without trying to preserve + state between packets which may in theory arrive in any + order, which is currently in the too hard category. + + Note that some senders may put the PDU and the PDV containing the command in the + same packet, which dumps nicely, and other may write the PDU header first, and send + the PDV containing the command in the next header, in which case it won't get + parsed and displayed ... see for example the C-ECHO-RQ which does dump the command + PDV and the C-ECHO-RSP which does not). + + You should be selective about the hosts and or ports on the + command line to reduce the chance of trying to parse non-DICOM + tcp/ip packets (which as mentioned are not identifiable in + any way except by where they go to/come from). + + Of course, you need to be root to run these. + + EXAMPLE + + An example of listening in on a C-ECHO, running on RH Linux 7.2: + + # tcpdump -i eth0 -s 8192 host flagship and host 192.168.1.105 and '(' dst port 4006 or src port 4006 ')' + tcpdump: listening on eth0 + 10:16:33.543559 192.168.1.105.34494 > flagship.4006: S 1469509135:1469509135(0) win 5840 (DF) + 10:16:33.543559 flagship.4006 > 192.168.1.105.34494: S 1944204164:1944204164(0) ack 1469509136 win 5792 (DF) + 10:16:33.543559 192.168.1.105.34494 > flagship.4006: . ack 1 win 5840 (DF) + 10:16:33.543559 192.168.1.105.34494 > flagship.4006: P 1:150(149) ack 1 win 5840 (DF) + --DICOM-- PDU Type=0x01 ASSOCIATE-RQ + --DICOM-- PDU Length=143 + --DICOM-- Protocol Version=1 + --DICOM-- Called AE Title=STORESCP + --DICOM-- Calling AE Title=STORESCU + --DICOM-- Item 10 (length 21) Application Context + --DICOM-- Application Context Name=1.2.840.10008.3.1.1.1 + --DICOM-- Item 20 (length 46) Presentation Context (offered) + --DICOM-- Presentation Context ID=1 + --DICOM-- Item 30 (length 17) Abstract Syntax + --DICOM-- Abstract Syntax Name=1.2.840.10008.1.1 + --DICOM-- Item 40 (length 17) Transfer Syntax + --DICOM-- Transfer Syntax Name=1.2.840.10008.1.2 + 10:16:33.543559 flagship.4006 > 192.168.1.105.34494: . ack 150 win 5792 (DF) + 10:16:33.553559 flagship.4006 > 192.168.1.105.34494: P 1:191(190) ack 150 win 5792 (DF) + --DICOM-- PDU Type=0x02 ASSOCIATE-AC + --DICOM-- PDU Length=184 + --DICOM-- Protocol Version=1 + --DICOM-- Item 10 (length 21) Application Context + --DICOM-- Application Context Name=1.2.840.10008.3.1.1.1 + --DICOM-- Item 21 (length 25) Presentation Context (accepted) + --DICOM-- Presentation Context ID=1 + --DICOM-- Result/Reason=0 (acceptance) + --DICOM-- Item 40 (length 17) Transfer Syntax + --DICOM-- Transfer Syntax Name=1.2.840.10008.1.2 + --DICOM-- Item 50 (length 58) User + --DICOM-- Item 51 (length 4) Maximum Length + --DICOM-- Maximum Length Received=16384 + --DICOM-- Item 52 (length 27) Implementation Class UID + --DICOM-- Implementation Class UID=1.2.276.0.7230010.3.0.3.5.1 + --DICOM-- Item 55 (length 15) Implementation Version Name + --DICOM-- Implementation Version Name=OFFIS_DCMTK_351 + 10:16:33.553559 192.168.1.105.34494 > flagship.4006: . ack 191 win 6432 (DF) + 10:16:33.613559 192.168.1.105.34494 > flagship.4006: P 150:230(80) ack 191 win 6432 (DF) + --DICOM-- PDU Type=0x04 P-DATA-TF + --DICOM-- PDU Length=74 + --DICOM-- First PDV Item Length=70 + --DICOM-- First PDV Pres Ctx ID=1 + --DICOM-- First PDV Message Control Header=03 (Command,Last) + 0x0000 0000 0000 0400 0000 3800 0000 0000 0200 ........8....... + 0x0010 1200 0000 312e 322e 3834 302e 3130 3030 ....1.2.840.1000 + 0x0020 382e 312e 3120 0000 0001 0200 0000 3000 8.1.1.........0. + 0x0030 0000 1001 0200 0000 0100 0000 0008 0200 ................ + 0x0040 0000 0101 .... + --DICOM-- (0000,0000) VL=4 (0x4) Group Length = 56 + --DICOM-- (0000,0002) VL=18 (0x12) Affected SOP Class UID = <1.2.840.10008.1.1 > + --DICOM-- (0000,0100) VL=2 (0x2) Command Field = 0x0030 C-ECHO-RQ + --DICOM-- (0000,0110) VL=2 (0x2) Message ID = 1 + --DICOM-- (0000,0800) VL=2 (0x2) Data Set Type = 0x0101 + 10:16:33.623559 flagship.4006 > 192.168.1.105.34494: P 191:203(12) ack 230 win 5792 (DF) + --DICOM-- PDU Type=0x04 P-DATA-TF + --DICOM-- PDU Length=84 + --DICOM-- First PDV Item Length=80 + --DICOM-- First PDV Pres Ctx ID=1 + --DICOM-- First PDV Message Control Header=03 (Command,Last) + 10:16:33.623559 192.168.1.105.34494 > flagship.4006: . ack 203 win 6432 (DF) + 10:16:33.623559 flagship.4006 > 192.168.1.105.34494: P 203:281(78) ack 230 win 5792 (DF) + 10:16:33.623559 192.168.1.105.34494 > flagship.4006: . ack 281 win 6432 (DF) + 10:16:33.643559 192.168.1.105.34494 > flagship.4006: P 230:240(10) ack 281 win 6432 (DF) + --DICOM-- PDU Type=0x05 A-RELEASE-RQ + --DICOM-- PDU Length=4 + 10:16:33.643559 flagship.4006 > 192.168.1.105.34494: P 281:291(10) ack 240 win 5792 (DF) + --DICOM-- PDU Type=0x06 A-RELEASE-RP + --DICOM-- PDU Length=4 + 10:16:33.643559 192.168.1.105.34494 > flagship.4006: F 240:240(0) ack 291 win 6432 (DF) + 10:16:33.643559 flagship.4006 > 192.168.1.105.34494: F 291:291(0) ack 241 win 5792 (DF) + 10:16:33.643559 192.168.1.105.34494 > flagship.4006: . ack 292 win 6432 (DF) + + CHANGELOG + + 19971014 First released + + 20020428 Changes + + Revised to support tcpdump-3.7.1 + + Use ascii-print() that is present for new -X option rather than modifying + default_print_unaligned() in tcpdump.c. + + Fixed to work on little-endian machines (was converting network byte order twice) + + Don't dump PDV's beyond length of buffer (i.e. rest of PDV may be in next packet) ! +