87 lines
2.4 KiB
Swift
87 lines
2.4 KiB
Swift
//
|
|
// IPPacket.swift
|
|
// Tun
|
|
//
|
|
// Created by 安礼成 on 2024/1/18.
|
|
//
|
|
|
|
import Foundation
|
|
|
|
struct IPHeader {
|
|
let version: UInt8
|
|
let headerLength: UInt8
|
|
let typeOfService: UInt8
|
|
let totalLength: UInt16
|
|
let id: UInt16
|
|
let offset: UInt16
|
|
let timeToLive: UInt8
|
|
let proto:UInt8
|
|
let checksum: UInt16
|
|
let source: UInt32
|
|
let destination: UInt32
|
|
|
|
var source_ip: String {
|
|
return intToIp(source)
|
|
}
|
|
|
|
var destination_ip: String {
|
|
return intToIp(destination)
|
|
}
|
|
|
|
private func intToIp(_ num: UInt32) -> String {
|
|
let ip0 = (UInt8) (num >> 24 & 0xFF)
|
|
let ip1 = (UInt8) (num >> 16 & 0xFF)
|
|
let ip2 = (UInt8) (num >> 8 & 0xFF)
|
|
let ip3 = (UInt8) (num & 0xFF)
|
|
|
|
return "\(ip0).\(ip1).\(ip2).\(ip3)"
|
|
}
|
|
|
|
public var description: String {
|
|
"""
|
|
IPHeader version: \(version), header length: \(headerLength), type of service: \(typeOfService), total length: \(totalLength),
|
|
id: \(id), offset: \(offset), time ot live: \(timeToLive), proto: \(proto), checksum: \(checksum), source ip: \(source_ip), destination ip:\(destination_ip)
|
|
"""
|
|
}
|
|
}
|
|
|
|
enum IPVersion: UInt8 {
|
|
case ipv4 = 4
|
|
case ipv6 = 6
|
|
}
|
|
|
|
enum TransportProtocol: UInt8 {
|
|
case icmp = 1
|
|
case tcp = 6
|
|
case udp = 17
|
|
}
|
|
|
|
struct IPPacket {
|
|
let header: IPHeader
|
|
let data: Data
|
|
|
|
init?(_ data: Data) {
|
|
guard data.count >= 20 else {
|
|
return nil
|
|
}
|
|
|
|
self.header = IPHeader(version: data[0] >> 4,
|
|
headerLength: (data[0] & 0b1111) * 4,
|
|
typeOfService: data[1],
|
|
totalLength: UInt16(bytes: (data[2], data[3])),
|
|
id: UInt16(bytes: (data[4], data[5])),
|
|
offset: 1,
|
|
timeToLive: data[8],
|
|
proto: data[9],
|
|
checksum: UInt16(bytes: (data[10], data[11])),
|
|
source: UInt32(bytes: (data[12], data[13], data[14], data[15])),
|
|
destination: UInt32(bytes: (data[16], data[17], data[18], data[19])))
|
|
self.data = data
|
|
}
|
|
|
|
// 获取负载部分
|
|
func getPayload() -> Data {
|
|
return data.subdata(in: 20..<data.count)
|
|
}
|
|
}
|