// TCPMessage.java package protocol; // protocol package import support.*; // import Jasper support classes /** This is the class for a TCP segment. @author Iain A. Robin, Kenneth J. Turner @version 1.0 (1st September 1999, IAR): initial version
1.4 (9th March 2006, KJT): updated for JDK 1.5
1.5 (26th July 2010, KJT): minor tidying, proper "toString" method added */ public class TCPMessage extends PDU { /** Urgent flag */ public final static int URG = 32; /** Acknowledgement flag */ public final static int ACK = 16; /** Push flag */ public final static int PSH = 8; /** Reset flag */ public final static int RST = 4; /** Synchronise flag */ public final static int SYN = 2; /** Finish flag */ public final static int FIN = 1; /** Acknowledgement sequence number */ protected int ack = -1; /** Flag setting */ protected int flags = 0; /** Window sequence number */ protected int win = -1; /** Protocol flags */ protected boolean urgFlag, ackFlag, pshFlag, rstFlag, synFlag, finFlag; /** Constructor for a TCP segment. @param seq sequence number @param flags flags @param size message size */ public TCPMessage(int seq, int flags, int size) { this.seq = seq; this.flags = flags; setFlags(); this.size = size; } /** Constructor for a TCP segment. @param seq sequence number @param ack acknowlegement sequence number @param flags flags @param size message size */ public TCPMessage(int seq, int ack, int flags, int size) { this.seq = seq; this.ack = ack; this.flags = flags; setFlags(); this.size = size; } /** Return the label of a TCP segment. @return segment label */ public String getLabel() { // return label for arrow representing this segment // in a time sequence diagram String label = ""; if (size > 0) label += "Seq " + seq + ", "; if (ackFlag) label += "Ack " + ack + ", "; if (win >= 0) label += "Win " + win; if (urgFlag) label += ", URG"; if (pshFlag) label += ", PSH"; if (rstFlag) label += ", RST"; if (synFlag) label += ", SYN"; if (finFlag) label += ", FIN"; return (label); } /** Return the Acknowledgement attribute of a TCP segment. @return Acknowledgement value */ public boolean isAck() { return (ackFlag); } /** Return the Finish attribute of a TCP segment. @return Finish value */ public boolean isFin() { return (finFlag); } /** Return the Push attribute of a TCP segment. @return Push value */ public boolean isPsh() { return (pshFlag); } /** Return the Reset attribute of a TCP segment. @return Reset value */ public boolean isRst() { return (rstFlag); } /** Return the Synchronise attribute of a TCP segment. @return Synchronise value */ public boolean isSyn() { return (synFlag); } /** Return the Urgent attribute of a TCP segment. @return Urgent value */ public boolean isUrg() { return (urgFlag); } /** Check if the given PDU matches this one. @param pdu PDU @return true/false if PDU does/does not match */ public boolean matches(PDU pdu) { if (pdu == null) return (false); if (this.getSource() != pdu.getSource()) // entities must match return (false); TCPMessage tcpdu = (TCPMessage) pdu; // if both segments have valid ACK numbers, check that they match if (this.isAck() && tcpdu.isAck() && this.ack != tcpdu.ack) return (false); return (this.seq == tcpdu.seq && this.flags == tcpdu.flags); } /** Set the flags attribute of the TCPMessage object */ private void setFlags() { int f = flags; finFlag = f % 2 > 0; f /= 2; synFlag = f % 2 > 0; f /= 2; rstFlag = f % 2 > 0; f /= 2; pshFlag = f % 2 > 0; f /= 2; ackFlag = f % 2 > 0; f /= 2; urgFlag = f % 2 > 0; } /** Set the window size of a TCP message. @param win window size */ public void setWindowSize(int win) { if (win >= 0) this.win = win; } /** Convert a PDU to a string representation. @return string representation of a PDU */ public String toString() { return ("PDU <" + getLabel() + ">"); } }