Skip to content

1.2.1 Syntax v0.2

Mark Bednarczyk edited this page Nov 14, 2024 · 1 revision

Absolutely! Refining the JNet Packet Language (JNPL) to handle protocol fields efficiently and simplifying the distribution syntax will enhance both its readability and usability. Below, I provide detailed suggestions and updated syntax examples addressing your requirements:


1. Utilizing Protocol Fields

To effectively utilize protocol fields such as Ip[Src] or Ip[Flags], it's essential to establish a clear and consistent syntax that allows users to reference nested or specific protocol attributes intuitively. Here are some strategies and examples to achieve this:

a. Dot Notation vs. Bracket Notation

  • Dot Notation (Ip.Src):

    • Pros: More familiar to users of many programming languages.
    • Cons: Might conflict with existing language constructs or object properties.
  • Bracket Notation (Ip[Src]):

    • Pros: Clearly distinguishes protocol fields from other identifiers.
    • Cons: Slightly more verbose but offers better clarity for nested fields.

Recommendation: Use Bracket Notation (Ip[Src]) for clarity and to avoid conflicts, especially when dealing with nested or hierarchical protocol fields.

b. Defining Protocol Fields

Ensure that protocol fields are well-defined within the language's grammar. This includes specifying supported protocols and their respective fields.

Example Definition:

// Supported Protocols and Fields
protocols {
    IP {
        fields: [Src, Dst, Flags, TTL, Protocol]
    }
    TCP {
        fields: [SrcPort, DstPort, Flags, Seq, Ack]
    }
    UDP {
        fields: [SrcPort, DstPort, Length, Checksum]
    }
    // Add more protocols as needed
}

c. Example Usage with Protocol Fields

Here are refined examples incorporating protocol fields using bracket notation:

// Filter packets with Source IP 192.168.1.1 and SYN flag set
filter_syn_packets {
    filter {
        Ip[Src] == 192.168.1.1
        and Ip[Flags] == SYN
    }
    action {
        log "SYN packet from 192.168.1.1 detected"
        assign priority high
        accept
    }
    priority = 5
}
// Drop packets with TTL less than 64 or malformed headers
filter_error_packets {
    filter {
        Ip[TTL] < 64
        or malformed_header == true
    }
    action {
        log "Error condition detected: Low TTL or Malformed Header"
        drop
    }
    priority = 0
}

2. Simplifying the distribute_to Section

To make the distribution syntax more concise, especially when distributing traffic to multiple buffers based on hash values, introducing a range-based shorthand can significantly enhance readability. Here's how you can implement and utilize this feature:

a. Introducing Range-Based Distribution

Syntax Proposal:

distribute = (start..end) to [action]
  • (start..end): Defines a range of buffer IDs.
  • to: Keyword indicating the distribution target.
  • [action]: Defines the action to be taken, such as assigning to a buffer or stream.

b. Defining Distribution Modes

To further streamline the distribution process, define distribution modes such as hashmode, which determines how the hash value is utilized to distribute packets.

Example Definition:

// Distribution Modes
distribution_modes {
    hashmode: {
        description: "Distribute based on hash modulo operation",
        operation: "hash % N" // N is the number of buffers
    }
    // Add more distribution modes as needed
}

c. Example Usage with Simplified Distribution

Here are updated examples demonstrating the simplified distribute syntax:

// Assign traffic to buffers 0 through 3 based on hash of src_ip and dst_port using hashmode
assign_distributed_buffers {
    filter {
        protocol == TCP
        and Ip[Src] in 192.168.0.0/16
        and Ip[DstPort] in 80, 443, 8080
    }
    
    hash {
        fields = [Ip[Src], Ip[DstPort]]
        algorithm = CRC32
    }
    
    distribute = (0..3) to buffer_handle based on hashmode
    
    priority = 10
}

Explanation:

  • distribute = (0..3) to buffer_handle based on hashmode:
    • Distributes packets to buffers with IDs 0, 1, 2, and 3.
    • The distribution is determined by applying the hashmode, which could be defined as hash % 4 to map the hash value to one of the four buffers.
// Distribute traffic to packet streams 0 through 3 based on current hash and hashmode
assign_distributed_streams {
    filter {
        protocol == UDP
        and Ip[Src] in 10.0.0.0/8
        and Ip[DstPort] in 53, 123
    }
    
    hash {
        fields = [Ip[Src], Ip[DstPort], payload_length]
        algorithm = SHA256
    }
    
    distribute = (0..3) to packet_stream based on hashmode
    
    priority = 12
}

Additional Example Incorporating Both Protocol Fields and Simplified Distribution:

// Comprehensive example: Assign traffic based on hash, slice payload, and handle errors with simplified distribution
assign_complex_traffic {
    // Filter to select all IPv4 TCP traffic
    filter {
        Ip[Version] == 4
        and protocol == TCP
    }
    
    // Check for error conditions
    if (Ip[Checksum] == false) {
        action {
            log "Checksum error detected"
            drop
            notify "checksum_error"
        }
        priority = 1
        exit
    }
    
    // Generate hash based on src_ip and dst_port
    hash {
        fields = [Ip[Src], Ip[DstPort]]
        algorithm = SHA256
    }
    
    // Simplified distribution to buffers 0 through 3
    distribute = (0..3) to buffer_handle based on hashmode
    
    // Slice payload at offset 256
    slice {
        offset = 256
        length = 128
        store_as "important_data"
    }
    
    // Perform action based on sliced data
    if important_data contains "CONFIDENTIAL" {
        action {
            encrypt "AES-256"
            assign priority critical
            forward to "secure_buffer"
        }
    } else {
        action {
            assign priority normal
            forward to "regular_buffer"
        }
    }
    
    priority = 5
}

3. Comprehensive Refined Syntax Examples

Incorporating the above suggestions, here are additional refined JNPL syntax examples demonstrating various functionalities:

a. Filtering Based on Inner Protocol Flags

// Filter packets with inner protocol flags set to ACK
filter_inner_ack {
    filter {
        Ip[Protocol] == TCP
        and TCP[Flags] == ACK
    }
    action {
        log "ACK flag detected in TCP packet"
        assign priority medium
        accept
    }
    priority = 10
}

b. Distributing Traffic to Multiple Buffers with Range Syntax

// Distribute UDP traffic to buffers 0 through 3 based on hash of src_ip and dst_port
assign_udp_buffers {
    filter {
        protocol == UDP
        and Ip[Src] in 172.16.0.0/12
        and Ip[DstPort] in 53, 123
    }
    
    hash {
        fields = [Ip[Src], Ip[DstPort]]
        algorithm = MD5
    }
    
    distribute = (0..3) to buffer_handle based on hashmode
    
    priority = 15
}

c. Handling Multiple Encapsulation Layers with Simplified Distribution

// Handle MPLS over VLAN and distribute to packet streams 0 through 3
handle_mpls_vlan_distribute {
    filter {
        encapsulation == VLAN
        and inner_encapsulation == MPLS
        and inner_protocol == BGP
    }
    
    action {
        log "Processing BGP over MPLS over VLAN"
        assign priority 8
        to_module "bgp_handler"
    }
    
    distribute = (0..3) to packet_stream based on hashmode
    
    priority = 12
}

d. Priority-Based Overlapping Filters with Simplified Distribution

// Priority-based overlapping filters with simplified distribution

// Highest priority: Block all traffic from blacklisted IPs
block_blacklisted_ips {
    filter {
        Ip[Src] in blacklisted_ips
    }
    action {
        log "Blocked traffic from blacklisted IP"
        drop
    }
    priority = 0
}

// High priority: Prioritize traffic to critical services and distribute to buffers 0-3
prioritize_critical_services {
    filter {
        Ip[DstPort] in [22, 443, 8443]
    }
    action {
        assign priority high
        distribute = (0..3) to buffer_handle based on hashmode
    }
    priority = 5
}

// Medium priority: Log all HTTP traffic
log_http_traffic {
    filter {
        Ip[DstPort] == 80
    }
    action {
        log "HTTP traffic detected"
    }
    priority = 10
}

// Low priority: Assign general traffic to standard processing and distribute
assign_standard_traffic {
    filter {
        protocol == TCP
    }
    action {
        assign to_module "standard_tcp_processor"
        distribute = (0..3) to buffer_handle based on hashmode
    }
    priority = 20
}

// Lowest priority: Catch-all rule
catch_all {
    filter {
        true
    }
    action {
        assign to_module "default_handler"
        distribute = (0..3) to buffer_handle based on hashmode
    }
    priority = 64
}

4. Additional Suggestions and Best Practices

a. Enhancing Readability with Indentation and Consistent Formatting

Maintain consistent indentation and formatting to improve the readability of JNPL scripts. This practice helps users quickly understand the structure and flow of the rules.

Example:

assign_example {
    filter {
        Ip[Src] == 10.0.0.1
        and Ip[Flags] == SYN
    }
    
    hash {
        fields = [Ip[Src], Ip[DstPort]]
        algorithm = CRC32
    }
    
    distribute = (0..3) to buffer_handle based on hashmode
    
    priority = 10
}

b. Utilizing Comments for Clarity

Incorporate comments to explain complex logic or the purpose of specific rules. This aids in maintaining and troubleshooting scripts.

// Assign TCP traffic from 10.0.0.1 with SYN flag to buffers 0-3
assign_syn_traffic {
    filter {
        Ip[Src] == 10.0.0.1
        and Ip[Flags] == SYN
    }
    
    hash {
        fields = [Ip[Src], Ip[DstPort]]
        algorithm = CRC32
    }
    
    // Distribute based on hash modulo operation
    distribute = (0..3) to buffer_handle based on hashmode
    
    priority = 10
}

c. Modularizing Rules for Reusability

Break down complex rules into smaller, reusable modules or functions. This promotes modularity and reduces redundancy.

Example:

// Define a reusable filter for critical ports
filter_critical_ports {
    protocol == TCP
    and Ip[DstPort] in [22, 443, 8443]
}

// Assign critical traffic using the reusable filter
assign_critical_traffic {
    filter {
        include filter_critical_ports
    }
    
    action {
        assign priority high
        distribute = (0..3) to buffer_handle based on hashmode
    }
    
    priority = 5
}

d. Error Handling and Default Rules

Always include error handling and default catch-all rules to ensure that unexpected packets are managed appropriately.

// Handle packets with unknown protocols
handle_unknown_protocols {
    filter {
        protocol not in [TCP, UDP, ICMP]
    }
    action {
        log "Unknown protocol detected"
        drop
    }
    priority = 30
}

// Default catch-all rule
default_rule {
    filter {
        true
    }
    action {
        assign to_module "default_handler"
        distribute = (0..3) to buffer_handle based on hashmode
    }
    priority = 64
}

5. Final Thoughts

By integrating these suggestions, JNPL will offer a more streamlined and intuitive syntax, facilitating easier script writing and maintenance. Here's a summary of the key enhancements:

  1. Protocol Field Utilization:

    • Adopt Bracket Notation (Ip[Src]) for clarity.
    • Clearly define supported protocols and their fields.
  2. Simplified Distribution Syntax:

    • Introduce range-based distribution ((0..3)).
    • Utilize distribution modes like hashmode for flexibility.
  3. Enhanced Readability and Maintainability:

    • Consistent formatting and indentation.
    • Comprehensive comments and documentation.
    • Modular rule definitions for reusability.
  4. Comprehensive Error Handling:

    • Implement rules to manage error conditions and unknown protocols.
    • Ensure the presence of default catch-all rules.

By adhering to these practices, JNPL can achieve a balance between flexibility, power, and ease of use, making it a robust tool for network packet management.

If you need further assistance in refining specific aspects of JNPL or have more queries about its syntax and features, feel free to reach out!

Clone this wiki locally