Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ hashes are given where a change is easiest to understand by reading the commit.
`--rsh-dir DIR`) answers TCP 514 at the gateway with `cat`, `dd`, `ls`, `echo`
and `pwd` on DIR, read-only, so the guest can pull files with
`rsh 192.168.0.1 cat /file` without a host `rshd`. It is not a shell and runs
nothing on the host. It speaks the BSD `rcmd` protocol, including the
nothing on the host. `exec /bin/sh` (what `inst` runs) is accepted: stdin is
run line by line against the same commands, including the
`( status=$? ; ... echo 'MARK\c' ; echo 'MARK'$status 1>&2 )` tail `inst`
waits for, `trap`, `echo X | dd`, `dd ... | fgrep STR` and the IRIX
`ls -inld` format; with `IRIS_RSH_TRACE` each line is logged. It speaks the BSD `rcmd` protocol, including the
stderr connection back to the guest from a reserved port. `src/net/rsh.rs`
is the protocol and the sandbox; `TcpService` gained `pull` (stream output
instead of holding it) and `side_connect` (a service asks for a connection
Expand Down
12 changes: 11 additions & 1 deletion HELP.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,17 @@ guest side of the NAT.
IRIX's `rsh` asks for a second connection for stderr; the gateway opens it back
to the guest from a reserved port, which `rcmd` insists on. With `rsh_dir` set,
guest connections to gateway port 514 are answered here instead of being
relayed to a host `rshd`. NAT mode only. Run `rsh -n` if the command should not
relayed to a host `rshd`. NAT mode only.

To see what a client (IRIX `inst`, say) asks for, start iris with
`IRIS_RSH_TRACE=1`. Each request is written to stderr when it arrives and again
when it ends, with the bytes moved, the time taken, and whether it completed,
was cut short by the guest, or never sent a whole request. This works in any
build; the `net debug` logging needs a `developer` build.
At startup iris prints `iris: rsh server ... serving DIR` when `rsh_dir` is on.
Every guest connection to port 514 is also reported with where it went, so a
trace with no requests means the guest never reached the built-in server (the
`rsh_dir` is unset, or `inst` is pointed at an address other than the gateway). Run `rsh -n` if the command should not
read the terminal.

### NAT
Expand Down
3 changes: 3 additions & 0 deletions src/net/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ impl NatEngine {
}
udp_services.push(svc);
}
if let Some(dir) = &config.rsh_dir {
eprintln!("iris: rsh server (read-only: cat, dd, ls, echo, pwd) serving {}", dir.display());
}
Self { config, host_dns: None, tx_cons, rx_prod, rx_wake, tx_wake, running, ctl,
udp_nat: HashMap::new(), tcp_nat: HashMap::new(),
icmp_nat: HashMap::new(), icmp_unavailable: false,
Expand Down
16 changes: 16 additions & 0 deletions src/net/nat_tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,18 @@ impl NatEngine {
let ends = Endpoints { guest_mac: client_mac, guest_ip: src_ip, guest_port: syn.sport(),
remote_ip: dst_ip, remote_port: dport };
let to_gw = dst_ip == self.config.gateway_ip;
if dport == RSH_PORT && super::rsh::trace_enabled() {
// Where did this guest rsh go? "No trace from the built-in server"
// usually means it never got the connection.
let verdict = if to_gw && self.config.rsh_dir.is_some() {
"answered by the built-in rsh server"
} else if to_gw {
"relayed to the host's port 514: rsh_dir is not set"
} else {
"relayed to that address: it is not the gateway"
};
eprintln!("iris: rsh: guest {}:{} -> {}:{}: {}", src_ip, syn.sport(), dst_ip, dport, verdict);
}
let backend = if to_gw && dport == TIME_PORT {
Backend::Service(ServiceConn::new(Box::new(TimeService(super::services::rfc868_time()))))
} else if to_gw && dport == PORTMAP_PORT && self.config.nfs.is_some() {
Expand Down Expand Up @@ -188,6 +200,10 @@ impl NatEngine {
};
dlog_dev!(LogModule::Net, "NAT TCP side connection {}:{} → guest {}:{}",
main.remote_ip, sport, main.guest_ip, side.guest_port);
if super::rsh::trace_enabled() {
eprintln!("iris: rsh: connecting back to guest {}:{} (stderr) from {}:{}",
main.guest_ip, side.guest_port, main.remote_ip, sport);
}
let ends = Endpoints { guest_port: side.guest_port, remote_port: sport, ..main };
let conn = TcpConn::open(ends, Backend::Service(ServiceConn::new(side.service)));
let syn = conn.syn(self.config.gateway_mac);
Expand Down
Loading
Loading