Skip to content

Conversation

@tmart234
Copy link

Summary

DICOM communications is used in medical imaging systems. This PR adds Scapy layers for the DICOM Upper Layer Protocol (DICOM PS3.8).

Features

  • Full PDU support: A-ASSOCIATE-RQ/AC/RJ, P-DATA-TF, A-RELEASE-RQ/RP, A-ABORT
  • Variable item negotiation: Application Context, Presentation Context, User Information, User Identity, Async Operations, Role Selection
  • DIMSE command packets: C-ECHO, C-STORE, C-FIND, C-MOVE, C-GET

Usage

from scapy.contrib.dicom import *

# Build an A-ASSOCIATE-RQ
pkt = DICOM() / A_ASSOCIATE_RQ(
    called_ae_title=_pad_ae_title("SERVER"),
    calling_ae_title=_pad_ae_title("CLIENT"),
    variable_items=[
        DICOMVariableItem() / DICOMApplicationContext(),
        build_presentation_context_rq(1, VERIFICATION_SOP_CLASS_UID, [DEFAULT_TRANSFER_SYNTAX_UID]),
        build_user_information(max_pdu_length=16384),
    ]
)

# Build a C-MOVE-RQ
move_rq = C_MOVE_RQ(message_id=1, move_destination=b"DEST_AE")

Testing

  • 59 unit tests in test/contrib/dicom.uts
  • All tests pass on Python 3.9+

References

@codecov
Copy link

codecov bot commented Dec 30, 2025

Codecov Report

❌ Patch coverage is 47.57282% with 378 lines in your changes missing coverage. Please review.
✅ Project coverage is 80.35%. Comparing base (40fc5ec) to head (ea5cced).

Files with missing lines Patch % Lines
scapy/contrib/dicom.py 47.57% 378 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #4891      +/-   ##
==========================================
- Coverage   80.85%   80.35%   -0.50%     
==========================================
  Files         369      370       +1     
  Lines       90961    91682     +721     
==========================================
+ Hits        73542    73671     +129     
- Misses      17419    18011     +592     
Files with missing lines Coverage Δ
scapy/contrib/dicom.py 47.57% <47.57%> (ø)

... and 20 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@polydroi
Copy link

Thanks for the PR. I’ve stared the unit tests. Looks good, however, could you please add type hints to your layer?

0x59: "User Identity Server Response",
}

def _pad_ae_title(title):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would recommend to introduced a StrFixedLenFieldWithPadding instead of the explicit call to the padding function for certain fields

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have a PadField for that ! You can use pas with=" "

class DICOMTransferSyntax(Packet):
name = "DICOM Transfer Syntax"
fields_desc = [
StrLenField("uid", _uid_to_bytes(DEFAULT_TRANSFER_SYNTAX_UID),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I recommend to create a dedicated UID field (e.g. DICOMUIDField) which applies "_uid_to_bytes" internally.


return DICOMVariableItem() / DICOMUserInformation(sub_items=sub_items)

class DICOMSession:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would recommend to use a different "name", since Scapy uses the term "Session" for a different term. From you implementation, I would treat this class as a "DICOMSocket". This would indicate the application layer functionality.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants