Updates to take out UDP and do this at the AX.25 level
This commit is contained in:
parent
258b59198a
commit
738ea6e75e
@ -1,4 +1,4 @@
|
|||||||
# CRAPRNIAC: Completely Ridiculous Amateur Protocol for Radio Node IP Auto-Configuration
|
# CRAPRNIAC: Completely Ridiculous Amateur Protocol for Radio Node IP Address Configuration
|
||||||
|
|
||||||
## Status of this Memo
|
## Status of this Memo
|
||||||
|
|
||||||
@ -8,10 +8,9 @@ This document describes version 0.1a of CRAPRNIAC, a protocol designed to facili
|
|||||||
|
|
||||||
Existing service discovery and dynamic host configuration protocols for TCP/IP networks are not ideal for bandwidth-constrained, high-latency, and lossy VHF packet radio environments. CRAPRNIAC addresses this by defining a join-and-configure protocol between a "base station" and one or more "client stations" that aims to cut the chatter.
|
Existing service discovery and dynamic host configuration protocols for TCP/IP networks are not ideal for bandwidth-constrained, high-latency, and lossy VHF packet radio environments. CRAPRNIAC addresses this by defining a join-and-configure protocol between a "base station" and one or more "client stations" that aims to cut the chatter.
|
||||||
|
|
||||||
The goal is to:
|
The goals are to:
|
||||||
- Minimize the number of packet exchanges required for a client to join a VHF packet network.
|
- Let a client discover a nearby base station, request an IP address, and join a packet network.
|
||||||
- Allow manual or automatic IP configuration with a minimum of overhead.
|
- Bring honor to you and your house?
|
||||||
- Bring honor to you and your house.
|
|
||||||
|
|
||||||
## 2. Protocol Overview
|
## 2. Protocol Overview
|
||||||
|
|
||||||
@ -26,6 +25,8 @@ CRAPRNIAC defines four primary message types:
|
|||||||
|
|
||||||
Messages are transmitted as plain ASCII text using simple pipe-separated (`|`) fields, allowing easy parsing by humans and computers alike.
|
Messages are transmitted as plain ASCII text using simple pipe-separated (`|`) fields, allowing easy parsing by humans and computers alike.
|
||||||
|
|
||||||
|
The protocol is versioned and extensible to allow for a future in which this is relevant enough for there to be concern over compatibility.
|
||||||
|
|
||||||
## 3. Message Format
|
## 3. Message Format
|
||||||
|
|
||||||
Each CRAPRNIAC message is a single text string with the following general format:
|
Each CRAPRNIAC message is a single text string with the following general format:
|
||||||
@ -93,26 +94,26 @@ Fields:
|
|||||||
|
|
||||||
## 6. Design Considerations
|
## 6. Design Considerations
|
||||||
|
|
||||||
- **Minimal Airtime Usage:** Critical for low-bandwidth links.
|
- Make it, despite its name, not crappy
|
||||||
- **Human-Readable:** Easy troubleshooting with a dumb terminal.
|
|
||||||
- **Flexibility:** Can extend in future versions with additional fields.
|
|
||||||
- **Backward Compatibility:** Protocol version prefix allows for graceful upgrades.
|
|
||||||
|
|
||||||
## 7. Security Considerations
|
## 7. Security Considerations
|
||||||
|
|
||||||
The S in CRAPRNIAC stands for Security!
|
That's what the 'S' in CRAPRNIAC stands for.
|
||||||
|
|
||||||
## 8. Other Considerations
|
## 8. Other Considerations
|
||||||
|
|
||||||
CRAPRNIAC will squat on whatever amateur frequencies operators choose.
|
- CRAPRNIAC does not prescribe a particular lower-layer protocol, though it is designed with a working AX.25 stack in mind, whether that's a classic serial TNC, a more modern bluetooth doodad, or Direwolf with kissattach creating an ax0 interface. The example implementation uses UDP packets over IP over AX.25.
|
||||||
|
- CRAPRNIAC will squat on an amateur frequency of the operator's choice.
|
||||||
|
|
||||||
## 9. Conclusion
|
## 9. Conclusion
|
||||||
|
|
||||||
CRAPRNIAC provides a starting point for connecting TCP/IP stacks over slow amateur radio links. By limiting the number and length of transmissions required for negotiation, it offers networking over VHF that works like it smells.
|
CRAPRNIAC provides a starting point for connecting TCP/IP stacks over slow amateur radio links. By limiting the number and length of transmissions required for negotiation, it offers networking over VHF that works as nice as it smells.
|
||||||
|
|
||||||
## 10. Further Development
|
## 10. Further Development
|
||||||
|
|
||||||
Future enhancements may include optional mesh extensions self-organizing slowness.
|
- Future enhancements may include optional mesh extensions for self-organizing slowness.
|
||||||
|
- A TLV protocol would be more compact. But why make it more efficient when the transmissions are literally slow enough to read with your eyes?
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@ -2,13 +2,11 @@ import socket
|
|||||||
import time
|
import time
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
BROADCAST_IP = "127.0.0.1"
|
|
||||||
PORT = 4444
|
|
||||||
|
|
||||||
BEACON_INTERVAL = 10 # seconds
|
|
||||||
BASE_CALLSIGN = "KI5QKX-10"
|
BASE_CALLSIGN = "KI5QKX-10"
|
||||||
NETWORK_NAME = "HAMNET-HOUSTON"
|
NETWORK_NAME = "HAMNET-HOUSTON"
|
||||||
|
|
||||||
|
BEACON_INTERVAL = 10 # seconds
|
||||||
|
|
||||||
# Fake IP pool
|
# Fake IP pool
|
||||||
IP_POOL = [
|
IP_POOL = [
|
||||||
"44.127.254.12",
|
"44.127.254.12",
|
||||||
@ -71,14 +69,14 @@ def handle_request(data, addr, sock):
|
|||||||
def beacon_loop(sock):
|
def beacon_loop(sock):
|
||||||
while True:
|
while True:
|
||||||
beacon = build_beacon().encode('utf-8')
|
beacon = build_beacon().encode('utf-8')
|
||||||
sock.sendto(beacon, (BROADCAST_IP, PORT))
|
# Beacon to *broadcast* — here we'll just send to our own callsign for now
|
||||||
|
sock.sendto(beacon, ('CRAPR-0',))
|
||||||
print(f"Sent beacon: {beacon.decode('utf-8')}")
|
print(f"Sent beacon: {beacon.decode('utf-8')}")
|
||||||
time.sleep(BEACON_INTERVAL)
|
time.sleep(BEACON_INTERVAL)
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
sock = socket.socket(socket.AF_AX25, socket.SOCK_DGRAM)
|
||||||
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
sock.bind((BASE_CALLSIGN,)) # Bind to our station callsign
|
||||||
# sock.bind((BROADCAST_IP, PORT))
|
|
||||||
|
|
||||||
print(f"Base Station {BASE_CALLSIGN} starting up on {NETWORK_NAME}...")
|
print(f"Base Station {BASE_CALLSIGN} starting up on {NETWORK_NAME}...")
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,6 @@
|
|||||||
import socket
|
import socket
|
||||||
import time
|
import time
|
||||||
|
|
||||||
LISTEN_IP = "0.0.0.0"
|
|
||||||
PORT = 4444
|
|
||||||
|
|
||||||
CLIENT_CALLSIGN = "N0CALL-7"
|
CLIENT_CALLSIGN = "N0CALL-7"
|
||||||
|
|
||||||
configured = False
|
configured = False
|
||||||
@ -33,9 +30,8 @@ def apply_network_config(assigned_ip, gateway, dns, lease_time):
|
|||||||
def main():
|
def main():
|
||||||
global configured, lease_expiration
|
global configured, lease_expiration
|
||||||
|
|
||||||
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
sock = socket.socket(socket.AF_AX25, socket.SOCK_DGRAM)
|
||||||
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
sock.bind((CLIENT_CALLSIGN,)) # Bind to our own callsign
|
||||||
sock.bind((LISTEN_IP, PORT))
|
|
||||||
|
|
||||||
print(f"Client {CLIENT_CALLSIGN} listening for CRAPRNIAC beacons...")
|
print(f"Client {CLIENT_CALLSIGN} listening for CRAPRNIAC beacons...")
|
||||||
|
|
||||||
@ -64,7 +60,7 @@ def main():
|
|||||||
print(f" Network: {network_name}")
|
print(f" Network: {network_name}")
|
||||||
print("Sending join request...")
|
print("Sending join request...")
|
||||||
request = build_request(network_name).encode('utf-8')
|
request = build_request(network_name).encode('utf-8')
|
||||||
sock.sendto(request, addr)
|
sock.sendto(request, (base_callsign,))
|
||||||
|
|
||||||
elif parts[1] == "CRAP_ACCEPT":
|
elif parts[1] == "CRAP_ACCEPT":
|
||||||
client_callsign = parts[2]
|
client_callsign = parts[2]
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user