1
0
mirror of https://github.com/SoftEtherVPN/SoftEtherVPN.git synced 2025-09-20 02:09:25 +03:00

16 Commits

Author SHA1 Message Date
6c04825b46 Merge pull request #2157 from chipitsine/1ce88cea-29e8-466a-88f4-3713e94171d8
docker: smoke test image during generating
2025-09-06 16:31:04 +02:00
0ec8a1ed54 docker: smoke test image during generating
reference: https://github.com/SoftEtherVPN/SoftetherVPN-docker/issues/17
2025-09-05 21:22:43 +02:00
2acefef41e Merge pull request #2156 from metalefty/fix_cpu_features
Proper fix for #2122 #2150
2025-09-05 19:43:42 +02:00
efb04daa34 Proper fix for #2122 #2150
Bundled cpu_features needs to be built with PIC but SHARED_LIBS should
be OFF.
2025-09-05 22:40:18 +09:00
c399ce6bbe Merge pull request #2152 from metalefty/cpu_features_pic
Build bundled cpu_features with PIC
2025-08-25 15:36:27 +02:00
2746e8dd19 Build bundled cpu_features with PIC
After updating bundled cpu_features to 0.9.0, set_property() is not
effective. We need to use set() instead.

Resolves: #2122 #2150
2025-08-25 21:52:15 +09:00
10d6efcc5e Merge pull request #2140 from onetown/fix_parse_vlan_packet
fix: Continue decapsulation to parse L3 data from VLAN-tagged packets
2025-07-17 18:13:58 +02:00
0389bfd97a fix: Continue decapsulation to parse L3 data from VLAN-tagged packets 2025-07-17 10:51:52 -04:00
12ed43f6eb Merge pull request #2126 from kiraware/fix-indonesian-translation
Fix Indonesian translation with printf formatting
2025-05-09 07:43:12 +02:00
d8bcb863f5 rephrase the string 2025-05-09 11:37:21 +07:00
7228de494d rephrase the string 2025-05-09 11:34:45 +07:00
afa848454a fix printf formatting 2025-05-09 10:34:53 +07:00
6f76880767 Merge pull request #2124 from kiraware/add-id-translation
Add id translation
2025-05-08 18:25:54 +02:00
cb9ccf41a5 Merge pull request #2125 from AhmadReza6610/master
Add iOS client implementation with SoftEther protocol handshake support
2025-05-08 18:22:14 +02:00
62c71ebe5c Add iOS client implementation with SoftEther protocol handshake support 2025-05-04 14:02:44 +03:30
80bab0f7d7 fix errors 2025-05-01 10:43:45 +07:00
11 changed files with 855 additions and 76 deletions

View File

@ -37,15 +37,18 @@ COPY --from=builder /usr/local/src/SoftEtherVPN/build/libcedar.so /usr/local/src
FROM base AS vpnserver
COPY --from=builder /usr/local/src/SoftEtherVPN/build/vpnserver ./
RUN ./vpnserver --help
EXPOSE 443/tcp 992/tcp 1194/tcp 1194/udp 5555/tcp 500/udp 4500/udp
CMD ["/usr/local/bin/vpnserver", "execsvc"]
FROM base AS vpnclient
COPY --from=builder /usr/local/src/SoftEtherVPN/build/vpnclient ./
RUN ./vpnclient --help
CMD ["/usr/local/bin/vpnclient", "execsvc"]
FROM base AS vpnbridge
COPY --from=builder /usr/local/src/SoftEtherVPN/build/vpnbridge ./
RUN ./vpnbridge --help
CMD ["/usr/local/bin/vpnbridge", "execsvc"]

View File

@ -0,0 +1,118 @@
import Foundation
import Network
import Security
/// SecureConnection handles the TLS connection with the SoftEther VPN server
class SecureConnection {
// MARK: - Properties
private var connection: NWConnection?
private let host: String
private let port: UInt16
private let queue = DispatchQueue(label: "com.softether.connection", qos: .userInitiated)
// MARK: - Initialization
/// Initialize a secure connection
/// - Parameters:
/// - host: Server hostname or IP address
/// - port: Server port number
init(host: String, port: UInt16) {
self.host = host
self.port = port
}
// MARK: - Public Methods
/// Connect to the server using TLS
/// - Parameter completion: Callback with connection result
func connect(completion: @escaping (Bool, Error?) -> Void) {
let hostEndpoint = NWEndpoint.Host(host)
let portEndpoint = NWEndpoint.Port(rawValue: port)!
// Create TLS parameters
let tlsOptions = NWProtocolTLS.Options()
// Configure TLS for maximum compatibility with SoftEther
let securityOptions = tlsOptions.securityProtocolOptions
sec_protocol_options_set_tls_min_version(securityOptions, .TLSv12)
sec_protocol_options_set_tls_max_version(securityOptions, .TLSv13)
// Allow all cipher suites for compatibility
sec_protocol_options_set_cipher_suites(securityOptions, nil, 0)
// Disable certificate validation for initial development (ENABLE IN PRODUCTION)
sec_protocol_options_set_verify_block(securityOptions, { (_, _, trustResult, _) in
return true // Accept all certificates for testing
}, queue)
// Create TCP options with TLS
let tcpOptions = NWProtocolTCP.Options()
tcpOptions.enableKeepalive = true
tcpOptions.keepaliveIdle = 30
// Create connection parameters
let parameters = NWParameters(tls: tlsOptions, tcp: tcpOptions)
// Create the connection
connection = NWConnection(host: hostEndpoint, port: portEndpoint, using: parameters)
// Set up state handling
connection?.stateUpdateHandler = { [weak self] state in
switch state {
case .ready:
completion(true, nil)
case .failed(let error):
self?.disconnect()
completion(false, error)
case .cancelled:
completion(false, NSError(domain: "SoftEtherError", code: 1000, userInfo: [NSLocalizedDescriptionKey: "Connection cancelled"]))
default:
break
}
}
// Start the connection
connection?.start(queue: queue)
}
/// Disconnect from the server
func disconnect() {
connection?.cancel()
connection = nil
}
/// Send data to the server
/// - Parameters:
/// - data: Data to send
/// - completion: Callback with error if any
func send(data: Data, completion: @escaping (Error?) -> Void) {
guard let connection = connection, connection.state == .ready else {
completion(NSError(domain: "SoftEtherError", code: 1001, userInfo: [NSLocalizedDescriptionKey: "Connection not ready"]))
return
}
connection.send(content: data, completion: .contentProcessed { error in
completion(error)
})
}
/// Receive data from the server
/// - Parameter completion: Callback with received data and error if any
func receive(completion: @escaping (Data?, Error?) -> Void) {
guard let connection = connection, connection.state == .ready else {
completion(nil, NSError(domain: "SoftEtherError", code: 1001, userInfo: [NSLocalizedDescriptionKey: "Connection not ready"]))
return
}
connection.receive(minimumIncompleteLength: 1, maximumLength: 65536) { data, _, isComplete, error in
completion(data, error)
if isComplete {
// Connection was closed by the peer
self.disconnect()
}
}
}
}

View File

@ -0,0 +1,90 @@
import Foundation
/// Handles the specific client signature format that SoftEther expects
class SoftEtherClientSignature {
// MARK: - Constants
private enum Constants {
static let clientBuildNumber: UInt32 = 5187
static let clientVersion: UInt32 = 5_02_0000 + clientBuildNumber
static let clientString = "SoftEther VPN Client"
static let softEtherMagic: [UInt8] = [0x5E, 0x68] // 'Se' in hex
// Protocol identification constants from SoftEther source
static let cedar = "CEDAR"
static let sessionKey = "sessionkey"
static let protocol1 = "PROTOCOL"
static let protocol2 = "PROTOCOL2"
}
// MARK: - Public Methods
/// Generate the client signature packet that identifies this client as a legitimate SoftEther VPN client
/// - Returns: Data containing the formatted client signature
static func generateSignature() -> Data {
var data = Data()
// 1. Add SoftEther magic bytes
data.append(contentsOf: Constants.softEtherMagic)
// 2. Add client version in network byte order (big endian)
data.appendUInt32(Constants.clientVersion)
// 3. Add client build number in network byte order
data.appendUInt32(Constants.clientBuildNumber)
// 4. Add cedar protocol identifier
if let cedarData = Constants.cedar.data(using: .ascii) {
data.append(cedarData)
data.append(0) // null terminator
}
// 5. Add client string with null terminator
if let clientString = (Constants.clientString + "\0").data(using: .ascii) {
data.append(clientString)
}
// 6. Add protocol identifiers
if let protocolData = (Constants.protocol1 + "\0").data(using: .ascii) {
data.append(protocolData)
}
if let protocol2Data = (Constants.protocol2 + "\0").data(using: .ascii) {
data.append(protocol2Data)
}
// 7. Add session key marker
if let sessionKeyData = (Constants.sessionKey + "\0").data(using: .ascii) {
data.append(sessionKeyData)
}
// 8. Add random data for session key (typically 20 bytes)
let randomSessionKey = SoftEtherCrypto.randomBytes(count: 20)
data.append(randomSessionKey)
// 9. Calculate and append SHA-1 hash of the entire data for integrity verification
let hash = SoftEtherCrypto.sha1(data)
data.append(hash)
return data
}
/// Verify a server response to the client signature
/// - Parameter data: Response data from server
/// - Returns: True if valid response, false otherwise
static func verifyServerResponse(_ data: Data) -> Bool {
// Basic validation - a real implementation would parse and validate the server response format
// This is a minimal check to see if we have enough data and it starts with the magic bytes
guard data.count >= 8 else {
return false
}
// Check if response starts with SoftEther magic bytes
if data[0] == Constants.softEtherMagic[0] && data[1] == Constants.softEtherMagic[1] {
return true
}
return false
}
}

View File

@ -0,0 +1,97 @@
import Foundation
import CryptoKit
/// Handles encryption operations for SoftEther protocol
class SoftEtherCrypto {
// MARK: - Constants
private enum Constants {
static let sha1Size = 20
static let md5Size = 16
}
// MARK: - Public Methods
/// Generate secure random bytes
/// - Parameter count: Number of random bytes to generate
/// - Returns: Data containing random bytes
static func randomBytes(count: Int) -> Data {
var data = Data(count: count)
_ = data.withUnsafeMutableBytes {
SecRandomCopyBytes(kSecRandomDefault, count, $0.baseAddress!)
}
return data
}
/// Calculate SHA-1 hash
/// - Parameter data: Input data
/// - Returns: SHA-1 hash of the input data
static func sha1(_ data: Data) -> Data {
let digest = SHA1.hash(data: data)
return Data(digest)
}
/// Calculate MD5 hash
/// - Parameter data: Input data
/// - Returns: MD5 hash of the input data
static func md5(_ data: Data) -> Data {
let digest = Insecure.MD5.hash(data: data)
return Data(digest)
}
/// Encrypt data using RC4 algorithm (for SoftEther compatibility)
/// - Parameters:
/// - data: Data to encrypt
/// - key: Encryption key
/// - Returns: Encrypted data
static func rc4Encrypt(data: Data, key: Data) -> Data {
let rc4 = RC4(key: key)
return rc4.process(data)
}
/// Decrypt data using RC4 algorithm (for SoftEther compatibility)
/// - Parameters:
/// - data: Data to decrypt
/// - key: Decryption key
/// - Returns: Decrypted data
static func rc4Decrypt(data: Data, key: Data) -> Data {
// RC4 is symmetric, so encryption and decryption are the same operation
return rc4Encrypt(data: data, key: key)
}
}
/// Simple RC4 implementation for SoftEther compatibility
/// Note: RC4 is considered insecure, but SoftEther uses it in parts of its protocol
private class RC4 {
private var state: [UInt8]
init(key: Data) {
state = Array(0...255)
var j: Int = 0
// Key scheduling algorithm
for i in 0..<256 {
let keyByte = key[i % key.count]
j = (j + Int(state[i]) + Int(keyByte)) & 0xFF
state.swapAt(i, j)
}
}
func process(_ data: Data) -> Data {
var result = Data(count: data.count)
var i: Int = 0
var j: Int = 0
// Generate keystream and XOR with plaintext
for k in 0..<data.count {
i = (i + 1) & 0xFF
j = (j + Int(state[i])) & 0xFF
state.swapAt(i, j)
let keyStreamByte = state[(Int(state[i]) + Int(state[j])) & 0xFF]
result[k] = data[k] ^ keyStreamByte
}
return result
}
}

View File

@ -0,0 +1,123 @@
import Foundation
/// Handles the SoftEther packet structure for communication
class SoftEtherPacket {
// MARK: - Constants
private enum PacketType: UInt32 {
case clientSignature = 0x01
case serverResponse = 0x02
case sessionRequest = 0x03
case sessionResponse = 0x04
case data = 0x05
case keepAlive = 0x06
}
private enum Constants {
static let headerSize: UInt32 = 16
static let maxPacketSize: UInt32 = 1024 * 1024 // 1MB
}
// MARK: - Properties
private var packetType: PacketType
private var packetId: UInt32
private var packetData: Data
// MARK: - Initialization
/// Initialize a packet with type, ID and data
/// - Parameters:
/// - type: Packet type
/// - id: Packet ID
/// - data: Packet payload
init(type: UInt32, id: UInt32, data: Data) {
self.packetType = PacketType(rawValue: type) ?? .data
self.packetId = id
self.packetData = data
}
/// Initialize a packet from raw data
/// - Parameter data: Raw packet data
init?(fromData data: Data) {
guard data.count >= Int(Constants.headerSize) else {
return nil
}
// Parse header
let typeValue = data.readUInt32(at: 0)
self.packetId = data.readUInt32(at: 4)
let dataSize = data.readUInt32(at: 8)
// Validate packet
guard let type = PacketType(rawValue: typeValue),
dataSize <= Constants.maxPacketSize,
data.count >= Int(Constants.headerSize + dataSize) else {
return nil
}
self.packetType = type
// Extract payload
let startIndex = Int(Constants.headerSize)
let endIndex = startIndex + Int(dataSize)
self.packetData = data.subdata(in: startIndex..<endIndex)
}
// MARK: - Public Methods
/// Serialize the packet to binary data format
/// - Returns: Serialized packet data
func serialize() -> Data {
var result = Data(capacity: Int(Constants.headerSize) + packetData.count)
// Write header
result.appendUInt32(packetType.rawValue)
result.appendUInt32(packetId)
result.appendUInt32(UInt32(packetData.count))
result.appendUInt32(0) // Reserved
// Write payload
result.append(packetData)
return result
}
/// Get the packet type
/// - Returns: Packet type
func getType() -> UInt32 {
return packetType.rawValue
}
/// Get the packet ID
/// - Returns: Packet ID
func getId() -> UInt32 {
return packetId
}
/// Get the packet payload
/// - Returns: Packet payload data
func getData() -> Data {
return packetData
}
}
// MARK: - Extensions
extension Data {
/// Read a UInt32 value from the data at specified offset
/// - Parameter offset: Offset to read from
/// - Returns: UInt32 value in big-endian order
func readUInt32(at offset: Int) -> UInt32 {
let slice = self.subdata(in: offset..<(offset + 4))
return slice.withUnsafeBytes { $0.load(as: UInt32.self).bigEndian }
}
/// Append a UInt32 value to the data in big-endian order
/// - Parameter value: UInt32 value to append
mutating func appendUInt32(_ value: UInt32) {
var bigEndian = value.bigEndian
append(UnsafeBufferPointer(start: &bigEndian, count: 1))
}
}

View File

@ -0,0 +1,184 @@
import Foundation
import Network
import Security
import CryptoKit
/// SoftEtherProtocol manages the communication between iOS client and SoftEther VPN server
class SoftEtherProtocol {
// MARK: - Properties
private var secureConnection: SecureConnection?
private var isConnected = false
private var host: String = ""
private var port: UInt16 = 443
private var nextPacketId: UInt32 = 1
// MARK: - Public Methods
/// Connect to a SoftEther VPN server
/// - Parameters:
/// - host: The server hostname or IP address
/// - port: The server port (default: 443)
/// - completion: Callback with connection result
public func connect(to host: String, port: UInt16 = 443, completion: @escaping (Bool, Error?) -> Void) {
self.host = host
self.port = port
// Create a secure connection
secureConnection = SecureConnection(host: host, port: port)
// Connect using TLS
secureConnection?.connect { [weak self] success, error in
guard let self = self, success else {
completion(false, error ?? NSError(domain: "SoftEtherError", code: 1, userInfo: [NSLocalizedDescriptionKey: "TLS connection failed"]))
return
}
// After successful TLS connection, send the client signature
self.sendClientSignature { success, error in
if success {
self.isConnected = true
}
completion(success, error)
}
}
}
/// Disconnect from the server
public func disconnect() {
secureConnection?.disconnect()
isConnected = false
}
// MARK: - Private Methods
/// Send the SoftEther client signature to identify as a legitimate client
/// - Parameter completion: Callback with result
private func sendClientSignature(completion: @escaping (Bool, Error?) -> Void) {
// Generate client signature using our specialized class
let signatureData = SoftEtherClientSignature.generateSignature()
// Create a packet with the signature data
let packetId = self.nextPacketId
self.nextPacketId += 1
let packet = SoftEtherPacket(type: 0x01, id: packetId, data: signatureData)
let packetData = packet.serialize()
print("Sending client signature packet: \(packetData.count) bytes")
// Send the packet
secureConnection?.send(data: packetData) { [weak self] error in
guard let self = self else { return }
if let error = error {
print("Error sending client signature: \(error)")
completion(false, error)
return
}
// After sending signature, wait for server response
self.receiveServerResponse { success, error in
completion(success, error)
}
}
}
/// Receive and process server response after sending signature
/// - Parameter completion: Callback with result
private func receiveServerResponse(completion: @escaping (Bool, Error?) -> Void) {
secureConnection?.receive { data, error in
if let error = error {
print("Error receiving server response: \(error)")
completion(false, error)
return
}
guard let data = data, data.count > 4 else {
let error = NSError(domain: "SoftEtherError", code: 2, userInfo: [NSLocalizedDescriptionKey: "Invalid server response"])
print("Invalid server response: insufficient data")
completion(false, error)
return
}
print("Received server response: \(data.count) bytes")
// Parse the response packet
guard let packet = SoftEtherPacket(fromData: data) else {
let error = NSError(domain: "SoftEtherError", code: 3, userInfo: [NSLocalizedDescriptionKey: "Invalid packet format"])
print("Could not parse server response packet")
completion(false, error)
return
}
// Verify the response
let packetData = packet.getData()
let isValid = SoftEtherClientSignature.verifyServerResponse(packetData)
if isValid {
print("Server accepted our client signature")
completion(true, nil)
} else {
print("Server rejected our client signature")
let error = NSError(domain: "SoftEtherError", code: 4, userInfo: [NSLocalizedDescriptionKey: "Server rejected client signature"])
completion(false, error)
}
}
}
/// Send a data packet to the server
/// - Parameters:
/// - data: Data to send
/// - completion: Callback with result
func sendData(data: Data, completion: @escaping (Bool, Error?) -> Void) {
guard isConnected else {
completion(false, NSError(domain: "SoftEtherError", code: 5, userInfo: [NSLocalizedDescriptionKey: "Not connected to server"]))
return
}
let packetId = self.nextPacketId
self.nextPacketId += 1
let packet = SoftEtherPacket(type: 0x05, id: packetId, data: data)
let packetData = packet.serialize()
secureConnection?.send(data: packetData) { error in
if let error = error {
completion(false, error)
return
}
completion(true, nil)
}
}
/// Receive data from the server
/// - Parameter completion: Callback with received data and result
func receiveData(completion: @escaping (Data?, Bool, Error?) -> Void) {
guard isConnected else {
completion(nil, false, NSError(domain: "SoftEtherError", code: 5, userInfo: [NSLocalizedDescriptionKey: "Not connected to server"]))
return
}
secureConnection?.receive { data, error in
if let error = error {
completion(nil, false, error)
return
}
guard let data = data, data.count > 4 else {
completion(nil, false, NSError(domain: "SoftEtherError", code: 2, userInfo: [NSLocalizedDescriptionKey: "Invalid server response"]))
return
}
// Parse the packet
guard let packet = SoftEtherPacket(fromData: data) else {
completion(nil, false, NSError(domain: "SoftEtherError", code: 3, userInfo: [NSLocalizedDescriptionKey: "Invalid packet format"]))
return
}
completion(packet.getData(), true, nil)
}
}
}

View File

@ -0,0 +1,149 @@
import Foundation
import UIKit
/// SoftEtherVPNClient provides a simple interface for connecting to SoftEther VPN servers
public class SoftEtherVPNClient {
// MARK: - Properties
private let protocol: SoftEtherProtocol
private var connectionState: ConnectionState = .disconnected
// MARK: - Public Types
/// Connection states for the VPN client
public enum ConnectionState {
case disconnected
case connecting
case connected
case disconnecting
case error(Error)
}
/// Connection delegate to receive state updates
public protocol ConnectionDelegate: AnyObject {
func connectionStateDidChange(_ state: ConnectionState)
}
/// Weak reference to the delegate
public weak var delegate: ConnectionDelegate?
// MARK: - Initialization
public init() {
self.protocol = SoftEtherProtocol()
}
// MARK: - Public Methods
/// Connect to a SoftEther VPN server
/// - Parameters:
/// - host: Server hostname or IP address
/// - port: Server port (default: 443)
/// - completion: Optional completion handler
public func connect(to host: String, port: UInt16 = 443, completion: ((Bool, Error?) -> Void)? = nil) {
// Update state
connectionState = .connecting
delegate?.connectionStateDidChange(connectionState)
// Connect using the protocol implementation
protocol.connect(to: host, port: port) { [weak self] success, error in
guard let self = self else { return }
if success {
self.connectionState = .connected
} else if let error = error {
self.connectionState = .error(error)
} else {
self.connectionState = .disconnected
}
self.delegate?.connectionStateDidChange(self.connectionState)
completion?(success, error)
}
}
/// Disconnect from the server
/// - Parameter completion: Optional completion handler
public func disconnect(completion: (() -> Void)? = nil) {
// Update state
connectionState = .disconnecting
delegate?.connectionStateDidChange(connectionState)
// Disconnect
protocol.disconnect()
// Update state again
connectionState = .disconnected
delegate?.connectionStateDidChange(connectionState)
completion?()
}
/// Get the current connection state
/// - Returns: Current ConnectionState
public func getConnectionState() -> ConnectionState {
return connectionState
}
/// Check if currently connected
/// - Returns: True if connected, false otherwise
public func isConnected() -> Bool {
if case .connected = connectionState {
return true
}
return false
}
// MARK: - Example Usage
/// Example showing how to use this class in a view controller
public static func exampleUsage() -> String {
return """
// In your view controller:
private let vpnClient = SoftEtherVPNClient()
override func viewDidLoad() {
super.viewDidLoad()
// Set delegate
vpnClient.delegate = self
}
@IBAction func connectButtonTapped(_ sender: UIButton) {
if vpnClient.isConnected() {
vpnClient.disconnect()
} else {
vpnClient.connect(to: "vpn.example.com") { success, error in
if !success {
print("Failed to connect: \\(error?.localizedDescription ?? "Unknown error")")
}
}
}
}
// MARK: - ConnectionDelegate
extension YourViewController: SoftEtherVPNClient.ConnectionDelegate {
func connectionStateDidChange(_ state: SoftEtherVPNClient.ConnectionState) {
switch state {
case .connected:
connectButton.setTitle("Disconnect", for: .normal)
statusLabel.text = "Connected"
case .connecting:
statusLabel.text = "Connecting..."
case .disconnecting:
statusLabel.text = "Disconnecting..."
case .disconnected:
connectButton.setTitle("Connect", for: .normal)
statusLabel.text = "Disconnected"
case .error(let error):
statusLabel.text = "Error: \\(error.localizedDescription)"
connectButton.setTitle("Connect", for: .normal)
}
}
}
"""
}
}

View File

@ -125,8 +125,10 @@ if(UNIX)
message("-- Using system's cpu_features")
target_link_libraries(mayaqua PRIVATE cpu_features)
else()
message("-- Using bundled cpu_features")
set(BUILD_SHARED_LIBS OFF)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
add_subdirectory(3rdparty/cpu_features)
set_property(TARGET cpu_features PROPERTY POSITION_INDEPENDENT_CODE ON)
target_link_libraries(mayaqua PRIVATE cpu_features)
endif()

View File

@ -2057,43 +2057,15 @@ bool ParsePacketL2Ex(PKT *p, UCHAR *buf, UINT size, bool no_l3, bool no_l3_l4_ex
if (type_id_16 > 1500)
{
// Ordinary Ethernet frame
switch (type_id_16)
if (type_id_16 == MAC_PROTO_TAGVLAN)
{
case MAC_PROTO_ARPV4: // ARPv4
if (no_l3 || no_l3_l4_except_icmpv6)
{
return true;
}
return ParsePacketARPv4(p, buf, size);
case MAC_PROTO_IPV4: // IPv4
if (no_l3 || no_l3_l4_except_icmpv6)
{
return true;
}
return ParsePacketIPv4(p, buf, size);
case MAC_PROTO_IPV6: // IPv6
if (no_l3)
{
return true;
}
return ParsePacketIPv6(p, buf, size, no_l3_l4_except_icmpv6);
default: // Unknown
if (type_id_16 == p->VlanTypeID)
{
// VLAN
return ParsePacketTAGVLAN(p, buf, size);
}
else
{
return true;
}
// Parse VLAN frame
return ParsePacketTAGVLAN(p, buf, size, no_l3, no_l3_l4_except_icmpv6);
}
else
{
// Parse Ordinary Ethernet frame
return ParsePacketL3(p, buf, size, type_id_16, no_l3, no_l3_l4_except_icmpv6);
}
}
else
@ -2128,10 +2100,44 @@ bool ParsePacketL2Ex(PKT *p, UCHAR *buf, UINT size, bool no_l3, bool no_l3_l4_ex
}
}
bool ParsePacketL3(PKT *p, UCHAR *buf, UINT size, USHORT proto, bool no_l3, bool no_l3_l4_except_icmpv6)
{
switch (proto)
{
case MAC_PROTO_ARPV4: // ARPv4
if (no_l3 || no_l3_l4_except_icmpv6)
{
return true;
}
return ParsePacketARPv4(p, buf, size);
case MAC_PROTO_IPV4: // IPv4
if (no_l3 || no_l3_l4_except_icmpv6)
{
return true;
}
return ParsePacketIPv4(p, buf, size);
case MAC_PROTO_IPV6: // IPv6
if (no_l3)
{
return true;
}
return ParsePacketIPv6(p, buf, size, no_l3_l4_except_icmpv6);
default: // Unknown
return true;
}
}
// TAG VLAN parsing
bool ParsePacketTAGVLAN(PKT *p, UCHAR *buf, UINT size)
bool ParsePacketTAGVLAN(PKT *p, UCHAR *buf, UINT size, bool no_l3, bool no_l3_l4_except_icmpv6)
{
USHORT vlan_ushort;
USHORT proto_ushort;
// Validate arguments
if (p == NULL || buf == NULL)
{
@ -2151,12 +2157,17 @@ bool ParsePacketTAGVLAN(PKT *p, UCHAR *buf, UINT size)
buf += sizeof(TAGVLAN_HEADER);
size -= sizeof(TAGVLAN_HEADER);
vlan_ushort = READ_USHORT(p->L3.TagVlanHeader->Data);
vlan_ushort = READ_USHORT(p->L3.TagVlanHeader->TagID);
vlan_ushort = vlan_ushort & 0xFFF;
p->VlanId = vlan_ushort;
return true;
proto_ushort = READ_USHORT(p->L3.TagVlanHeader->Protocol);
proto_ushort = proto_ushort & 0xFFFF;
// Parse the L3 packet
return ParsePacketL3(p, buf, size, proto_ushort, no_l3, no_l3_l4_except_icmpv6);
}
// BPDU Parsing

View File

@ -87,7 +87,8 @@ struct ARPV4_HEADER
// Tagged VLAN header
struct TAGVLAN_HEADER
{
UCHAR Data[2]; // Data
UCHAR TagID[2]; // TagID
UCHAR Protocol[2]; // Protocol
} GCC_PACKED;
// IPv4 header
@ -762,10 +763,11 @@ void FreePacketTCPv4(PKT *p);
void FreePacketICMPv4(PKT *p);
void FreePacketDHCPv4(PKT *p);
bool ParsePacketL2Ex(PKT *p, UCHAR *buf, UINT size, bool no_l3, bool no_l3_l4_except_icmpv6);
bool ParsePacketL3(PKT *p, UCHAR *buf, UINT size, USHORT proto, bool no_l3, bool no_l3_l4_except_icmpv6);
bool ParsePacketARPv4(PKT *p, UCHAR *buf, UINT size);
bool ParsePacketIPv4(PKT *p, UCHAR *buf, UINT size);
bool ParsePacketBPDU(PKT *p, UCHAR *buf, UINT size);
bool ParsePacketTAGVLAN(PKT *p, UCHAR *buf, UINT size);
bool ParsePacketTAGVLAN(PKT *p, UCHAR *buf, UINT size, bool no_l3, bool no_l3_l4_except_icmpv6);
bool ParseICMPv4(PKT *p, UCHAR *buf, UINT size);
bool ParseICMPv6(PKT *p, UCHAR *buf, UINT size);
bool ParseTCP(PKT *p, UCHAR *buf, UINT size);

View File

@ -1336,7 +1336,7 @@ SM_FMINFO_HUB Virtual Hub #%u
SM_FMINFO_HUB_TAG_1 %S (Dinamis)
SM_FMINFO_HUB_TAG_2 %S (Statis)
SM_FMINFO_NUM_SESSION Jumlah Sesi
SM_FMINFO_NUM_CONNECTION Jumlah Koneksi TCP
SM_FMINFO_NUN_CONNECTION Jumlah Koneksi TCP
SM_FMINFO_CAPTION Status Anggota Cluster Server
SM_FC_STATUS_CAPTION Status Koneksi ke Pengendali Cluster
SM_FC_IP Alamat IP Pengendali
@ -1890,7 +1890,7 @@ LE_RECONNECT Pengaturan EtherIP / L2TPv3 telah diubah. Pipa internal sekarang
# (PPP Log)
LP_PREFIX Sesi PPP %S[%S:%u]:
LP_PREFIX %S%SSesi PPP [%S:%u]:
LP_CONNECTED Sesi PPP baru dimulai (Protokol atas: %S). Alamat IP Klien PPP: %S (Nama Host: "%S"), Nomor Port Klien PPP: %u, Alamat IP Server PPP: %S, Nomor Port Server PPP: %u, Nama Perangkat Lunak Klien: "%S", Ukuran Segmen Maksimum TCP IPv4 (MSS): %u byte
LP_DISCONNECTED Sesi PPP terputus.
LP_PAP_REJECTED Klien menolak untuk menerima protokol otentikasi "PAP" (Protokol Otentikasi Kata Sandi, protokol otentikasi kata sandi teks jelas). Aktifkan PAP di sisi klien dan coba lagi.
@ -4588,8 +4588,8 @@ CMD_ListenerDisable_PortPrompt Nomor port dari Listener TCP/IP yang akan dihenti
# PortsUDPSet command
CMD_PortsUDPSet Mengatur Port UDP yang Harus Didengarkan oleh Server
CMD_PortsUDPSet_Help Perintah ini dapat digunakan untuk menentukan satu atau beberapa port UDP yang harus didengarkan oleh server. \nAnda dapat menentukan port yang sedang digunakan oleh proses lain, namun server tidak akan dapat menggunakannya sampai port tersebut menjadi bebas. \nTentukan nomor port yang berada dalam rentang 1 hingga 65535. \nAnda dapat melihat port yang saat ini telah disetel dengan perintah PortsUDPGet. \nUntuk menjalankan perintah ini, Anda harus memiliki hak akses administrator VPN Server.
CMD_PortsUDPSet_Args PortsUDPSet [port]
CMD_PortsUDPSet_[port] Beberapa port UDP dapat ditentukan dengan memisahkannya menggunakan spasi atau koma, misalnya: "443, 992, 1194, 5555". \nTentukan "0" untuk menonaktifkan pendengar UDP. \n\nPort:
CMD_PortsUDPSet_Args PortsUDPSet [ports]
CMD_PortsUDPSet_[ports] Beberapa port UDP dapat ditentukan dengan memisahkannya menggunakan spasi atau koma, misalnya: "443, 992, 1194, 5555". \nTentukan "0" untuk menonaktifkan pendengar UDP. \n\nPort:
# PortsUDPGet command
@ -4602,11 +4602,11 @@ CMD_PortsUDPGet_Ports Port UDP
# ProtoOptionsSet command
CMD_ProtoOptionsSet Mengatur nilai opsi untuk protokol yang ditentukan
CMD_ProtoOptionsSet_Help Perintah ini dapat digunakan untuk mengubah nilai opsi untuk protokol tertentu. \nAnda dapat mengambil opsi menggunakan perintah ProtoOptionsGet. \nUntuk menjalankan perintah ini, Anda harus memiliki hak istimewa administrator VPN Server.
CMD_ProtoOptionsSet_Args ProtoOptionsSet [protokol] [/NAME:nama_opsi] [/VALUE:string/true/false]
CMD_ProtoOptionsSet_[protokol] Nama protokol.
CMD_ProtoOptionsSet_Args ProtoOptionsSet [protocol] [/NAME:option_name] [/VALUE:string/true/false]
CMD_ProtoOptionsSet_[protocol] Nama protokol.
CMD_ProtoOptionsSet_NAME Nama opsi.
CMD_ProtoOptionsSet_VALUE Nilai opsi. Pastikan untuk menulis nilai yang diterima oleh protokol yang ditentukan!
CMD_ProtoOptionsSet_Prompt_[protokol] Protokol:
CMD_ProtoOptionsSet_Prompt_[protocol] Protokol:
CMD_ProtoOptionsSet_Prompt_NAME Opsi:
CMD_ProtoOptionsSet_Prompt_VALUE Nilai:
@ -4614,9 +4614,9 @@ CMD_ProtoOptionsSet_Prompt_VALUE Nilai:
# ProtoOptionsGet command
CMD_ProtoOptionsGet Menampilkan opsi untuk protokol yang ditentukan
CMD_ProtoOptionsGet_Help Perintah ini dapat digunakan untuk mengambil opsi untuk protokol tertentu. \nInformasi detail (misalnya tipe nilai) akan ditampilkan. \nAnda dapat mengubah nilai opsi dengan perintah ProtoOptionsSet.
CMD_ProtoOptionsGet_Args ProtoOptionsGet [protokol]
CMD_ProtoOptionsGet_[protokol] Nama protokol.
CMD_ProtoOptionsGet_Prompt_[protokol] Protokol:
CMD_ProtoOptionsGet_Args ProtoOptionsGet [protocol]
CMD_ProtoOptionsGet_[protocol] Nama protokol.
CMD_ProtoOptionsGet_Prompt_[protocol] Protokol:
CMD_ProtoOptionsGet_Column_Name Nama
CMD_ProtoOptionsGet_Column_Type Tipe
CMD_ProtoOptionsGet_Column_Value Nilai
@ -4633,8 +4633,8 @@ CMD_ProtoOptions_Description_OpenVPN_Timeout Waktu dalam milidetik setelah
# ServerPasswordSet command
CMD_ServerPasswordSet Setel Kata Sandi Administrator VPN Server
CMD_ServerPasswordSet_Help Ini mengatur kata sandi administrator VPN Server. Anda dapat menentukan kata sandi sebagai parameter. Jika kata sandi tidak ditentukan, prompt akan ditampilkan untuk memasukkan kata sandi dan konfirmasi kata sandi. Jika Anda menyertakan kata sandi sebagai parameter, kata sandi ini akan ditampilkan sesaat di layar, yang dapat menimbulkan risiko. Kami menyarankan agar sebisa mungkin, hindari menentukan parameter ini dan masukkan kata sandi menggunakan prompt kata sandi. \nUntuk mengeksekusi perintah ini, Anda harus memiliki hak istimewa administrator VPN Server.
CMD_ServerPasswordSet_Args ServerPasswordSet [kata_sandi]
CMD_ServerPasswordSet_[kata_sandi] Ini menentukan pengaturan kata sandi baru.
CMD_ServerPasswordSet_Args ServerPasswordSet [password]
CMD_ServerPasswordSet_[password] Ini menentukan pengaturan kata sandi baru.
# ClusterSettingGet command
@ -5232,25 +5232,25 @@ CMD_StatusGet_Args StatusGet
# LogGet command
CMD_LogGet Dapatkan Pengaturan Penyimpanan Log dari Hub Virtual
CMD_LogGet_Help Gunakan ini untuk mendapatkan pengaturan penyimpanan log dari Hub Virtual yang sedang dikelola. Anda dapat memperoleh informasi pengaturan seperti pengaturan penyimpanan terkait log keamanan dan log paket serta informasi tentang apa yang telah disimpan.
CMD_LogGet_Args LogGet
CMD_Log_Security Log Simpan Log Keamanan
CMD_Log_PacketLog Simpan Log Paket
CMD_Log_SwitchType Siklus Pergantian File Log
CMD_Log_0 Log Koneksi TCP
CMD_Log_1 Log Paket TCP
CMD_Log_2 Log DHCP
CMD_Log_3 Log UDP
CMD_Log_4 Log ICMP
CMD_Log_5 Log IP
CMD_Log_6 Log ARP
CMD_Log_7 Log Ethernet
CMD_LogGet Dapatkan Pengaturan Penyimpanan Log dari Hub Virtual
CMD_LogGet_Help Gunakan ini untuk mendapatkan pengaturan penyimpanan log dari Hub Virtual yang sedang dikelola. Anda dapat memperoleh informasi pengaturan seperti pengaturan penyimpanan terkait log keamanan dan log paket serta informasi tentang apa yang telah disimpan.
CMD_LogGet_Args LogGet
CMD_Log_SecurityLog Simpan Log Keamanan
CMD_Log_PacketLog Simpan Log Paket
CMD_Log_SwitchType Siklus Pergantian File Log
CMD_Log_0 Log Koneksi TCP
CMD_Log_1 Log Paket TCP
CMD_Log_2 Log DHCP
CMD_Log_3 Log UDP
CMD_Log_4 Log ICMP
CMD_Log_5 Log IP
CMD_Log_6 Log ARP
CMD_Log_7 Log Ethernet
# LogEnable command
CMD_LogEnable Mengaktifkan Log Keamanan atau Log Paket
CMD_LogEnable_Help Gunakan ini untuk mengaktifkan log keamanan atau log paket dari Hub Virtual yang sedang dikelola. \nUntuk mendapatkan pengaturan saat ini, Anda dapat menggunakan perintah LogGet.
CMD_LogEnable Mengaktifkan Log Keamanan atau Log Paket
CMD_LogEnable_Help Gunakan ini untuk mengaktifkan log keamanan atau log paket dari Hub Virtual yang sedang dikelola. \nUntuk mendapatkan pengaturan saat ini, Anda dapat menggunakan perintah LogGet.
CMD_LogEnable_Args LogEnable [security|packet]
CMD_LogEnable_[security|packet] Pilih jenis log untuk diaktifkan. Tentukan "keamanan" atau "paket".
CMD_LogEnable_Prompt Pilih Keamanan atau Paket:
@ -5421,7 +5421,7 @@ CMD_CascadeEncryptDisable_[name] Tentukan nama Koneksi Cascade yang pengaturanny
# CascadeCompressEnable command
CMD_CascadeCompressEnable Aktifkan Kompresi Data saat Berkomunikasi melalui Koneksi Cascade
CMD_CascadeCompressEnable_Help Ketika Koneksi Cascade yang terdaftar pada Virtual Hub yang saat ini dikelola ditentukan dan Koneksi Cascade tersebut digunakan untuk komunikasi antara Server VPN melalui koneksi VPN, gunakan ini untuk mengatur agar isi komunikasi antara Server VPN dikompresi. \nMungkin mencapai kompresi maksimal hingga 80%. Namun, kompresi memberikan beban yang lebih tinggi pada CPU baik pada mesin klien maupun server. Ketika kecepatan garis sekitar 10 Mbps atau lebih, kompresi dapat menurunkan throughput, tetapi terkadang dapat memiliki efek sebaliknya. \nAnda tidak dapat menjalankan perintah ini untuk Virtual Hub pada Server VPN yang beroperasi sebagai cluster.
CMD_CascadeCompressEnable_Help Ketika Koneksi Cascade yang terdaftar pada Virtual Hub yang saat ini dikelola ditentukan dan Koneksi Cascade tersebut digunakan untuk komunikasi antara Server VPN melalui koneksi VPN, gunakan ini untuk mengatur agar isi komunikasi antara Server VPN dikompresi. \nKompresi dapat mencapai hingga 80% efisiensi dalam mengurangi ukuran data. Namun, kompresi memberikan beban yang lebih tinggi pada CPU baik pada mesin klien maupun server. Ketika kecepatan garis sekitar 10 Mbps atau lebih, kompresi dapat menurunkan throughput, tetapi terkadang dapat memiliki efek sebaliknya. \nAnda tidak dapat menjalankan perintah ini untuk Virtual Hub pada Server VPN yang beroperasi sebagai cluster.
CMD_CascadeCompressEnable_Args CascadeCompressEnable [name]
CMD_CascadeCompressEnable_[name] Tentukan nama Koneksi Cascade yang pengaturannya ingin Anda ubah.
@ -5685,8 +5685,8 @@ CMD_AccessAddEx_SRCMAC Tentukan alamat MAC sumber sebagai aturan. Tentukan alam
CMD_AccessAddEx_DESTMAC Tentukan alamat MAC tujuan sebagai aturan. Gunakan metode yang sama seperti untuk parameter /SRCMAC.
CMD_AccessAddEx_TCPSTATE Tentukan status koneksi TCP sebagai aturan. Gunakan Established atau Unestablished.
CMD_AccessAddEx_DELAY Tentukan nilai ini untuk menghasilkan keterlambatan ketika paket melewati. Tentukan periode keterlambatan dalam milidetik. Menentukan 0 berarti tidak ada keterlambatan yang dihasilkan. Keterlambatan maksimal adalah 10000 milidetik.
CMD_AccessAddEx_JITTER Tentukan nilai ini untuk menghasilkan jitter ketika paket melewati. Tentukan rasio fluktuasi jitter dalam kisaran 0% hingga 100%. Menentukan 0 berarti tidak ada jitter yang dihasilkan.
CMD_AccessAddEx_LOSS Tentukan nilai ini untuk menghasilkan kehilangan paket ketika paket melewati. Tentukan rasio kehilangan paket dalam kisaran 0% hingga 100%. Menentukan 0 berarti tidak ada kehilangan paket yang dihasilkan.
CMD_AccessAddEx_JITTER Tentukan nilai ini untuk menghasilkan jitter ketika paket melewati. Rasio fluktuasi jitter dapat ditentukan dalam kisaran dari 0% hingga 100% sesuai kebutuhan. Menentukan 0 berarti tidak ada jitter yang dihasilkan.
CMD_AccessAddEx_LOSS Tentukan nilai ini untuk menghasilkan kehilangan paket ketika paket melewati. Rasio kehilangan paket dapat ditentukan dalam kisaran dari 0% hingga 100% sesuai kebutuhan. Menentukan 0 berarti tidak ada kehilangan paket yang dihasilkan.
CMD_AccessAddEx_REDIRECTURL URL yang ditentukan akan dijawab wajib kepada klien sebagai respons untuk paket permintaan koneksi TCP yang cocok dengan kondisi entri daftar akses ini melalui Virtual Hub ini. Untuk menggunakan pengaturan ini, kamu dapat memaksa browser web di komputer VPN Client untuk menunjukkan situs web yang ditentukan ketika browser tersebut mencoba mengakses alamat IP tertentu.
CMD_AccessAddEx_Prompt_DELAY Keterlambatan yang Akan Dihasilkan (dalam milidetik: 0 - 10000):
CMD_AccessAddEx_Prompt_JITTER Fluktuasi Jitter yang Akan Dihasilkan (Persen: 0 - 100):
@ -5747,8 +5747,8 @@ CMD_AccessAddEx6_SRCMAC Tentukan alamat MAC sumber sebagai aturan. Tentukan ala
CMD_AccessAddEx6_DESTMAC Tentukan alamat MAC tujuan sebagai aturan. Gunakan metode yang sama seperti untuk parameter /SRCMAC.
CMD_AccessAddEx6_TCPSTATE Tentukan status koneksi TCP sebagai aturan. Gunakan Established atau Unestablished.
CMD_AccessAddEx6_DELAY Tentukan nilai ini untuk menghasilkan keterlambatan saat paket melewati. Tentukan periode keterlambatan dalam milidetik. Tentukan 0 berarti tidak ada keterlambatan yang dihasilkan. Keterlambatan maksimal yang dapat dihasilkan adalah 10000 milidetik.
CMD_AccessAddEx6_JITTER Tentukan nilai ini untuk menghasilkan jitter saat paket melewati. Tentukan rasio fluktuasi jitter dalam rentang 0% hingga 100%. Tentukan 0 berarti tidak ada jitter yang dihasilkan.
CMD_AccessAddEx6_LOSS Tentukan nilai ini untuk menghasilkan kehilangan paket saat paket melewati. Tentukan rasio kehilangan paket dalam rentang 0% hingga 100%. Tentukan 0 berarti tidak ada kehilangan paket yang dihasilkan.
CMD_AccessAddEx6_JITTER Tentukan nilai ini untuk menghasilkan jitter ketika paket melewati. Rasio fluktuasi jitter dapat ditentukan dalam kisaran dari 0% hingga 100% sesuai kebutuhan. Menentukan 0 berarti tidak ada jitter yang dihasilkan.
CMD_AccessAddEx6_LOSS Tentukan nilai ini untuk menghasilkan kehilangan paket ketika paket melewati. Rasio kehilangan paket dapat ditentukan dalam kisaran dari 0% hingga 100% sesuai kebutuhan. Menentukan 0 berarti tidak ada kehilangan paket yang dihasilkan.
CMD_AccessAddEx6_REDIRECTURL URL yang ditentukan akan dijawab secara wajib kepada klien sebagai respons untuk paket permintaan koneksi TCP yang cocok dengan kondisi entri daftar akses ini melalui Virtual Hub ini. Untuk menggunakan pengaturan ini, kamu dapat memaksa peramban web pada komputer VPN Client untuk menampilkan situs web yang ditentukan ketika peramban web tersebut mencoba mengakses alamat IP tertentu.
CMD_AccessAddEx6_Prompt_DELAY Keterlambatan untuk Dihasilkan (dalam milidetik: 0 - 10000):
CMD_AccessAddEx6_Prompt_JITTER Fluktuasi Jitter untuk Dihasilkan (Persen: 0 - 100):
@ -6728,7 +6728,7 @@ CMD_AccountEncryptDisable_[name] Tentukan nama Pengaturan Koneksi VPN yang penga
# AccountCompressEnable command
CMD_AccountCompressEnable Aktifkan Kompresi Data saat Berkomunikasi melalui Pengaturan Koneksi VPN
CMD_AccountCompressEnable_Help Ketika Pengaturan Koneksi VPN yang terdaftar di VPN Client ditentukan dan Pengaturan Koneksi VPN tersebut digunakan untuk komunikasi antara VPN Server melalui koneksi VPN, gunakan ini untuk mengatur konten komunikasi antara VPN Server agar dikompresi. \nKompresi dapat mencapai hingga 80%. Namun, kompresi memberikan beban yang lebih tinggi pada CPU baik di mesin klien maupun server. Ketika kecepatan jalur sekitar 10 Mbps atau lebih, kompresi dapat menurunkan throughput, tetapi kadang-kadang dapat memiliki efek sebaliknya.
CMD_AccountCompressEnable_Help Ketika Pengaturan Koneksi VPN yang terdaftar di VPN Client ditentukan dan Pengaturan Koneksi VPN tersebut digunakan untuk komunikasi antara VPN Server melalui koneksi VPN, gunakan ini untuk mengatur konten komunikasi antara VPN Server agar dikompresi. \nKompresi dapat mencapai hingga 80% efisiensi dalam mengurangi ukuran data. Namun, kompresi memberikan beban yang lebih tinggi pada CPU baik di mesin klien maupun server. Ketika kecepatan jalur sekitar 10 Mbps atau lebih, kompresi dapat menurunkan throughput, tetapi kadang-kadang dapat memiliki efek sebaliknya.
CMD_AccountCompressEnable_Args AccountCompressEnable [name]
CMD_AccountCompressEnable_[name] Tentukan nama Pengaturan Koneksi VPN yang pengaturannya ingin Anda ubah.