multiple ports
SNMP uses ports 161 and 162 as standard. This tool only attempts to scan port 161 by default. There is a -p option but this only takes one port. The code strtol(optarg, NULL, 10) == 0 will take the first number it finds in the string and set as the port, then drop everything else as soon as a bad character is encountered.
As such, -p161,162 will run, but only scan port 161. This is confusing and unexpected behavior given that the command runs without warning or error. The current code only ever errors out if -p begins with a non-numeric character.
Suggestion: Implement functionality for multiple ports to be scanned from one program invocation. Allow the tool to take 161,162 and know to scan both ports 161 and 162. Additionally, scan both 161 and 162 by default
I may be wrong about needing to scan p162. This port seems to be used for different types of calls. Having the option to specify multiple ports with -pmight still be nice though
Analysis of Issue #33: Multiple Port Support
I've analyzed this feature request and confirmed the current limitation. Here's a comprehensive analysis and implementation plan for adding multiple port support to onesixtyone.
Current Behavior Analysis
The current port parsing has a silent failure issue:
// Current code at line 295-300:
if (strtol(optarg, NULL, 10) == 0) {
printf("Malformed port: %s\n", optarg);
exit(1);
} else {
o.port = strtol(optarg, NULL, 10);
}
What happens with -p161,162:
-
strtol("161,162", NULL, 10)returns161and ignores,162 - No error or warning is shown
- Users think they're scanning both ports, but only port 161 is scanned
SNMP Port Context
Clarification on SNMP port usage:
- Port 161: SNMP agent (standard SNMP requests/responses)
- Port 162: SNMP trap receiver (notifications/alarms)
While port 162 is primarily for traps (not typical scanning), there are valid use cases for multi-port scanning:
- Non-standard SNMP configurations
- Security testing across multiple services
- Devices running SNMP on alternate ports
Implementation Plan
Phase 1: Basic Multiple Port Support
Data Structure Changes:
// Replace single port with array
struct {
int debug;
int log;
int ports[MAX_PORTS]; // New: array of ports
int port_count; // New: number of ports to scan
int print_ip;
int quiet;
long wait;
FILE* log_fd;
} o;
#define MAX_PORTS 16 // Reasonable limit
Port Parsing Enhancement:
case 'p':
o.port_count = parse_ports(optarg, o.ports, MAX_PORTS);
if (o.port_count <= 0) {
printf("Invalid port specification: %s\n", optarg);
printf("Valid formats: 161 or 161,162,8161\n");
exit(1);
}
break;
New Parsing Function:
int parse_ports(char *portstr, int *ports, int max_ports) {
char *str = strdup(portstr);
char *token;
int count = 0;
token = strtok(str, ",");
while (token != NULL && count < max_ports) {
char *endptr;
long port = strtol(token, &endptr, 10);
// Validate port
if (*endptr != '\0' || port <= 0 || port > 65535) {
free(str);
return -1; // Invalid port
}
ports[count++] = (int)port;
token = strtok(NULL, ",");
}
free(str);
return count;
}
Main Loop Modification:
// Wrap existing loop in port iteration
for (int p = 0; p < o.port_count; p++) {
remote_addr.sin_port = htons(o.ports[p]);
if (!o.quiet && o.port_count > 1) {
printf("Scanning port %d...\n", o.ports[p]);
}
for (c = 0; c < community_count; c++) {
// Existing community/host loops
for (i = 0; i < host_count; i++) {
// Existing scanning code
}
}
}
Phase 2: Enhanced Features (Optional)
-
Port Range Support (
-p161-163):- Parse ranges and expand them
- Useful for scanning sequential ports
-
Mixed Format (
-p161,8161-8163,9161):- Combine individual ports and ranges
- Maximum flexibility
-
Service Detection:
- Different timeouts for trap ports
- Port-specific community strings
Backward Compatibility
- Default behavior remains unchanged (port 161)
- Single port syntax (
-p161) works exactly as before - New syntax only activated with commas or ranges
Output Format Changes
For multiple ports, enhance output to show port number:
192.168.1.1:161 [public] Linux router 5.4.0
192.168.1.1:8161 [private] Custom SNMP Agent v2.0
Testing Recommendations
-
Single port (regression):
-p161 -
Multiple ports:
-p161,162,8161 -
Invalid formats:
-p161,abc,-p161,0,-p161,70000 -
Edge cases:
-p161,161(duplicate),-p(missing arg)
Security Considerations
- Limit maximum ports to prevent resource exhaustion
- Validate all port numbers (1-65535)
- Consider rate limiting for multiple port scans
Estimated Effort
- Basic implementation: ~100 lines of code changes
- Full implementation with ranges: ~200 lines
- Testing: Moderate complexity
- Documentation updates: README, man page, usage()
This enhancement would make onesixtyone more versatile for real-world scenarios where SNMP services run on non-standard ports, while maintaining backward compatibility and the tool's simplicity.