Tag Archive : networking

/ networking

Socat Cheatsheet

December 26, 2016 | Article | 1 Comment

Socat, a powerful tools you should have in you arsenal. Some say socat is another swiss army knife beside netcat. It is a command line based utility that establishes two bidirectional byte streams and transfer data between them. Socat has been long used for creating a simple forwarder. But, did you know that we can do more than that?

Basic Knowledge

Basically socat is a tool to manipulate sockets. To give you a hint, socat comes from socket and cat.

The idea of sockets is too restrictive. Speaking socat we should speaks in the level of “data channel”. It can be combinations of:

  • a file
  • a pipe
  • a device (ex: a serial line)
  • a socket (IPv4, IPv6, raw, TCP, UDP, SSL)
  • a FD (STDIN, STDOUT)
  • a program or script

Now socat has a different syntax on what you are used to with netcat or other standard unix tools. Here is the simple syntax:

socat [options] <channel> <channel>

both channel should be provided. The channel should be like this:

<protocol>:<ip>:<port>

All you need to remember is: socat is bidirectional. It is like a pipe so there is no strict definition of which one should be source or destination. Both address can have src/dst role.

Tips and Trick

Now, come to our actual topic. For the sake of simplicity, we will pretend there are two distinct hosts namely HOST-L and HOST-R.These hosts can be anywhere with any IP. In most case HOST-L is our local machine while HOST-R is remote machine. On most case we will use port 13510 and 18210 as example.

Let’s see our catalog:

  • Basic network connection
    • Connect to remote machine
    • Listening to a socket
    • UDP traffic
    • Execute program when connection come
    • SSLify connection
    • Make a tunnel
    • Make a tunnel via proxy
  • File transfer
    • Display content of file to standard output
    • Create and write to a file
    • Transfer file
  • UDP tunneling through SSH connection
  • Local serial line
  • Get HTTP content without browser
socat TCP-LISTEN:13510 -
socat - TCP-LISTEN:13510
socat - UDP-LISTEN:13510
socat - UDP:HOST-R:13510

For example, shell.

socat TCP-LISTEN:13510 EXEC:"/bin/bash"

for multiple connection

socat -L TCP-LISTEN:13510 EXEC:/bin/bash

we also have SYSTEM address, which uses the system() call rather than a call to exec(). We can do something like this (something netcat can’t do).

socat TCP-LISTEN:2323,reuseaddr SYSTEM:'echo $HOME; ls -la'

In short, strip incoming SSL to plain traffic.

socat OPENSSL-LISTEN:443,reuseaddr,pf=ip4,fork,cert=cert.pem,cafile=client.crt TCP4-CONNECT:HOST-L:80

– Make a tunnel

socat TCP4-LISTEN:13510,reuseaddr,fork TCP:xathrya.id:22

– Make a tunnel via proxy

socat TCP4-LISTEN:13510,reuseaddr,fork PROXY:certain.proxy.id:xathrya.id22,proxyport=3128,proxyauth=user:pass

address can be a file. Thus directive FILE: is used to read content of file.txt and then pipe it.

socat -u STDIN OPEN:file.txt,creat,trunc

– Transfer file

and as you might expect, pipe a file to remote host.

HOST-L# socat FILE:file.txt TCP:HOST-R:13510
HOST-R# socat TCP-LISTEN:13510 OPEN:file.txt,creat,trunc

– UDP tunneling through SSH connection

see this article.

LOCAL# ssh -L 13510:LOCAL:13510 SERVER
SERVER# socat tcp4-listen:13510,reuseaddr,fork UDP:NAMESERVER:53 
LOCAL# socat -T15 udp4-recvfrom:53,reuseaddr,fork tcp:LOCAL:13510

– Local serial line

Use as a local serial line. For example, to configure a network device, modem, or embedded device without a terminal emulator.

socat \
READLINE,history:/tmp/serial.cmds \
OPEN:/dev/ttyS0,ispeed=9600,ospeed=9600,crnl,raw,sane,echo=false

READLINE data channel use GNU readline to allow editing and reusing input lines like a classic shell.

– Grab some HTTP content without a browser

# cat <<EOF | socat - TCP4:xathrya.id:80
GET / HTTP/1.1
Host: xathrya.id

EOF

GET to EOF is something we need to type in.

 

UDP Tunneling Through SSH Connection

December 26, 2016 | Article | 1 Comment

Imagine you are in a situation where you are using ISP which do censorship based on DNS. We might use free DNS service but quite often ISP will hijack the traffic and redirect them to their DNS. Another approach is using tool which transfer DNS traffic on top of encrypted channel, for example dnscrypt. However in this article we won’t use this approach. I will give insight about another approach, doing it by ourselves.

We will have three entities involved:

  • SERVER
  • LOCAL
  • NAMESERVER

SERVER is an endpoint of SSH tunnel. NAMESERVER is DNS server, which we will contact. It can be a internal DNS server on SERVER’s network, or it can be SERVER itself. LOCAL is our local machine.

The idea is simple:

  • creating a SSH tunnel between LOCAL and SERVER
  • setup TCP to UDP forward on SERVER
  • setup UDP to TCP forward on LOCAL

Create SSH Tunnel

On LOCAL, connect to SERVER by SSH. We need additional -L option so that SSH will do TCP port forwarding.

LOCAL# ssh -L 13510:LOCAL:13511 SERVER

This will allow TCP connection to port 13510 of local machine to be forwarded to the port number 13511 on SERVER. Of course, replace LOCAL and SERVER as we need.

Setup TCP to UDP Forward on SERVER

On the server we open listener on port 13511 which will forward data to UDP port 53 of specified IP, or NAMESERVER to be precise. There are two approach, whether you want to use netcat or socat.

Netcat

We need to create a fifo. The fifo is necessary to have two-way communication between two channels. A pipe won’t do because it only transfer data from STDOUT of left process to STDIN of right process.

SERVER# mkfifo /tmp/tunsshfifo
SERVER# nc -lp 13511 < /tmp/tunsshfifo | nc -u NAMESERVER 53 > /tmp/tunsshfifo

This will have bidirectional communication, from SERVER:13511 to NAMESERVER:53 and vice-versa

Socat

Socat is bidirectional by nature, so we don’t need to create a fifo.

SERVER# socat TCP4-LISTEN:13511,reuseaddr,fork UDP:NAMESERVER:53

see socat cheatsheet for more info on socat capability.

Setup UDP to TCP Forward on LOCAL

On LOCAL we need a privilege access to bind on port 53. Other than that, it’s only bit opposite of what we have done on SERVER.

Netcat

LOCAL# mkfifo /tmp/tunsshfifo
LOCAL# sudo nc -lup 53 < /tmp/tunsshfifo | nc localhost 13510 > /tmp/tunsshfifo

This will have bidirectional communication, from LOCAL:53 to LOCAL:13510 and vice-versa

Socat

Again, socat is bidirectional by nature.

LOCAL# socat -T15 UDP4-RECVFROM:53,reuseaddr,fork TCP:localhost:13510

see socat cheatsheet for more info on socat capability.

Testing

As mentioned, our traffic now flow like this LOCAL:53 – LOCAL:13510 – SSH TUNNEL – SERVER:13511 – NAMESERVER:53 for request. To test DNS service on local machine, use host

host xathrya.id 127.0.0.1

Cheers!

AT Commands is shortening of ATtention Commands. It is set of command understood by mobile phone and modem. Knowing AT command allow you to control your mobile phone by terminal, or even a modem you use.

In this article we will try to explore AT command using cu command. CU (Call Up) is a little tool for communicating with another system. It is a basic networking application that shipped with most linux (or maybe all) linux distribution. From linux man page we got information that cu is used to call up or connect directly or indirectly to another system and act as a dial in terminal. It can also do simple file transfers with no error checking.

To establish a connection using a modem we can invoke:

cu [ -d ] [ -h ] [ -m ] [ -T seconds ] [ -n ] [ -s speed] [ -t ] [ -e | -o ] Telephone / number

To specify the name of a device for a connection:

cu [ - d] [ -h ] [ -m ] [ -T seconds ] [ -s speed ] [ -e | -o ] -l line

To specify a system name for a connection:

cu [ - d] [ -h ] [ -m ] [ -T seconds ] [ -e | -o ] SystemName

For this article, I will using a modem (old modem which I forget the specification but it has 3.5G capability if I remember it) to perform a connection. Our goal is connecting to modem with cu application while we will discuss other use of AT commands like sending SMS in another article.

What we need:

  • mobile device, in this case modem as I said before.
  • USB cable, this for connecting our device and our computer.
  • Computer, of course! In this case I use GNU/Linux (well obviously)

Before proceeding, please switch to super user!

Device Recognition

First, we plug both of cable-end to the device and computer.

Make sure the device is recognized by computer. To see it, invoke this command:

dmesg | tail -10

That command will give last 10 message from kernel. Make sure you find entries indicated that your computer recognize the device. In my case I have this messages:

[12209.457401] usbserial: USB Serial Driver core
[12209.479009] USB Serial support registered for GSM modem (1-port)
[12209.479129] usbcore: registered new interface driver option
[12209.479131] option: v0.7.2:USB Driver for GSM modems
[12209.481986] option 3-1:1.0: GSM modem (1-port) converter detected
[12209.484529] usb 3-1: GSM modem (1-port) converter now attached to ttyUSB0
[12209.484589] option 3-1:1.1: GSM modem (1-port) converter detected
[12209.486172] usb 3-1: GSM modem (1-port) converter now attached to ttyUSB1
[12209.486229] option 3-1:1.2: GSM modem (1-port) converter detected
[12209.486653] usb 3-1: GSM modem (1-port) converter now attached to ttyUSB2

My device is registered as GSM modem and has attached to ttyUSB0, ttyUSB1, and ttyUSB2. This result might be different in your system but find out these information, especially what terminal is your device attached to. There is no exception to CDMA phone / mobile. Unless it is not detected by system, you can proceed to next stage.

Our device is registered now, then let’s see the /dev directory to make sure.

ls /dev | grep tty

Because my device is attached as ttyUSB0, ttyUSB1, and ttyUSB2, I make sure that these file is present at /dev directory. Once we have confirmed it, we can proceed to next step.

Contacting and Communicating

In this step, we will try to contacting the device with information we got from previous command. Here I use terminal ttyUSB0. Start up terminal and fire cu command. But first, let’s specify our need.

In this article I need half duplex connection so I will give -h switch. The baud rate I use is 38400 (this is standard rate). And the line I use is /dev/ttyUSB0. Now let’s type on terminal:

cu -h -s 38400 -l /dev/ttyUSB0

If you are success, you will see a “Connected.” message on your terminal. Congratulation, in this stage we have established the connection to remote device.

Now, test if AT command is recognized by device. Give this command to your terminal:

AT

You should has OK response from device indicated that your device is supporting AT command.

Sometimes your device echoing every character you type. For example you type AT but in your terminal you see AATT. It would be difficult to see what command you have typed actually. For that case, we will disable the echo by giving command:

ATE0

And gotcha, you have your terminal give clear message.

To disconnecting your connection, you can type ~. (a tilde followed by a point), and press enter (carriage return). You should see the message “Disconnected” and be returned to your prompt (terminal).

Happy hacking! 😀

In previous article, we have discussed some basic for network programming such as IP, port number, and byte order of computer. In this article we will look some API and its basic usage.

Converting Byte Order

We have know that each computer might have different endian but the network infrastructure ensure format in network order. To convert our host order to network order (or vice versa) we can use some function:

htons()
htonl()
ntohs()
ntohl()

Some Structs

We will discussed some struct used here. Try to remember them, okay?

struct addrinfo – This structure is more recent invention and is used to prepare the socket address structures for subsequent use. It’s also used in host name lookups, and service name lookups.

struct addrinfo {
   int              ai_flags;     // AI_PASSIVE, AI_CANONNAME, etc
   int              ai_family;    // AF_INET, AF_INET6, AF_UNSPEC
   int              ai_socktype;  // SOCK_STREAM, SOCK_DGRAM
   int              ai_protocol   // use 0 for "any"
   size_t           ai_addrlen;   // size of ai_addr in bytes
   struct sockaddr *ai_addr;      // can be struct sockaddr_in or sockaddr_in6
   char            *ai_canonname; // full canonical hostname
   struct addrinfo *ai_next;	  // linked list, next node
};

Load this struct up a bit and then call getaddrinfo(). It’ll return a pointer to a new linked list of these structures filled out with all the information needed. We can force it to use IPv4 or IPv6 or leave it as AF_UNSPEC to use whatever.

struct sockaddr – This structure hold information about address.

struct sockaddr {
   unsigned short  sa_family;    // address family, AF_XXX
   char            sa_data[14];  // 14 bytes of protocol address;
};

sa_family can be variety, but it’ll be AF_INET or AF_INET6 (you must have known the difference when I write that ;p . sa_data containes destination address and port number for socket.

struct sockaddr_in – structure for specific use, IPv4. Make reference elements of the socket address. Please remember that sin_zero must be set to all zero with memset() function.

struct sockaddr_in {
   short int          sin_family;    // Address family, AF_INET
   unsigned shot int  sin_port;      // Port number
   struct in_addr     sin_addr;      // Internet address
   unsigned char      sin_zero[8];   // filled with zero to keep same size as sockaddr
};

struct in_addr – structure for hold internet address (IPv4)

struct in_addr {
   uint32_t s_addr;    // 32 bit int
};

struct sockaddr_in6 – structure for specific use, IPv6. Similiar to IPv4 version

struct sockaddr_in6 {
   u_int16_t        sin6_family;    // Address family, AF_INET6
   u_int16_t        sin6_port;	    // Port number, network byte
   u_int16_t        sin6_flowinfo;  // IPv6 flow information
   struct in6_addr  sin6_addr;      // IPv6 address
   u_int32_t        sin6_scope_id;  // Scope ID
};

struct in6_addr – structure for hold internet address (IPv6)

struct in6_addr {
   unsigned char s6_addr[16];   // IPv6 address
};

struct sockaddr_storage – structure large enough to hold both IPv4 and IPv6.

struct sockaddr_storage {
   sa_family_t  ss_family;	// address family

   // all this is padding, implementation specific
   char         __ss_pad1[_SS_PAD1SIZE];
   int64_t      __ss_align;
   char         __ss_pad2[_SS_PAD2SIZE];
};

The important one is the ss_family field, we can check it for AF_INET or AF_INET6. Then we can cast it to struct sockaddr_in or struct sockaddr_in6 if we want.

IP Address Representation

There are a bunch of function to manipulate IP address. If we have IP address “10.12.110.57” and “2001:db8:63b3:1::3490” we will use inet_pton() function to converts them to their respective address representation. To reverse it (convert to internet address representation to string), use inet_ntop() function.

#include <arpa/inet.h>

struct sockaddr_in sa;	// IPv4
struct sockaddr_in6 sa6	// IPv6
char ip4[INET_ADDRSTRLEN];
char ip6[INET6_ADDRSTRLEN];

inet_pton(AF_INET,"10.12.110.57",&(sa.sin_addr));	// IPv4
inet_pton(AF_INET6,"2001:db8:63b3:1::3490", &(sa6.sin6_addr));	// IPv6

inet_ntop(AF_INET, &(sa.sin_addr), ip4, INET_ADDRSTRLEN);
printf("IPv4 Address is: %s\n", ip4);
inet_ntop(AF_INET6, &(sa6.sin6_addr), ip6, INET6_ADDRSTRLEN);
printf("IPv6 Address is: %s\n", ip6);

Socket Descriptor

As we discussed in some articles ago, a socket in Unix is a file associated with a integer. To create a socket we need create a variable for socket which can be as simple as integer.

Socket Creation

To create a socket we will call a function socket(). Function socket() has 3 arguments: a family type (AF_INET / AF_INET6), packet type (SOCK_STREAM / SOCK_DGRAM), protocol type.

#include <sys/types.h>
#include <sys/socket.h>

int socket_fd = socket(AF_INET, SOCK_STREAM, 0);

Socket Bind to

Socket has been created on creation step and stored in socket_fd. But it would be meaningless if we cannot use it for communication because it has not bind into any port. Bind a port mean attach our socket to port and create a “tunnel” for our application to the port, exclusively. Once the socket bounded to a port, other program cannot use same port until our socket is unattached from the port. The information needed would be stored in struct sockaddr_* respective to type of address it want to use (IPv4 or IPv6).

#include <sys/types.h>
#include <sys/socket.h>

struct sockaddr_in sin;

memset(sin.sin_zero,0,sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(13510);
inet_pton(AF_INET, "127.0.0.1", &(sa.sin_addr));

bind( socket_fd, (struct sockaddr*) &sin, sizeof(sin) );

Socket Listen to

The bounded socket can listen to some incoming connections. A function listen() will set the maximum number of connection it can handle.

#include <sys/types.h>
#include <sys/socket.h>

listen( socket_fd, 20 );

Socket Accept request

Once a listening socket got an incoming packet, it is up to programmer to accept it or drop it. To accept incoming packet we use accept function and create a new file descriptor. The data can be fetched from new file descriptor (remember that everything in Unix is file?). Peer is remote computer who initiate communication.

#include <sys/types.h>
#include <sys/socket.h>

struct sockaddr* peer_addr;

int accfd = accept( socket_fd, (struct sockaddr*) peer_addr, sizeof(peer_addr) );

Socket Receive message

After accepting connection, we have a new file descriptor that store message. The next thing to do is fetching the data.

#include <sys/types.h>
#include <sys/socket.h>

char message[1024];
int nbytes;

nbytes = recv(accfd, message, 1024, 0);

Socket Connect to

A socket can also used for sending message or simply connecting to another host. The open socket, socket created from socket(), is unnecessary to bounded to any port. It only need information about address it want to connect.

#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>

struct sockaddr_in sin;

memset( &sin.sin_zero, 0, sizeof(sin) );
sin.sin_family = AF_INET;
sin.sin_port = htons(13510);
inet_pton(AF_INET, "127.0.0.1", &(sin.sin_addr));

int result = connect( socket_fd, (struct sockaddr*) &addr, sizeof(addr) );

Socket Send message

When connection established, we can send message over our socket.

#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>

char message[1024];
strcpy(message,"To server, hello");
send(sock_fd, message,1024,0)

Last article, we have discussed about what is socket. This article will give a quick presentation about network before start learning socket programming.

Internet Protocol (IP) Address and Subnetwork

Internet Protocol (IP) Address or IP Address is simply an address. Like address in real world, IP address determine how your device can be reach from other device. IP address set a complex message transferring system in internet which is called routing, and responsible to route data packets from one end to another end.

There are 2 type of IP address used in public: IPv4 (IP version 4) and IPv6 (IP version 6).

IPv4 has 32 bit length with representation series of decimal numbers separated by dot. For example 192.168.1.1 is IPv4 address. With IPv4 there would be 2^32 addresses or 4,294,967,296 (approximately 4 billion address). These addresses are currently running out so an alternative address named IPv6 is developed.

IPv6 has 128 bit length with representation series of hexadecimal numbers separated by colon. For example 2001:0db8:c9d2:0012:0000:0000:0000:0051. With IPv6 there would be 2^128 addresses for entire planet. This is relatively huge, far more huge than older IPv4 way.

There is an organization Internet Assigned Number Authority (IANA, http://www.iana.org/) that manages global IP allocation and delegates it to five Regional Internet Registries (RIRs) to allocate IP block to Local Internet Registries (LIRs) and other organization. So RIR are IANA’s delegation to manages all IP address around the world. Those 5 regions are:

  1. African Network Information Center (AfriNIC) for Afrika.
  2. American Registry for Internet Numbers (ARIN) for United States, Canada, and some region of Caribbean.
  3. Asia-Pacific Network Information Center (APNIC) for Asia, Australia, New Zealand, and surrounding nation.
  4.  Latin America and Caribbean Network Information Center (LACNIC) for Latin America and some region of Caribbean.
  5. Réseaux IP Européens Network Coordination Centre (RIPE) for Europe, Middle East, and Middle Asia.

While LIRs are organization in every nation. They allocate IP address for customer in each nation but still under supervisor of their own RIR.

Subnetwork or subnet is a logically visible subdivision of an IP network. All computers that belong to a subnet are addressed with a common, identical, most-significant bit-group in their IP address. This results in the logical diviion of an IP address into two fiels: a network or routing prefix and the rest field or host identifier. The rest field is identifier for a specific host or network interface.

The routing prefix is expressed in CIDR notation and written as the first address of a network followed by a slash character (/), and ending with the bit-length of prefix. For example 202.168.1.0/24 is the prefix of the IPv4. The example for IPv6 is 2001:db8::/32 is a large network with 2^96 address, having a 32-bit routing prefix. In IPv4 the routing prefix is also specified in the form of the subnet mask, which is expressed in quad-dotted decimal representation like an address, for example: 255.255.255.0 is network mask for 24-bit routing prefix.

Port Numbers

In computer network, a port is a logical gateway to exchange information to the world. Like a port in real world, incoming and outgoing packet are visiting port each time. Therefore it is a vital part for communication.

Port Number is a number that associated with kernel. A port number is 16-bit number that is like local address for the connection.

We can associate IP address like address of a building (apartment), while port number is room number for each attendant (a program). A message passed from one program to another program can be in same building (same machine) or different building (different machine) via postal agent (internet).

Port number is also differentiate services on a server, such as mail server and web server.

Different services on internet have different well-known post numbers. There is a big list maintained by IANA or if you are on Unix machine you can see the list on /etc/services file. HTTP (web) is port 80, telnet is 23, SMTP is 25, and so on.

Byte Order

There are two way computer might store number, in Big-Endian or Little-Endian. A Big-Endian system store number with big end first. While Little-Endian is the reverse. Intel and Intel-compatible processor store data in Little-Endian. Therefore, a number in hexadecimal 0xb34f would be stored in memory as sequential 4f followed by b3. In Big-Endian, 0xb34f would be stored in memory in two sequential bytes b3 followed by 4f.

The computer dependent number presentation (can be Little-Endian or Big-Endian depend on processor) is called Host Byte Order. The data across network is standardized using Big-Endian for clarity. The byte order for network is  called Network Byte Order.

Social media & sharing icons powered by UltimatelySocial