package org.mobicents.protocols.ss7.tools.simulator.level1; import java.io.ByteArrayOutputStream; import java.io.FileOutputStream; import java.io.IOException; import org.mobicents.protocols.ss7.m3ua.impl.M3UAManagementImpl; import org.mobicents.protocols.ss7.mtp.Mtp3TransferPrimitive; public class M3UAManagementProxyImpl extends M3UAManagementImpl { private String pcapTraceName; public M3UAManagementProxyImpl(String name) { super(name, null); } public void startPcapTrace(String fileName) { this.pcapTraceName = fileName; this.startPcapTrace(); } @Override public void sendMessage(Mtp3TransferPrimitive mtp3TransferPrimitive) throws IOException { super.sendMessage(mtp3TransferPrimitive); this.storeTransferMessageToPcap(mtp3TransferPrimitive, true); } @Override public void sendTransferMessageToLocalUser(Mtp3TransferPrimitive msg, int seqControl) { super.sendTransferMessageToLocalUser(msg, seqControl); this.storeTransferMessageToPcap(msg, false); } private synchronized void startPcapTrace() { try { FileOutputStream fs = new FileOutputStream(this.pcapTraceName, false); // pcap global header fs.write(0xd4); fs.write(0xc3); fs.write(0xb2); fs.write(0xa1); fs.write(2); fs.write(0); fs.write(4); fs.write(0); fs.write(0); fs.write(0); fs.write(0); fs.write(0); fs.write(0); fs.write(0); fs.write(0); fs.write(0); fs.write(0xFF); fs.write(0xFF); fs.write(0); fs.write(0); fs.write(1); fs.write(0); fs.write(0); fs.write(0); fs.close(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } private int tsnNum = 1; private void storeTransferMessageToPcap(Mtp3TransferPrimitive msg, boolean localOriginated) { if (this.pcapTraceName == null) return; try { // pcap version // m3ua part byte[] sccpPart = msg.getData(); ByteArrayOutputStream stm1 = new ByteArrayOutputStream(); stm1.write(1); // m3ua version - release 1 stm1.write(0); // m3ua reserved stm1.write(1); // m3ua message class - Transfer message stm1.write(1); // m3ua Message type - Payload data int lenb = sccpPart.length + 16; int lena = lenb + 8; int m3uaPad = lena % 4; if (m3uaPad > 0) m3uaPad = 4 - m3uaPad; lena += m3uaPad; stm1.write(0); // m3ua Payload data length stm1.write(0); stm1.write(lena / 256); stm1.write(lena % 256); stm1.write(2); // Parameter tag: protocol data stm1.write(0x10); stm1.write(lenb / 256); // protocol data length stm1.write(lenb % 256); // m3ua opc stm1.write(msg.getOpc() >> 24); stm1.write(msg.getOpc() >> 16); stm1.write(msg.getOpc() >> 8); stm1.write(msg.getOpc()); // m3ua dpc stm1.write(msg.getDpc() >> 24); stm1.write(msg.getDpc() >> 16); stm1.write(msg.getDpc() >> 8); stm1.write(msg.getDpc()); stm1.write(msg.getSi()); stm1.write(msg.getNi()); stm1.write(msg.getMp()); stm1.write(msg.getSls()); stm1.write(sccpPart); for (int i1 = 0; i1 < m3uaPad; i1++) { stm1.write(0); } byte[] m3uaPart = stm1.toByteArray(); // sctp part ByteArrayOutputStream stm2 = new ByteArrayOutputStream(); stm2.write(1); // source port stm2.write(1); stm2.write(2); // dest port stm2.write(2); stm2.write(3); // verification tag stm2.write(3); stm2.write(3); stm2.write(3); stm2.write(4); // checksum - not really calculated stm2.write(4); stm2.write(4); stm2.write(4); int lenc = m3uaPart.length + 16; stm2.write(0); // chunk type - data stm2.write(3); // chunk flags stm2.write(lenc / 256); // chunk length stm2.write(lenc % 256); tsnNum++; stm2.write(tsnNum); // TSN stm2.write(0); stm2.write(0); stm2.write(0); stm2.write(0); // stream identifier stm2.write(3); stm2.write(11); // stream sequence number stm2.write(11); stm2.write(0); // protocol identifier - m3ua stm2.write(0); stm2.write(0); stm2.write(3); stm2.write(m3uaPart); byte[] sctpPart = stm2.toByteArray(); // ip V4 part ByteArrayOutputStream stm3 = new ByteArrayOutputStream(); int lend = sctpPart.length + 20; stm3.write(0x45); // version 4 + headerLen=20 stm3.write(0xe0); // dscp + ecn stm3.write(lend / 256); // total length stm3.write(lend % 256); stm3.write(10); // identification stm3.write(11); stm3.write(0); // flags + fragment offset stm3.write(0); stm3.write(0x40); // time to live stm3.write(0x84); // protocol: sctp stm3.write(0); // checksum: not really checked stm3.write(0); stm3.write(1); // source ip address stm3.write(2); stm3.write(3); stm3.write(4); stm3.write(4); // dest ip address stm3.write(3); stm3.write(2); stm3.write(1); stm3.write(sctpPart); byte[] ipPart = stm3.toByteArray(); // calculating ip header checksum int ix = 0; for (int i1 = 0; i1 < 10; i1++) { int ii1 = ipPart[i1 * 2] & 0xFF; int ii2 = ipPart[i1 * 2 + 1] & 0xFF; ix += (ii1 << 8) + ii2; } int iy = ix & 0xFFFF; int iz = iy ^ 0xFFFF; ipPart[10] = (byte) (iz / 256); ipPart[11] = (byte) (iz % 256); // Ethernet part ByteArrayOutputStream stm4 = new ByteArrayOutputStream(); stm4.write(8); // source stm4.write(8); stm4.write(8); stm4.write(8); stm4.write(8); stm4.write(8); stm4.write(6); // destination stm4.write(6); stm4.write(6); stm4.write(6); stm4.write(6); stm4.write(6); stm4.write(8); // type: ip stm4.write(0); stm4.write(ipPart); byte[] ethPart = stm4.toByteArray(); // pcap header FileOutputStream fs = new FileOutputStream(this.pcapTraceName, true); int ln = ethPart.length; fs.write(0); fs.write(0); fs.write(0); fs.write(0); fs.write(0); fs.write(0); fs.write(0); fs.write(0); fs.write(ln % 256); fs.write(ln / 256); fs.write(0); fs.write(0); fs.write(ln % 256); fs.write(ln / 256); fs.write(0); fs.write(0); // pcap data fs.write(ethPart); fs.close(); // MsgLog.txt version // byte[] txData = msg.encodeMtp3(); // FileOutputStream fs = new FileOutputStream("MsgLog.txt", true); // int ln = txData.length; // fs.write(ln & 0xFF); // fs.write(ln >> 8); // fs.write(txData); // fs.close(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }