public void UpdateSlots(LinkedList <NormalBurst> bursts) { CleanupLamps(bursts); foreach (NormalBurst burst in bursts) { if (burst.Direction == LibRXFFT.Libraries.GSM.Layer1.eLinkDirection.Downlink) { StatusLamp lamp = GetLamp(burst); string status = "---"; switch (burst.State) { case NormalBurst.eBurstState.Idle: status = "Idle"; lamp.State = eLampState.Grayed; break; case NormalBurst.eBurstState.PlainTraffic: status = "not encrypted"; lamp.State = eLampState.Green; break; case NormalBurst.eBurstState.CryptedTraffic: status = "encrypted"; lamp.State = eLampState.Red; break; case NormalBurst.eBurstState.DecryptedTraffic: status = "encrypted (Kc: " + ByteUtil.BytesToString(burst.A5CipherKey) + ")"; lamp.State = eLampState.Yellow; break; } lock (BurstLampMap) { BurstStatusMap[burst] = status; } lock (lblDetails) { if (CurrentHoveredBurst == burst) { string msg = "[" + burst.Name + "], TS: " + burst.TimeSlot + ", " + BurstStatusMap[burst]; BeginInvoke(new Action(() => { lblDetails.Text = msg; })); } } } } }
protected static void AddScanResult(string request, byte[] result) { if (!UseCache) { return; } lock (ScanResults) { if (result != null) { ScanResults.Add(request, ByteUtil.BytesToString(result)); } else { ScanResults.Add(request, NotFoundString); } SaveCache(); } }
public static string[] DecodeTLPacketDownlink(byte[] pduData) { int pos = 0; int elementLength = 0; int tpMti = (pduData[0] & 0x03); StringBuilder builder = new StringBuilder(); ArrayList messages = new ArrayList(); messages.Add("SMS-TL (GSM 03.40 9.2.2)"); builder.Append("Message type "); string message = null; string originating = null; string timestamp = null; switch (tpMti) { case 0: { /* GSM 03.40 9.2.2.1, http://www.slideshare.net/seanraz/10-slides-to-sms */ bool tpRp = (pduData[0] & 0x80) != 0; bool tpUdhi = (pduData[0] & 0x40) != 0; bool tpSri = (pduData[0] & 0x20) != 0; bool tpMms = (pduData[0] & 0x04) != 0; int tpDcs = 0; int tpUdl = 0; builder.Append("SMS-DELIVER"); messages.Add(builder.ToString()); builder.Length = 0; builder.Append("More Messages " + (tpMms?"Yes":"No")); messages.Add(builder.ToString()); builder.Length = 0; builder.Append("Reply Path " + (tpRp ? "Yes" : "No")); messages.Add(builder.ToString()); builder.Length = 0; builder.Append("User Data Header " + (tpUdhi ? "Exists" : "None")); messages.Add(builder.ToString()); builder.Length = 0; builder.Append("Status Report " + (tpSri ? "Requested" : "Not requested")); messages.Add(builder.ToString()); builder.Length = 0; pos++; /* second octet, TP-OA */ originating = DecodeAddress(pduData, pos, out elementLength); builder.Append("Originating address ").Append(originating); messages.Add(builder.ToString()); builder.Length = 0; pos += elementLength; /* TP-PID */ builder.Append("Protocol identifier ").Append(pduData[pos]); messages.Add(builder.ToString()); builder.Length = 0; pos++; /* TP-DCS */ tpDcs = pduData[pos]; builder.Append("Data coding scheme ").Append(tpDcs); messages.Add(builder.ToString()); builder.Length = 0; pos++; /* TP-SCTS */ timestamp = DecodeTimestamp(pduData, pos, out elementLength); builder.Append("SC Timestamp ").Append(timestamp); messages.Add(builder.ToString()); builder.Length = 0; pos += elementLength; /* TP-UDL */ tpUdl = pduData[pos]; builder.Append("TP-User Data length ").Append(tpUdl).Append(" characters"); messages.Add(builder.ToString()); builder.Length = 0; pos++; int udhLength = 0; bool containsSMSOTA = false; /* GSM 03.40 9.2.3.24 */ if (!tpUdhi) { builder.Append("TP-User Data Header ").Append("None"); messages.Add(builder.ToString()); builder.Length = 0; udhLength = 0; } else { int udhPos = pos; /* TP-UDH */ builder.Append("TP-User Data Header ").Append("Exists"); messages.Add(builder.ToString()); builder.Length = 0; udhLength = pduData[pos] + 1; builder.Append(" Header Length "); builder.Append(udhLength).Append(" byte"); messages.Add(builder.ToString()); builder.Length = 0; udhPos++; while (udhPos < (pos + udhLength)) { int type = pduData[udhPos++]; int length = pduData[udhPos++]; builder.Append(" Type "); builder.Append(type); messages.Add(builder.ToString()); builder.Length = 0; builder.Append(" Length "); builder.Append(length).Append(" byte"); messages.Add(builder.ToString()); builder.Length = 0; builder.Append(" Content "); for (int len = 0; len < length; len++) { builder.AppendFormat("{0:X02} ", pduData[udhPos + len]); } messages.Add(builder.ToString()); builder.Length = 0; switch (type) { case 0: int reference = pduData[udhPos]; int max = pduData[udhPos + 1]; int num = pduData[udhPos + 2]; builder.Append(" Decoded "); builder.AppendFormat("Concatenated SMS. This is message {1} of {2} (ID: {0})", reference, num, max); messages.Add(builder.ToString()); builder.Length = 0; break; case 1: int indication = pduData[udhPos] & 0x7F; bool store = (pduData[udhPos] & 0x80) != 0; int msgs = pduData[udhPos + 1]; string msgType = "Unknown: " + indication; switch (indication) { case 0: msgType = "Voice Message"; break; case 1: msgType = "Fax Message"; break; case 2: msgType = "E-Mail Message"; break; case 3: msgType = "Other Message"; break; } builder.Append(" Decoded "); builder.AppendFormat("Message notification, type: '{1}', messages: {2}, {0}", store ? "store this sms" : "don't store this sms", msgType, msgs); messages.Add(builder.ToString()); builder.Length = 0; break; case 0x70: int ccSize = pduData[udhPos]; containsSMSOTA = true; builder.Append(" Decoded "); builder.AppendFormat("SMS-PP Command Packet with size {0}", ccSize); messages.Add(builder.ToString()); builder.Length = 0; break; default: builder.Append(" Decoded "); builder.AppendFormat("Unknown/Undefined ID 0x{0:X02}", type); messages.Add(builder.ToString()); builder.Length = 0; break; } udhPos += length; } } /* TP-UD */ builder.Append("TP-User Data "); int userdataPayload = pduData.Length - pos; bool decoded = false; int coding = -1; /* no message class, plain text. still missing the special cases defined in GSM 03.38 */ if ((tpDcs & 0xF0) == 0) { coding = (tpDcs >> 2) & 3; } else if ((tpDcs & 0xF0) == 0x10) { /* message with message class */ coding = (tpDcs >> 2) & 3; } else if ((tpDcs & 0xF0) == 0xF0) { if ((tpDcs & 3) != 0) { /* message class other than 0 */ coding = tpDcs; } else { /* class 0 message */ if ((tpDcs & 4) != 0) { /* 8 bit data */ coding = 1; } else { /* 7 bit data */ coding = 0; } } } switch (coding) { case 0: builder.Append("7 bit GSM alphabet"); messages.Add(builder.ToString()); builder.Length = 0; message = DecodeGSM7Bit(pduData, pos, udhLength, tpUdl); builder.Append(" Content "); builder.Append(message); messages.Add(builder.ToString()); builder.Length = 0; decoded = true; break; case 1: builder.Append("8 bit message"); messages.Add(builder.ToString()); builder.Length = 0; message = DecodeASCII(pduData, pos, udhLength, tpUdl); builder.Append(" Content "); builder.Append(message); messages.Add(builder.ToString()); builder.Length = 0; decoded = true; break; case 2: builder.Append("Unicode message"); messages.Add(builder.ToString()); builder.Length = 0; message = DecodeUnicode(pduData, pos, udhLength, tpUdl); builder.Append(" Content "); builder.Append(message); messages.Add(builder.ToString()); builder.Length = 0; decoded = true; break; case 0xF5: break; /* * need to check this: * http://adywicaksono.wordpress.com/2008/05/21/understanding-gsm-0348/ * seems to be a good documentation to check against */ case 0xF6: builder.Append("SMS-OTA (GSM-03.48)"); messages.Add(builder.ToString()); builder.Length = 0; if (containsSMSOTA && pduData.Length > pos + 14) { int pLength = (pduData[pos] << 8) | pduData[pos + 1]; int hLength = pduData[pos + 2]; int spi1 = pduData[pos + 3]; int spi2 = pduData[pos + 4]; int kic = pduData[pos + 5]; int kid = pduData[pos + 6]; int tar = (pduData[pos + 7] << 16) | (pduData[pos + 8] << 8) | pduData[pos + 9]; uint cntr = ((uint)pduData[pos + 10] << 24) | (uint)(pduData[pos + 11] << 16) | (uint)(pduData[pos + 12] << 8) | (uint)pduData[pos + 13]; builder.Append(" Packet Length: ").Append(pLength); messages.Add(builder.ToString()); builder.Length = 0; builder.Append(" Header Length: ").Append(hLength); messages.Add(builder.ToString()); builder.Length = 0; /* SPI */ builder.Append(" SPI: "); messages.Add(builder.ToString()); builder.Length = 0; switch (spi1 & 3) { case 0: builder.Append(" No RC, CC or DS"); break; case 1: builder.Append(" Redundancy Check"); break; case 2: builder.Append(" Cryptographic Checksum"); break; case 3: builder.Append(" Digital Signature"); break; } messages.Add(builder.ToString()); builder.Length = 0; switch ((spi1 >> 2) & 1) { case 0: builder.Append(" No Ciphering"); break; case 1: builder.Append(" Ciphering"); break; } messages.Add(builder.ToString()); builder.Length = 0; switch ((spi1 >> 3) & 3) { case 0: builder.Append(" No counter available"); break; case 1: builder.Append(" Counter available; no replay or sequence checking"); break; case 2: builder.Append(" Process if and only if counter value is higher than the value in the RE"); break; case 3: builder.Append(" Process if and only if counter value is one higher than"); break; } messages.Add(builder.ToString()); builder.Length = 0; switch (spi2 & 3) { case 0: builder.Append(" No PoR reply to the Sending Entity (SE)"); break; case 1: builder.Append(" PoR required to be sent to the SE"); break; case 2: builder.Append(" PoR required only when an error has occured"); break; case 3: builder.Append(" Reserved"); break; } messages.Add(builder.ToString()); builder.Length = 0; switch ((spi2 >> 2) & 3) { case 0: builder.Append(" No security applied to PoR response to SE"); break; case 1: builder.Append(" PoR response with simple RC applied to it"); break; case 2: builder.Append(" PoR response with CC applied to it"); break; case 3: builder.Append(" PoR response with DS applied to it"); break; } messages.Add(builder.ToString()); builder.Length = 0; switch ((spi2 >> 4) & 1) { case 0: builder.Append(" PoR response shall not be ciphered"); break; case 1: builder.Append(" PoR response shall be ciphered"); break; } messages.Add(builder.ToString()); builder.Length = 0; switch ((spi2 >> 5) & 1) { case 0: builder.Append(" PoR response shall be sent using SMS-DELIVER-REPORT"); break; case 1: builder.Append(" PoR response shall be sent using SMS-SUBMIT "); break; } messages.Add(builder.ToString()); builder.Length = 0; /* KIc */ builder.Append(" KIc: "); messages.Add(builder.ToString()); builder.Length = 0; switch (kic & 3) { case 0: builder.Append(" Algorithm known implicitly by both entities"); break; case 1: builder.Append(" DES"); break; case 2: builder.Append(" Reserved"); break; case 3: builder.Append(" proprietary Implementations"); break; } switch ((kic >> 2) & 3) { case 0: builder.Append(" DES in CBC mode"); break; case 1: builder.Append(" Triple DES in outer-CBC mode using two different keys"); break; case 2: builder.Append(" Triple DES in outer-CBC mode using three different keys"); break; case 3: builder.Append(" DES in ECB mode"); break; } messages.Add(builder.ToString()); builder.Length = 0; builder.Append(" Using key #").Append((kic >> 4)); messages.Add(builder.ToString()); builder.Length = 0; /* KID */ switch (kid & 3) { case 0: builder.Append(" Algorithm known implicitly by both entities"); break; case 1: builder.Append(" DES"); break; case 2: builder.Append(" Reserved"); break; case 3: builder.Append(" proprietary Implementations"); break; } switch ((kid >> 2) & 3) { case 0: builder.Append(" DES in CBC mode"); break; case 1: builder.Append(" Triple DES in outer-CBC mode using two different keys"); break; case 2: builder.Append(" Triple DES in outer-CBC mode using three different keys"); break; case 3: builder.Append(" DES in ECB mode"); break; } messages.Add(builder.ToString()); builder.Length = 0; builder.Append(" Using key #").Append((kid >> 4)); messages.Add(builder.ToString()); builder.Length = 0; /* counter */ builder.Append(" TAR: ").AppendFormat("{0:X06}", tar); messages.Add(builder.ToString()); builder.Length = 0; builder.Append(" CNTR: ").AppendFormat("{0:X08}", cntr); messages.Add(builder.ToString()); builder.Length = 0; decoded = true; } break; } if (!decoded) { builder.Append("Message with unknown data coding scheme - will not decode"); messages.Add(builder.ToString()); builder.Length = 0; builder.Append(" Content "); for (int len = pos; len < userdataPayload; len++) { builder.AppendFormat("{0:X02} ", pduData[len]); } messages.Add(builder.ToString()); builder.Length = 0; } break; } case 1: { builder.Append("SMS-SUBMIT-REPORT"); messages.Add(builder.ToString()); builder.Length = 0; break; } case 2: { builder.Append("SMS-STATUS-REPORT"); messages.Add(builder.ToString()); builder.Length = 0; pos++; builder.Append("Message reference ").Append(pduData[pos]); messages.Add(builder.ToString()); builder.Length = 0; pos++; builder.Append("Recipient address ").Append(DecodeAddress(pduData, pos, out elementLength)); messages.Add(builder.ToString()); builder.Length = 0; pos += elementLength; builder.Append("SC Timestamp ").Append(DecodeTimestamp(pduData, pos, out elementLength)); messages.Add(builder.ToString()); builder.Length = 0; pos += elementLength; builder.Append("Discharge time ").Append(DecodeTimestamp(pduData, pos, out elementLength)); messages.Add(builder.ToString()); builder.Length = 0; pos += elementLength; builder.Append("Status code ").Append(pduData[pos]); messages.Add(builder.ToString()); builder.Length = 0; pos++; break; } case 3: { builder.Append("Reserved"); messages.Add(builder.ToString()); builder.Length = 0; break; } } if (timestamp != null && message != null && originating != null) { try { FileStream stream = File.Open("sms.txt", FileMode.Append, FileAccess.Write); TextWriter writer = new StreamWriter(stream); string key = "(failed)"; string ident = "(failed)"; string prevIdent = ""; try { key = ByteUtil.BytesToString(((LibRXFFT.Libraries.GSM.Layer1.Bursts.NormalBurst)LibRXFFT.Libraries.GSM.Layer1.TimeSlotHandler._HACK_Parameters.CurrentBurstHandler).A5CipherKey); ident = ((LibRXFFT.Libraries.GSM.Layer1.Bursts.NormalBurst)LibRXFFT.Libraries.GSM.Layer1.TimeSlotHandler._HACK_Parameters.CurrentBurstHandler).PhoneIdentity.Trim().Replace("TMSI/P-TMSI ", "").Replace("IMSI ", "").Replace(" ", " ").PadRight(14); prevIdent = ((LibRXFFT.Libraries.GSM.Layer1.Bursts.NormalBurst)LibRXFFT.Libraries.GSM.Layer1.TimeSlotHandler._HACK_Parameters.CurrentBurstHandler).PhoneIdentityPrev.Trim().Replace("TMSI/P-TMSI ", "").Replace("IMSI ", "").Replace(" ", " ").PadRight(14); } catch (Exception) { } string identStr = ""; if (prevIdent != "") { identStr = prevIdent + " -> " + ident; } else { identStr = ident + " " + "".PadRight(14); } writer.WriteLine(originating.PadRight(16) + " | " + identStr + " | " + key + " | " + timestamp + " | " + message); writer.Close(); } catch (Exception) { } } return((string[])messages.ToArray(typeof(string))); }