Monday, 6 August 2012

Raspberry Pi - C Programming and TCP/IP

I've been meaning to get into a bit more C programming lately as my new job is embedded C programming. I've also got quite an interest in networking and associated protocols.
I thought that it would be a great idea to cut my teeth on TCP/IP using my Raspberry Pi and my Desktop computer.

Currently my network set up is as such:

INTERNET > ROUTER > Wireless
                  > SWITCH > UNMANAGED SWITCH
                                     > Raspberry Pi
                                     > My Desktop

Hopefully you can understand that. Basically I've got my desktop and Raspberry Pi connect via Ethernet and an unmanaged switch.

I've learnt C for about 2 years now, so I'd say I'm al right with it, just a little rusty as I haven't used it in about 6 months (been learning Java). All I needed to look up programming wise was either a book or tutorial using Cs TCP/IP libraries and some examples.

I had a read of some websites, however found that the example code on this website was the most useful for just getting the basic idea of how it works.

So I set up the copied, compiled and ran the TCPEchoServer.c on my desktop. I had to include the DieWithError.c and HandleTCPClient.c files using two #include "..." s

I compiled them using the command gcc -Wall -o echoServer TCPEchoServer.c 

Then I tested them just locally using to locall loopback address (127.0.0.1) and my LAN IP address (10.1.1.10):



I had to install gcc on the Raspberry Pi using:

pacman -S gcc

After I copied and compiled the TCPEchoClient.c file I checked I had connectivity by sshing into the Raspberry Pi then running the client and pointing it toward my desktop computer.


Success!

Raspberry Pi - OpenSSH

After getting all the basics sorted on the Raspberry Pi with Arch Linux. I thought it would be a good idea to set up OpenSSH on the device so I don't need to keep swapping over my keyboard and screen to the Pi.

Using the package manager, this proved to be extremely easy. It was as simple as typing in:


pacman -S openssh

And it was ready to go once it had been installed. The service had already added itself to the rc.conf file under DAEMONS with the @ symbol so it wouldn't wait for openssh to load and just run in in the background.

I was able to log in from my desktop (running Linux Mint if you're interested) below:
SSHing into my Raspberry Pi
So there it goes. I also did a little bit of testing using iperf to see if it really was 100Mbit:


Close enough to 100Mbit for me not to worry about it!

Raspberry Pi - Basic Setup

I've finally got round to having a bit of a play with my Raspberry Pi.
My Raspberry Pi sitting on my switch sitting on my desktop PC
To start off with I thought it would be interesting to try out Arch Linux. Previously I've only used Ubuntu and other Debian based distros so it's been a bit of a learning experience.

After downloading the image and copying it to my SD card, the device booted without issue.

You're met with a rather unassuming login screen consisting of nothing more than this:



The welcoming login screen
I logged in fine and had a quick look around the file system. First thing I noticed was the lack of a user folder under /home. After reading a bit about Arch Linux, especially their philosophy, I can understand why. Essentially Arch aims to provide the bones of a system that you build up for yourself.

I tried pining out to the internet without luck however. I checked /etc/rc.conf to find the usual:


 interface=eth0
 address=
 netmask=
 gateway=

Which should enable DHCP. This wasn't a problem however as I was going to put a static IP in there anyway. So I updated it to read:

 interface=eth0
 address=10.1.1.11
 netmask=255.255.255.0
 broadcast=10.1.1.255
 gateway=10.1.1.1

then restarted Raspberry Pi using reboot. Once it came back up I tested it by pinging my desktop computer, the router, then out to a Google DHCP server.

[root@ArchPi ~]# ping 10.1.1.10
PING 10.1.1.10 (10.1.1.10) 56(84) bytes of data.
64 bytes from 10.1.1.10: icmp_req=1 ttl=64 time=0.572 ms
^C
--- 10.1.1.10 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.572/0.572/0.572/0.000 ms

[root@ArchPi ~]# ping 10.1.1.1
PING 10.1.1.1 (10.1.1.1) 56(84) bytes of data.
64 bytes from 10.1.1.1: icmp_req=1 ttl=255 time=1.47 ms
64 bytes from 10.1.1.1: icmp_req=2 ttl=255 time=1.62 ms
^C
--- 10.1.1.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 1.478/1.551/1.625/0.083 ms

[root@ArchPi ~]# ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_req=1 ttl=38 time=208 ms
64 bytes from 8.8.8.8: icmp_req=2 ttl=37 time=208 ms
64 bytes from 8.8.8.8: icmp_req=3 ttl=38 time=207 ms
^C
--- 8.8.8.8 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2000ms
rtt min/avg/max/mdev = 207.756/208.129/208.624/0.521 ms

YAY! It was working, or at least I thought.
When I tried pinging google.com, I got this:

[root@ArchPi ~]# ping google.com
ping: unknown host google.com


Obviously if I can ping out to the internet, but can't find a named host I must be missing some DNS servers. I edited /etc/resolv.conf  and added these lines:

nameserver 202.37.101.1
nameserver 202.37.101.2

Which are my ISPs primary and secondary DNS servers. Success this time, I was able to resolve names

[root@ArchPi ~]# ping google.com
PING google.com (74.125.237.36) 56(84) bytes of data.
64 bytes from syd01s05-in-f4.1e100.net (74.125.237.36): icmp_req=1 ttl=47 time=50.9 ms
64 bytes from syd01s05-in-f4.1e100.net (74.125.237.36): icmp_req=2 ttl=47 time=57.2 ms

I then ran pacman -Syu to update my package lists.

Success!