diff --git a/share/libc/sys/socket.h b/share/libc/sys/socket.h
index 4a6e6c21f4f0c90c4f9038e42b47340ad1a7ab38..faad4d167cb90fb2aee12659ee8782fb3e903b6a 100644
--- a/share/libc/sys/socket.h
+++ b/share/libc/sys/socket.h
@@ -443,8 +443,29 @@ extern int listen(int sockfd, int backlog);
  */
 extern ssize_t recv(int sockfd, void * buf, size_t len, int flags);
 
-extern ssize_t recvfrom(int, void *, size_t, int,
-        struct sockaddr *, socklen_t *);
+
+/*@
+  requires valid_sockfd: 0 <= sockfd < __FC_MAX_OPEN_SOCKETS;
+  requires valid_buffer_length: \valid((char *)buf+(0 .. len-1));
+  requires valid_addrbuf_or_null: (\valid(addrbuf_len) &&
+                                   \initialized(addrbuf_len) &&
+                                   \valid((char *)addrbuf+(0 .. *addrbuf_len-1)))
+                                  || (addrbuf == \null && addrbuf_len == \null);
+  assigns *((char *)buf+(0 .. len-1)), __fc_sockfds[sockfd], \result
+          \from sockfd, len, flags, __fc_sockfds[sockfd];
+  assigns *addrbuf_len \from indirect:sockfd, indirect: len,
+                             indirect:flags, __fc_sockfds[sockfd];
+  assigns *((char *)addrbuf+(0 .. \old(*addrbuf_len)-1))
+          \from indirect:sockfd, indirect: len,
+                         indirect:flags, __fc_sockfds[sockfd];
+  ensures result_error_or_received_length: \result == -1 || 0 <= \result <= len;
+  ensures initialization:buf: \initialized(((char *)buf+(0 .. \result-1)));
+  ensures initialization:addrbuf:
+          addrbuf != \null ==>
+            \initialized(((char *)addrbuf+(0 .. \old(*addrbuf_len)-1)));
+*/
+extern ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
+                        struct sockaddr *addrbuf, socklen_t *addrbuf_len);
 
 /*@ requires valid_sockfd: 0 <= sockfd < __FC_MAX_OPEN_SOCKETS;
   @ requires msg_control_has_room:
@@ -483,8 +504,22 @@ extern ssize_t recvmsg(int sockfd, struct msghdr *hdr, int flags);
  */
 extern ssize_t send(int sockfd, const void *buf, size_t len, int flags);
 extern ssize_t sendmsg(int, const struct msghdr *, int);
-extern ssize_t sendto(int, const void *, size_t, int, const struct sockaddr *,
-        socklen_t);
+
+/*@
+  requires available_sockfd: 0 <= sockfd < __FC_MAX_OPEN_SOCKETS;
+  requires buf_len_ok: \valid_read(((char*)buf)+(0 .. len - 1));
+  assigns errno
+    \from indirect:sockfd, indirect:__fc_sockfds[sockfd],
+          indirect:((char *)buf)[0..len], flags;
+  assigns __fc_sockfds[sockfd]
+    \from __fc_sockfds[sockfd], ((char *)buf)[0..len], flags;
+  assigns \result
+    \from indirect:sockfd, indirect:__fc_sockfds[sockfd],
+          indirect:((char*)buf)[0..len], indirect:flags;
+  ensures error_or_chars_sent: \result == -1 || 0 <= \result <= len;
+ */
+extern ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
+                      const struct sockaddr *address, socklen_t address_len);
 
 /*@
   requires valid_sockfd: 0 <= sockfd < __FC_MAX_OPEN_SOCKETS;
diff --git a/tests/libc/oracle/fc_libc.0.res.oracle b/tests/libc/oracle/fc_libc.0.res.oracle
index 21143ee8813c382d58b61c64f175924430c33b18..42687186222dc0d070e0a5d494c477dca47b6e42 100644
--- a/tests/libc/oracle/fc_libc.0.res.oracle
+++ b/tests/libc/oracle/fc_libc.0.res.oracle
@@ -1,4 +1,6 @@
 [kernel] Parsing tests/libc/fc_libc.c (with preprocessing)
+[kernel] share/libc/sys/socket.h:451: Warning: 
+  clause with '\initialized' must contain name 'initialization'
 [eva] Analyzing a complete application starting at main
 [eva] Computing initial state
 [eva] Initial state computed
@@ -41,7 +43,7 @@
    wcscpy (0 call); wcslen (2 calls); wcsncat (0 call); wcsncpy (0 call);
    wmemcpy (0 call); wmemset (0 call); 
   
-  Specified-only functions (411)
+  Specified-only functions (413)
   ==============================
    FD_CLR (0 call); FD_ISSET (0 call); FD_SET (0 call); FD_ZERO (0 call);
    Frama_C_int_interval (0 call); Frama_C_long_interval (0 call);
@@ -133,38 +135,39 @@
    putchar (0 call); putchar_unlocked (0 call); puts (0 call); qsort (0 call);
    quick_exit (0 call); raise (0 call); rand (0 call); random (0 call);
    read (0 call); readdir (0 call); readv (0 call); realloc (3 calls);
-   recv (0 call); recvmsg (0 call); remove (0 call); rename (0 call);
-   rewind (0 call); round (0 call); roundf (0 call); roundl (0 call);
-   seed48 (0 call); select (0 call); send (0 call); setbuf (0 call);
-   setegid (0 call); seteuid (0 call); setgid (0 call); sethostname (0 call);
-   setitimer (0 call); setjmp (0 call); setlogmask (0 call); setpgid (0 call);
-   setpriority (0 call); setregid (0 call); setresgid (0 call);
-   setresuid (0 call); setreuid (0 call); setrlimit (0 call); setsid (0 call);
-   setsockopt (0 call); settimeofday (0 call); setuid (0 call);
-   setvbuf (0 call); shutdown (0 call); sigaction (0 call); sigaddset (0 call);
-   sigdelset (0 call); sigemptyset (0 call); sigfillset (0 call);
-   sigismember (0 call); siglongjmp (0 call); signal (0 call);
-   sigprocmask (0 call); sin (0 call); sinf (0 call); sinl (0 call);
-   socket (0 call); socketpair (0 call); sqrt (0 call); sqrtf (0 call);
-   sqrtl (0 call); srand (0 call); srand48 (0 call); srandom (0 call);
-   stat (0 call); stpcpy (0 call); strcasestr (0 call); strchrnul (0 call);
-   strcoll (0 call); strcspn (0 call); strftime (0 call); strlcat (0 call);
-   strlcpy (0 call); strncasecmp (0 call); strpbrk (0 call); strsep (0 call);
-   strspn (0 call); strtod (0 call); strtof (0 call); strtoimax (0 call);
-   strtok (0 call); strtok_r (0 call); strtol (0 call); strtold (0 call);
-   strtoll (0 call); strtoul (0 call); strtoull (0 call); strxfrm (0 call);
-   sync (0 call); sysconf (0 call); syslog (0 call); system (0 call);
-   tcflush (0 call); tcgetattr (0 call); tcsetattr (0 call); time (0 call);
-   times (0 call); tmpfile (0 call); tmpnam (0 call); trunc (0 call);
-   truncf (0 call); truncl (0 call); ttyname (0 call); tzset (0 call);
-   umask (0 call); uname (0 call); ungetc (0 call); unlink (0 call);
-   usleep (0 call); utimes (0 call); vfprintf (0 call); vfscanf (0 call);
-   vprintf (0 call); vscanf (0 call); vsnprintf (0 call); vsprintf (0 call);
-   vsyslog (0 call); wait (0 call); waitpid (0 call); wcschr (0 call);
-   wcscmp (0 call); wcscspn (0 call); wcslcat (0 call); wcslcpy (0 call);
-   wcsncmp (0 call); wcspbrk (0 call); wcsrchr (0 call); wcsspn (0 call);
-   wcsstr (0 call); wcstombs (0 call); wctomb (0 call); wmemchr (0 call);
-   wmemcmp (0 call); wmemmove (0 call); write (0 call); 
+   recv (0 call); recvfrom (0 call); recvmsg (0 call); remove (0 call);
+   rename (0 call); rewind (0 call); round (0 call); roundf (0 call);
+   roundl (0 call); seed48 (0 call); select (0 call); send (0 call);
+   sendto (0 call); setbuf (0 call); setegid (0 call); seteuid (0 call);
+   setgid (0 call); sethostname (0 call); setitimer (0 call); setjmp (0 call);
+   setlogmask (0 call); setpgid (0 call); setpriority (0 call);
+   setregid (0 call); setresgid (0 call); setresuid (0 call);
+   setreuid (0 call); setrlimit (0 call); setsid (0 call); setsockopt (0 call);
+   settimeofday (0 call); setuid (0 call); setvbuf (0 call); shutdown (0 call);
+   sigaction (0 call); sigaddset (0 call); sigdelset (0 call);
+   sigemptyset (0 call); sigfillset (0 call); sigismember (0 call);
+   siglongjmp (0 call); signal (0 call); sigprocmask (0 call); sin (0 call);
+   sinf (0 call); sinl (0 call); socket (0 call); socketpair (0 call);
+   sqrt (0 call); sqrtf (0 call); sqrtl (0 call); srand (0 call);
+   srand48 (0 call); srandom (0 call); stat (0 call); stpcpy (0 call);
+   strcasestr (0 call); strchrnul (0 call); strcoll (0 call); strcspn (0 call);
+   strftime (0 call); strlcat (0 call); strlcpy (0 call); strncasecmp (0 call);
+   strpbrk (0 call); strsep (0 call); strspn (0 call); strtod (0 call);
+   strtof (0 call); strtoimax (0 call); strtok (0 call); strtok_r (0 call);
+   strtol (0 call); strtold (0 call); strtoll (0 call); strtoul (0 call);
+   strtoull (0 call); strxfrm (0 call); sync (0 call); sysconf (0 call);
+   syslog (0 call); system (0 call); tcflush (0 call); tcgetattr (0 call);
+   tcsetattr (0 call); time (0 call); times (0 call); tmpfile (0 call);
+   tmpnam (0 call); trunc (0 call); truncf (0 call); truncl (0 call);
+   ttyname (0 call); tzset (0 call); umask (0 call); uname (0 call);
+   ungetc (0 call); unlink (0 call); usleep (0 call); utimes (0 call);
+   vfprintf (0 call); vfscanf (0 call); vprintf (0 call); vscanf (0 call);
+   vsnprintf (0 call); vsprintf (0 call); vsyslog (0 call); wait (0 call);
+   waitpid (0 call); wcschr (0 call); wcscmp (0 call); wcscspn (0 call);
+   wcslcat (0 call); wcslcpy (0 call); wcsncmp (0 call); wcspbrk (0 call);
+   wcsrchr (0 call); wcsspn (0 call); wcsstr (0 call); wcstombs (0 call);
+   wctomb (0 call); wmemchr (0 call); wmemcmp (0 call); wmemmove (0 call);
+   write (0 call); 
   
   Undefined and unspecified functions (1)
   =======================================
@@ -191,7 +194,7 @@
   Goto = 97
   Assignment = 459
   Exit point = 83
-  Function = 495
+  Function = 497
   Function call = 93
   Pointer dereferencing = 159
   Cyclomatic complexity = 296
diff --git a/tests/libc/oracle/fc_libc.1.res.oracle b/tests/libc/oracle/fc_libc.1.res.oracle
index 3c58f77336d9211e32fcf1f042c424df96e53bb7..1c7f3e7c9488445e723a1e84af235443d579c607 100644
--- a/tests/libc/oracle/fc_libc.1.res.oracle
+++ b/tests/libc/oracle/fc_libc.1.res.oracle
@@ -3686,6 +3686,40 @@ extern int listen(int sockfd, int backlog);
  */
 extern ssize_t recv(int sockfd, void *buf, size_t len, int flags);
 
+/*@ requires valid_sockfd: 0 ≤ sockfd < 1024;
+    requires valid_buffer_length: \valid((char *)buf + (0 .. len - 1));
+    requires
+      valid_addrbuf_or_null:
+        (\valid(addrbuf_len) ∧ \initialized(addrbuf_len) ∧
+         \valid((char *)addrbuf + (0 .. *addrbuf_len - 1))) ∨
+        (addrbuf ≡ \null ∧ addrbuf_len ≡ \null);
+    ensures
+      result_error_or_received_length:
+        \result ≡ -1 ∨ (0 ≤ \result ≤ \old(len));
+    ensures
+      initialization: buf:
+        \initialized((char *)\old(buf) + (0 .. \result - 1));
+    ensures
+      initialization: addrbuf:
+        \old(addrbuf) ≢ \null ⇒
+        \initialized((char *)\old(addrbuf) + (0 .. \old(*addrbuf_len) - 1));
+    assigns *((char *)buf + (0 .. len - 1)), __fc_sockfds[sockfd], \result,
+            *addrbuf_len, *((char *)addrbuf + (0 .. \old(*addrbuf_len) - 1));
+    assigns *((char *)buf + (0 .. len - 1))
+      \from sockfd, len, flags, __fc_sockfds[sockfd];
+    assigns __fc_sockfds[sockfd]
+      \from sockfd, len, flags, __fc_sockfds[sockfd];
+    assigns \result \from sockfd, len, flags, __fc_sockfds[sockfd];
+    assigns *addrbuf_len
+      \from (indirect: sockfd), (indirect: len), (indirect: flags),
+            __fc_sockfds[sockfd];
+    assigns *((char *)addrbuf + (0 .. \old(*addrbuf_len) - 1))
+      \from (indirect: sockfd), (indirect: len), (indirect: flags),
+            __fc_sockfds[sockfd];
+ */
+extern ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
+                        struct sockaddr *addrbuf, socklen_t *addrbuf_len);
+
 /*@ requires valid_sockfd: 0 ≤ sockfd < 1024;
     requires
       msg_control_has_room:
@@ -3737,6 +3771,23 @@ extern ssize_t recvmsg(int sockfd, struct msghdr *hdr, int flags);
  */
 extern ssize_t send(int sockfd, void const *buf, size_t len, int flags);
 
+/*@ requires available_sockfd: 0 ≤ sockfd < 1024;
+    requires buf_len_ok: \valid_read((char *)buf + (0 .. len - 1));
+    ensures
+      error_or_chars_sent: \result ≡ -1 ∨ (0 ≤ \result ≤ \old(len));
+    assigns __fc_errno, __fc_sockfds[sockfd], \result;
+    assigns __fc_errno
+      \from (indirect: sockfd), (indirect: __fc_sockfds[sockfd]),
+            (indirect: *((char *)buf + (0 .. len))), flags;
+    assigns __fc_sockfds[sockfd]
+      \from __fc_sockfds[sockfd], *((char *)buf + (0 .. len)), flags;
+    assigns \result
+      \from (indirect: sockfd), (indirect: __fc_sockfds[sockfd]),
+            (indirect: *((char *)buf + (0 .. len))), (indirect: flags);
+ */
+extern ssize_t sendto(int sockfd, void const *buf, size_t len, int flags,
+                      struct sockaddr const *address, socklen_t address_len);
+
 /*@ requires valid_sockfd: 0 ≤ sockfd < 1024;
     requires
       optval_null_or_has_room:
diff --git a/tests/libc/oracle/socket_h.res.oracle b/tests/libc/oracle/socket_h.res.oracle
index fb67e21c1df1632acbdfaed561ee56229063ce04..06bdbf31c5edea8d5522cbc5ee63d99658a3365f 100644
--- a/tests/libc/oracle/socket_h.res.oracle
+++ b/tests/libc/oracle/socket_h.res.oracle
@@ -59,10 +59,52 @@
 [eva] tests/libc/socket_h.c:21: 
   function getsockname: precondition 'valid_address' got status valid.
 [eva] Done for function getsockname
+[eva] computing for function sendto <- main.
+  Called from tests/libc/socket_h.c:24.
+[eva] using specification for function sendto
+[eva] tests/libc/socket_h.c:24: 
+  function sendto: precondition 'available_sockfd' got status valid.
+[eva] tests/libc/socket_h.c:24: 
+  function sendto: precondition 'buf_len_ok' got status valid.
+[eva] Done for function sendto
+[eva] computing for function sendto <- main.
+  Called from tests/libc/socket_h.c:27.
+[eva] tests/libc/socket_h.c:27: 
+  function sendto: precondition 'available_sockfd' got status valid.
+[eva] tests/libc/socket_h.c:27: 
+  function sendto: precondition 'buf_len_ok' got status valid.
+[eva] Done for function sendto
+[eva] computing for function recvfrom <- main.
+  Called from tests/libc/socket_h.c:31.
+[eva] using specification for function recvfrom
+[eva] tests/libc/socket_h.c:31: 
+  function recvfrom: precondition 'valid_sockfd' got status valid.
+[eva] tests/libc/socket_h.c:31: 
+  function recvfrom: precondition 'valid_buffer_length' got status valid.
+[eva] tests/libc/socket_h.c:31: 
+  function recvfrom: precondition 'valid_addrbuf_or_null' got status valid.
+[eva] Done for function recvfrom
+[eva] tests/libc/socket_h.c:35: assertion got status valid.
+[eva] computing for function recvfrom <- main.
+  Called from tests/libc/socket_h.c:37.
+[eva] tests/libc/socket_h.c:37: 
+  function recvfrom: precondition 'valid_sockfd' got status valid.
+[eva] tests/libc/socket_h.c:37: 
+  function recvfrom: precondition 'valid_buffer_length' got status valid.
+[eva] tests/libc/socket_h.c:37: 
+  function recvfrom: precondition 'valid_addrbuf_or_null' got status valid.
+[eva:invalid-assigns] tests/libc/socket_h.c:37: 
+  Completely invalid destination for assigns clause *addrbuf_len. Ignoring.
+[eva:invalid-assigns] tests/libc/socket_h.c:37: 
+  Completely invalid destination
+  for assigns clause *((char *)addrbuf + (0 .. \old(*addrbuf_len) - 1)).
+  Ignoring.
+[eva] Done for function recvfrom
 [eva] Recording results for main
 [eva] done for function main
 [eva] ====== VALUES COMPUTED ======
 [eva:final-states] Values at end of function main:
+  __fc_errno ∈ [--..--]
   __fc_sockfds[0..1023] ∈ [--..--]
   __fc_socket_counter ∈ [--..--]
   sockfd ∈ [0..1023]
@@ -73,3 +115,10 @@
   optlen ∈ {4}
   addr2 ∈ [--..--] or UNINITIALIZED
   socklen ∈ [0..8]
+  buf[0..39] ∈ [--..--]
+  sent ∈ {-1; 0; 1; 2; 3}
+  sent2 ∈ {-1; 0; 1; 2; 3}
+  recvfrom_addr ∈ [--..--]
+  recvfrom_addr_len ∈ [--..--]
+  received ∈ [-1..40]
+  received2 ∈ [-1..40]
diff --git a/tests/libc/socket_h.c b/tests/libc/socket_h.c
index 3a0e8d8cab974f29eb249f53759997d661e740d1..d52cb75cf23c207b155a61156ba0f9fa138706c7 100644
--- a/tests/libc/socket_h.c
+++ b/tests/libc/socket_h.c
@@ -19,5 +19,21 @@ int main() {
   struct sockaddr_in addr2;
   socklen_t socklen = sizeof(addr2);
   rc = getsockname(sockfd, (struct sockaddr *)&addr2, &socklen);
+
+  char buf[40] = {'a', 'b', 'c'};
+  ssize_t sent = sendto(sockfd, buf, 3, 0, (struct sockaddr *)&addr,
+                        sizeof(addr));
+
+  ssize_t sent2 = sendto(sockfd, buf, 3, 0, 0, 0);
+
+  struct sockaddr_in recvfrom_addr;
+  socklen_t recvfrom_addr_len = sizeof(recvfrom_addr);
+  ssize_t received = recvfrom(sockfd, buf, sizeof(buf), 0,
+                              (struct sockaddr *)&recvfrom_addr,
+                              &recvfrom_addr_len);
+  if (received != -1) {
+    //@ assert \initialized(&recvfrom_addr);
+  }
+  ssize_t received2 = recvfrom(sockfd, buf, sizeof(buf), 0, 0, 0);
   return rc;
 }