title: Linux x86_64 assembly socket programming
body: <p><strong>Hello all.</strong></p>
  
  <p>So I'm learning assembly.<br>And as per my usual learning steps with any new language I pick up I've arrived at networking with assembly.</p>
  
  <p>Which, sadly isn't going that well as I've pretty much failed at step 0, which would be getting a socket through which communication can begin.</p>
  
  <p>The assembly code should be roughly equal to the following C code:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;sys/socket.h&gt;
  
  int main(){
          int sock;
          sock = socket(AF_INET, SOCK_STREAM, 0);
  }
  </code></pre>
  
  <p>(Let's ignore the fact that it's not closing the socket for now.)</p>
  
  <p>So here's what I did thus far:</p>
  
  <ul>
  <li>Checked <a href="http://syscalls.kernelgrok.com/" rel="noreferrer">the manual</a>. Which would imply that I need to make a <code>socketcall()</code> this is all good and well. The problem starts with that it would need an <code>int</code> that describes what sort of socketcall it should make. The calls <a href="http://man7.org/linux/man-pages/man2/socketcall.2.html" rel="noreferrer">manpage</a> isn't helping much with this either as it only describes that:</li>
  </ul>
  
  <blockquote>
    <p>On a some architectures—for example, x86-64 and ARM—there is no
           socketcall() system call; instead socket(2), accept(2), bind(2), and
           so on really are implemented as separate system calls.</p>
  </blockquote>
  
  <ul>
  <li><p>Yet there are no such calls in the original list of syscalls - and as far as I know the <code>socket()</code>, <code>accept()</code>, <code>bind()</code>, <code>listen()</code>, etc. are calls from <code>libnet</code> and not from the kernel. This got me utterly confused so I've decided to compile the above <code>C</code> code and check up on it with <code>strace</code>. This yielded the following:</p>
  
  <p>socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3</p></li>
  <li><p>While that didn't got me any closer to knowing what <code>socket()</code> <strong>is</strong> it did explain it's arguments. For witch I don't seem to find the proper documentation (again). I thought that <code>PF_INET</code>, <code>SOCK_STREAM</code>, <code>IPPROTO_IP</code> would be defined in <code>&lt;sys/socket.h&gt;</code> but my <code>grep</code>-ing for them didn't seem to find anything of use. So I decided to just wing it by using <code>gdb</code> in tandem with <code>disass main</code> to find the values. This gave the following output:</p>
  
  <p>Dump of assembler code for function main:
     0x00000000004004fd &lt;+0>: push   rbp
     0x00000000004004fe &lt;+1>: mov    rbp,rsp
     0x0000000000400501 &lt;+4>: sub    rsp,0x10
     0x0000000000400505 &lt;+8>: mov    edx,0x0
     0x000000000040050a &lt;+13>:    mov    esi,0x1
     0x000000000040050f &lt;+18>:    mov    edi,0x2
     0x0000000000400514 &lt;+23>:    call   0x400400 
     0x0000000000400519 &lt;+28>:    mov    DWORD PTR [rbp-0x4],eax
     0x000000000040051c &lt;+31>:    leave<br>
     0x000000000040051d &lt;+32>:    ret<br>
  End of assembler dump.</p></li>
  <li><p>In my experience this would imply that <code>socket()</code> gets it's parameters from <code>EDX</code> (<code>PF_INET</code>), <code>ESI</code> (<code>SOCK_STREAM</code>), and <code>EDI</code> (<code>IPPROTO_IP</code>). Which would be odd for a syscall (as the convention with linux syscalls would be to use <code>EAX</code>/<code>RAX</code> for the call number and other registers for the parameters in increasing order, eg. <code>RBX</code>, <code>RCX</code>, <code>RDX</code> ...). The fact that this is beaing <code>CALL</code>-ed and not <code>INT 0x80</code>'d would also imply that this is not in fact a system call but rather something thats being called from a shared object. Or something.</p></li>
  <li><p>But then again. Passing arguments in registers is very odd for something that's <code>CALL</code>-ed. Normally as far as I know argument's for called things should be <code>PUSH</code>-ed onto the stack, as the compiler can't know what registers they would try to use.</p></li>
  <li><p>This behavior becomes even more curious when checking the produced binary with <code>ldd</code>:</p>
  
  <p>linux-vdso.so.1 (0x00007fff4a7fc000)
  libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f56b0c61000)
  /lib64/ld-linux-x86-64.so.2 (0x00007f56b1037000)</p></li>
  <li><p>There appears to be no networking library's linked.</p></li>
  </ul>
  
  <p>And that's the point where I've ran out of ideas.</p>
  
  <p>So I'm asking for the following:</p>
  
  <ul>
  <li>A documentation that describes the <code>x86-64</code> linux kernel's actual syscalls and their associated numbers. (Preferably as a header file for <code>C</code>.)</li>
  <li>The header files that define <code>PF_INET</code>, <code>SOCK_STREAM</code>, <code>IPPROTO_IP</code> as it really bugs me that I wasn't able to find them on my own system.</li>
  <li>Maybe a tutorial for networking in assembly on <code>x86-64</code> linux. (For <code>x86-32</code> it's easy to find material but for some reason I came up empty with the 64 bits stuff.)</li>
  </ul>
  
  <p>Thanks!</p>