netcat script to send a message to a marquee device - bash

I wrote a script that uses netcat to update the marquee in my office without knowing the ip address of the device. I used fping to calculate candidateIPs.
The script works. But, I still don't know the IP address of the device. Can someone help me understand how to update the script to narrow down the IP address that updated the text on the device?
#!/bin/bash
while read p; do
echo "try $p"
echo "\x00\x00\x00\x00\x00\x01\x5A\x30\x30\x02\x41\x41\x1B\x22\x61 Test message!\x04" | nc $p 3001 &
done < candidateIPs
wait

You can log your outputs an add verbosity e.g.
#!/bin/bash
while read p; do
echo "try $p"
echo "\x00\x00\x00\x00\x00\x01\x5A\x30\x30\x02\x41\x41\x1B\x22\x61 Test message!\x04" | nc -v "$p" 3001 2>&1 | tee "$p.log" &
done < candidateIPs
wait
You can examine either the ip-specific log files after that.

Related

Thermal printer ESC/POS status command result to BASH variable

I am trying to create a script that will check if the serial connection is functional on the thin client running strip down version of ubuntu.
I am able to print to the printer, however, I need to find a way to read settings from the printer connected with RS232 (ttyS0).
here is the BASH script I have so far:
#!/bin/bash
# Gather information
ip4=$(/sbin/ip -o -4 addr list eth0 | awk '{print $4}' | cut -d/ -f1)
locdate=$(date)
drstatus="To be implemented yet"
#[Set serial port speed]
stty -F /dev/ttyS0 38400;
#listen to the port report
# cat /dev/ttyS0&
#[Send print test to the printer]
#initialize printer
echo -e '\x1b\x40'>/dev/ttyS0
# send printer data
echo -e '\x1b\x45 TM88 Hardware Test:\x1b\x46\xa'>/dev/ttyS0
echo -e $locdate'' >/dev/ttyS0
echo -e 'Hostname: '$HOSTNAME'' >/dev/ttyS0
echo -e 'Endpoint IP address: '$ip4''>/dev/ttyS0
echo -e '\x1d\x6b\x04000\x00'>/dev/ttyS0
echo -e 'Printer connected to COM1 / ttyS0'>/dev/ttyS0
echo -e 'Comm. speed 38400 bps'>/dev/ttyS0
echo -e 'Cash drawer status:'$drstatus'\xa'>/dev/ttyS0
echo -e '\xa\xa\xa\xa\xa\xa\x1bm'>/dev/ttyS0
According to the reference site the code should look like this for the request should look like this:
echo -e '\x1d\x49\x01'>/dev/ttyS0
and the response should be visible with
cat < /dev/ttyS0
However cat does not display anything.
How can I get the response from the ESC/POS command into a variable?

Test if netcat listener got a connection and run a command locally

I need a way to fire a netcat listener from a shell script and if a connection received I need to run a command on the same local listener machine and without interrupting the netcat process / connection
it's like the -e option but I need to run a command locally while keeping the netcat connection running
I don't really know if it can be done I mean after the shell process forked the netcat child can it interact with nc's output for example and run other command before netcat exit?
Edit: I figured it's even easier to do it on the client C code side by checking the return value of an initial send() message to determine if the client connected successfully if we got the sent message length
sret = send(sock, message, strlen(message), 0);
if (sret == strlen(message)) // We're Connected
do something
Thanks
This will check if the initial nc process has started listening, and it will echo every line of input it receives and will then send back a Received response:
rm -f input.txt
touch input.txt
tail -f input.txt | nc -l 5555 > output.txt &
if ! ps -p $! >/dev/null; then
echo "Netcat didn't start. Exiting..."
exit 1
fi
tail -f output.txt | while read -r LINE; do
echo "Received input: $LINE"
echo "Received" >> input.txt
done
See if you can adapt this to meet your needs.

Bash script that accepts TCP connection, when a client connection occurs, send the time of day as a response to the client

I'm not going to lie this is an homework assignment, but I've been googling constantly to try to get some idea on how the heck to approach this particular question.
"Create a script named lab6s6 that accepts TCP connections. When a client connection
occurs, send the time of day as a response to client. You may choose any port number as
the listening port, and don’t forget to close your connections."
I'm running the latest fedora OS on my virtualbox
So far after doing some research I've come across this particular piece of code
$ exec {file-descriptor}<>/dev/{protocol}/{host}/{port}
What i've come up with after doing some research would be
exec 3<>/dev/TCP/127.0.0.1/8000
So from my general understanding the file descriptor tends to always be set to 3 (is this because of the stdin, stdout, stderr, what is the purpose of this?) also the "<>" which represents reading and writing, and the directory is a way to actually use those protocols. and lastly, for my ip I read somewhere that I shouldnt be using the loopback that this wouldn't work but I'll be honest I was a bit clueless while reading the article, and for the port I never really understood that, is it like the higher the number the more available your signal is?
and another side question, do I need to install any other type of software to even accomplish something like this? If anyone could clarify if I'm basically opening up like a phone line on my computer to be able to talk to other computers at are on my LAN, is that even possible?
I'm not asking for direct answers, but if someone could nudge me in the right direction I would appreciate it greatly!
Thanks again!
I have prepared for you two scripts: client and server
after giving them the execution right: chmod u+x script_name you can run them in any order (client -> server or server -> client)
bash_server.sh
#!/usr/bin/env bash
#define port on which the server will listen
#and the output file that will be used to store the client port to send an answer
readonly PORT_LISTEN=22222;
readonly SERVER_FILE=server_file_tmp.out;
echo "Removing the server temporary file: ${SERVER_FILE}";
rm -f "${SERVER_FILE}";
#will open/bind/listen on PORT_LISTEN and whenever some information is received
#it will write it in the SERVER FILE
echo "Starting the server on port: ${PORT_LISTEN} with configuration file: ${SERVER_FILE}";
nc -k -l "${PORT_LISTEN}" | tee "${SERVER_FILE}" &
echo "Waiting for connection..."
#active listening to entry connection
while true;
do
#get always information about the external connection trying to connect to our open port
tmpNetworkString=$(lsof -i:"${PORT_LISTEN}" | grep "localhost:${PORT_LISTEN} (ESTABLISHED)" | awk '{print $9}');
echo -n "${tmpNetworkString}";
if [ -s "${SERVER_FILE}" ] && [ ! -z "${tmpNetworkString}" ]; then
answerPORT=$(cat "${SERVER_FILE}");
echo "Connection received on port ${PORT_LISTEN}...";
incomingIP=$(echo $tmpNetworkString | cut -d':' -f1);
incomingPort=$(echo $tmpNetworkString | cut -d'-' -f1 | cut -d':' -f2);
echo ">>Incoming traffic IP: ${incomingIP}";
echo ">>Incoming traffic Port: ${incomingPort}";
echo "Answering on IP: ${incomingIP}, port: ${answerPORT}...";
#wait client port to be ready
nc -z "${incomingIP}" "${answerPORT}";
isOpen=$?;
while [ ! "${isOpen}" -eq 0 ];
do
nc -z "${incomingIP}" "${answerPORT}";
isOpen=$?;
done
echo $(date) | nc -q 2 "${incomingIP}" "${answerPORT}";
echo "Closing the server, port: ${PORT_LISTEN}";
fuser -k -n tcp "${PORT_LISTEN}";
echo "Removing the server temporary file: ${SERVER_FILE}";
rm -f "${SERVER_FILE}";
exit 0;
fi
done
bash_client.sh
#!/usr/bin/env bash
#define port on which the client will listen
#and the output file that will be used to store the answer from the server
readonly PORT_LISTEN=33333;
readonly CLIENT_FILE=client_file_tmp.out;
readonly SERVER_PORT=22222;
readonly SERVER_IP=localhost
echo "Removing the client temporary file: ${CLIENT_FILE}";
rm -f "${CLIENT_FILE}";
#will open/bind/listen on PORT_LISTEN and whenever some information is received
#it will write it in the CLIENT FILE
echo "Starting the server on port: ${PORT_LISTEN} with configuration file: ${CLIENT_FILE}";
nc -k -l "${PORT_LISTEN}" > "${CLIENT_FILE}" &
echo "Connecting to the server: ${SERVER_IP}, on port: ${SERVER_PORT} and waiting for answer";
#sending port information for answer:
#wait client port to be ready
nc -z "${SERVER_IP}" "${SERVER_PORT}";
isOpen=$?;
while [ ! "${isOpen}" -eq 0 ];
do
nc -z "${SERVER_IP}" "${SERVER_PORT}";
isOpen=$?;
done
echo "${PORT_LISTEN}" | nc -q 2 "${SERVER_IP}" "${SERVER_PORT}";
while true;
do
if [ -s "${CLIENT_FILE}" ]; then
echo "Answer received from server...";
echo "##############################";
echo "##############################";
cat "${CLIENT_FILE}";
echo "##############################";
echo "##############################";
#sleep 10;
echo "Closing the open port of the client, port: ${PORT_LISTEN}";
fuser -k -n tcp "${PORT_LISTEN}";
echo "Removing the answer file: ${CLIENT_FILE}";
rm -f "${CLIENT_FILE}";
exit 0;
fi
done

Network monitoring ping

i am reading from a txt file several hundred ip addresses, want to ping the list to the end of the file. would like this to run in a loop instead, read to the end of the file, then start at the first address again.
trap 'echo ****Interrupted****; exit'INT
echo -n "Enter the file name with the ip addresses"
read file
echo -n "Enter the file name for the log file"
read log
while read line
do
echo "pinging: "$line
echo -e "">>$log
echo -n "NEXT PING: ">>$log
echo -n "$line" : " >>$log
$ping -c 3 -W 2 $line >>$log
done <"$file"
Use fping.
http://fping.org/
From the fping man page:
DESCRIPTION
fping is a program like ping(8) which uses the Internet Control Message
Protocol (ICMP) echo request to determine if a target host is responding.
fping differs from ping in that you can specify any number of targets on the
command line, or specify a file containing the lists of targets to ping.
Instead of sending to one target until it times out or replies, fping will
send out a ping packet and move on to the next target in a round-robin
fashion.

parsing external command output and saving as variables

I'm trying to make a script that can will run nmap against an ip and tell me if the host is up or not as well as the OS. I want host up and the OS details to be the only things output.
ip=$1
nmap -O $ip |while read -r line; do
if [[ `echo $line|grep "1 host up"`] !=0]
then
echo "1 Host is up"
else
echo "No Host"
fi
done
I'm pretty bad at this so any help you can give me will be greatly appreciated :)
EDIT: Sample NMap output as requested
Starting Nmap 5.21 ( http://nmap.org ) at 2013-07-16 13:18 EDT
Nmap scan report for hostname.domain.com (192.168.1.5)
Host is up (0.00028s latency).
Not shown: 997 closed ports
PORT STATE SERVICE
135/tcp open msrpc
139/tcp open netbios-ssn
445/tcp open microsoft-ds
MAC Address: 78:2B:CB:7E:C7:74 (Unknown)
Device type: general purpose
Running: Microsoft Windows XP
OS details: Microsoft Windows XP SP2 or SP3, or Windows Server 2003
Network Distance: 1 hop
OS detection performed. Please report any incorrect results at http://nmap.org/submit/
Nmap done: 1 IP address (1 host up) scanned in 2.44 seconds
Here's something you could try:
#! /bin/bash
host=whatever
while read -r line ; do
if [[ $line =~ ([0-9])+\ hosts?\ up ]] ; then
host_up="${BASH_REMATCH[1]}"
elif [[ $line =~ OS\ details:\ (.*) ]] ; then
host_os="${BASH_REMATCH[1]}"
fi
done < <(nmap -O $host)
echo "Up: $host_up OS: $host_os"
This uses process substitution to drive the while loop (necessary here - if you do nmap | while, the while ends up in a subshell and can't modify the parent's variables), and a pair of regular expressions to extract the information you need.
Easy to extended later if you need more of the output.
You are over-complicating things a bit. Your command could be re-written like this:
if grep "1 host up" <(nmap -O "$i")
then
echo "UP"
else
echo "DOWN"
fi
Some explanations:
We use process substitution (with the <( ) to redirect the output of the command as a parameter to the grep command.
The grep command returns zero if it finds a match, and non-zero otherwise. Thus, we can use it directly in the if statement
You can also avoid the if all together like this:
grep "1 host up" <(nmap -O "$i") && echo "UP" || echo "DOWN"

Resources