swiftlib_sdlan/Sources/Punchnet/LayerPacket.swift
2025-07-16 17:23:56 +08:00

100 lines
2.5 KiB
Swift

//
// LayerPacket.swift
// Tun
//
// Created by on 2024/8/21.
//
import Foundation
import zlib
struct LayerPacket {
//
enum PacketType: UInt16 {
case arp = 0x0806
case ipv4 = 0x0800
case ipv6 = 0x86DD
case taggedFrame = 0x8100
}
enum LayerPacketError: Error {
case invalidLength
case invaldPacketType
}
struct MacAddress {
let data: Data
init(data: Data) {
self.data = data
}
func isBroadcast() -> Bool {
return data.count == 6 && self.data.allSatisfy { $0 == 0xFF}
}
func isMulticast() -> Bool {
return data.count == 6 && (data[0] == 0x01 && data[1] == 0x00 && data[2] == 0x5E)
}
func format() -> String {
// mac
let bytes = [UInt8](data)
return bytes.map { String(format: "%02X", $0) }.joined(separator: ":").lowercased()
}
static func description(data: Data) -> String {
// mac
let bytes = [UInt8](data)
return bytes.map { String(format: "%02X", $0) }.joined(separator: ":").lowercased()
}
}
let dstMac: Data
let srcMac: Data
let type: PacketType
let data: Data
init(dstMac: Data, srcMac: Data, type: PacketType, data: Data) {
self.dstMac = dstMac
self.srcMac = srcMac
self.type = type
self.data = data
}
init(layerData playload: Data) throws {
guard playload.count >= 14 else {
throw LayerPacketError.invalidLength
}
self.dstMac = Data(playload[0..<6])
self.srcMac = Data(playload[6..<12])
guard let type = PacketType(rawValue: UInt16(bytes: (playload[12], playload[13]))) else {
throw LayerPacketError.invaldPacketType
}
self.type = type
self.data = Data(playload[14...])
}
func marshal() -> Data {
var packet = Data()
packet.append(dstMac)
packet.append(srcMac)
packet.append(self.type.rawValue.data())
packet.append(self.data)
return packet
}
private static func crc32(data: Data) -> UInt32 {
let crc = data.withUnsafeBytes { buffer in
return zlib.crc32(0, buffer.bindMemory(to: UInt8.self).baseAddress, uInt(buffer.count))
}
return UInt32(crc)
}
}