1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 2009-2019. All Rights Reserved. 5%% 6%% Licensed under the Apache License, Version 2.0 (the "License"); 7%% you may not use this file except in compliance with the License. 8%% You may obtain a copy of the License at 9%% 10%% http://www.apache.org/licenses/LICENSE-2.0 11%% 12%% Unless required by applicable law or agreed to in writing, software 13%% distributed under the License is distributed on an "AS IS" BASIS, 14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15%% See the License for the specific language governing permissions and 16%% limitations under the License. 17%% 18%% %CopyrightEnd% 19%% 20 21-module(ssh_tcpip_forward_srv). 22 23-behaviour(ssh_server_channel). 24 25-record(state, { 26 id, cm, 27 fwd_socket 28 }). 29 30-export([init/1, handle_msg/2, handle_ssh_msg/2, terminate/2]). 31 32init([FwdSocket]) -> 33 {ok, #state{fwd_socket=FwdSocket}}. 34 35 36handle_msg({ssh_channel_up, ChannelId, ConnectionManager}, State) -> 37 {ok, State#state{id = ChannelId, 38 cm = ConnectionManager}}; 39 40handle_msg({tcp,Sock,Data}, #state{fwd_socket = Sock, 41 cm = CM, 42 id = ChId} = State) -> 43 ssh_connection:send(CM, ChId, Data), 44 inet:setopts(Sock, [{active,once}]), 45 {ok, State}; 46 47handle_msg({tcp_closed,Sock}, #state{fwd_socket = Sock, 48 cm = CM, 49 id = ChId} = State) -> 50 ssh_connection:send_eof(CM, ChId), 51 {stop, ChId, State#state{fwd_socket=undefined}}. 52 53 54 55handle_ssh_msg({ssh_cm, _CM, {data, _ChannelId, _Type, Data}}, #state{fwd_socket=Sock} = State) -> 56 gen_tcp:send(Sock, Data), 57 {ok, State}; 58 59handle_ssh_msg({ssh_cm, _CM, {eof, ChId}}, State) -> 60 {stop, ChId, State}; 61 62handle_ssh_msg({ssh_cm, _CM, {signal, _, _}}, State) -> 63 %% Ignore signals according to RFC 4254 section 6.9. 64 {ok, State}; 65 66handle_ssh_msg({ssh_cm, _CM, {exit_signal, ChId, _, _Error, _}}, State) -> 67 {stop, ChId, State}; 68 69handle_ssh_msg({ssh_cm, _, {exit_status, ChId, _Status}}, State) -> 70 {stop, ChId, State}. 71 72 73terminate(_Reason, #state{fwd_socket=Sock}) -> 74 gen_tcp:close(Sock), 75 ok. 76