Reputation: 1258
Hi I am trying to create a function which remotely executes my packet sniffing script on my raspberry pi using paramiko and ssh.
def startPacketReceiver():
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(AutoAddPolicy())
ssh.connect(RECV_IP_ADDRESS, username="pi", password="raspberry")
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command("sudo gcc Code/test.c && sudo ./a.out")
print("Done")
The test.c file is the packet sniffing script. It will only terminate with a CTRL-C (or equivalent method). It does not terminate naturally/eventually.
I want to be able to start the receiver and then quit the receiver e.g:
startPacketReceiver()
...
stopPacketReceiver()
Currently when I run the python script I never get the "Done" print message, meaning that the program is hung on the exec_command and will not continue until it is terminated.
Additional Info
The test.c file loops infinitely, essentially:
while(1)
{
saddr_size = sizeof saddr;
//Receive a packet
data_size = recvfrom(sock_raw , buffer , 65536 , 0 , &saddr , (socklen_t*)&saddr_size);
//fprintf(stderr,"%d",data_size);
if(data_size <0 )
{
fprintf(stderr,"Failed to get packet\n");
printf("Recvfrom error , failed to get packets\n");
return 1;
}
//Now process the packet
ProcessPacket(buffer , data_size);
}
and so to stop it you must CTRL-C it.
Upvotes: 0
Views: 523
Reputation: 46
I suggest taking a look at daemon(3)
Then you can capture SIGNALS or reopen standard input. Depends on what you would like to do with your python script. (If you don't want to use any python any python library other than sys and os)
EDIT:
I am pretty sure when the python script will terminate the ssh connection will obviously close and so any program running on that tty by the user who initiated the connection will be terminated. For that reason your c program needs to be daemonized and may need to have its uid and/or euid changed.
Despite that i tried to reproduce your code and I ran into a similar problem: the python script was running the command then print "Done" but as I tried to read stdout, the entire script was pause. I think it was waiting for the script return status. So i did the following changes:
try:
port = '22'
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect('<host_name>', port=22, username='<username>',
password='<password>')
chan = client.get_transport().open_session()
chan.get_pty()
chan.exec_command("cd <script_directory>;\
; gcc test.c; ./a.out")
while True:
print(chan.recv(1024))
finally:
client.close()
The while loop here is to get output of the c program. But if you close the python script the c program will follow. I did not dug to much into this library.
EDIT 2:
Look up nohup
if you don't want to use de daemon approach.
Upvotes: 1
Reputation: 814
You need to send your password to the sudo
command. Please enable tty
mode for executing your command by passing get_pty = True
argument to exec_command
function call. And then you need to pass your password through ssh_stdin
file interface.
def startPacketReceiver():
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(AutoAddPolicy())
ssh.connect(RECV_IP_ADDRESS, username="pi", password="raspberry")
ssh.stdin, ssh_stdout, ssh_stderr = ssh.exec_command("gcc Code/test.c && sudo ./a.out", get_pty=True)
print("raspberry", ssh_stdin) # Your password for sudo command
print("Done")
return ssh, ssh_stdin, ssh_stdout, ssh_stderr
And then you can write your stopPacketReceiver
to send Ctrl-C signal.
def stopPacketReceiver(ssh, ssh_stdin, ssh_stdout, ssh_stderr):
print('\x03', file=ssh_stdin) # Send Ctrl-C signal
print(ssh_stdout.read()) #print the stdout
print(ssh_stderr.read())
Upvotes: 1