Sock submodule for raw IPv4/IPv6. More...
Sock submodule for raw IPv4/IPv6.
First you need to include a module that implements this API in your application's Makefile. For example the implementation for GNRC is called gnrc_sock_ip
.
Above you see a simple IPv6 server. Don't forget to also include the IPv6 module of your networking implementation (e.g. gnrc_ipv6_default
for GNRC) and at least one network device.
After including header files for the address families, protocol numbers and the raw `sock`s themselves, we create some buffer space buf
to store the data received by the server:
To be able to listen for incoming packets we bind the sock
by setting a local end point (even if we just state here, that we just want to bind it to any IPv6 address).
We then proceed to create the sock
. It is bound to local
and listens for IPv6 packets with next header field PROTNUM_IPV6_NONXT. Since we don't need any further configuration we set the flags to 0. In case of an error we stop the program:
The application then waits indefinitely for an incoming message in buf
from remote
. If we want to timeout this wait period we could alternatively set the timeout
parameter of sock_ip_recv() to a value != SOCK_NO_TIMEOUT
. If an error occurs on receive we just ignore it and continue looping.
If we receive a message we use its remote
to reply. Note since the proto
was already set during sock_ip_create() we can just leave proto
for the sock_ip_send() set to 0 (it is ignored by that function in that case anyway). In case of an error on send we print an according message:
There are two kinds of clients. Those that do expect a reply and those who don't. A client that does not require a reply is very simple to implement in one line:
With data
being the data sent, data_len
the length of data
, PROTNUM
the next header number for the sent packet and remote
the remote end point the packet that is to be sent.
To see some other capabilities we look at a more complex example in form of the counter of the echo server above:
Again: Don't forget to also include the IPv6 module of your networking implementation (e.g. gnrc_ipv6_default
for GNRC) and at least one network device.
We first create again a sock
with a local end point bound to any IPv6 address. Note that we also could specify the remote end point here and not use it with sock_ip_send().
We then create a remote end point for the link-local all nodes multicast address (ff02::1
) and send a "Hello!" message to that end point.
We then wait a second for a reply and print it when it is received.
Finally, we wait a second before sending out the next "Hello!" with xtimer_sleep(1)
.
Files | |
file | ip.h |
Raw IPv4/IPv6 sock definitions. | |
Typedefs | |
typedef struct sock_ip | sock_ip_t |
Type for a raw IPv4/IPv6 sock object. More... | |
Functions | |
int | sock_ip_create (sock_ip_t *sock, const sock_ip_ep_t *local, const sock_ip_ep_t *remote, uint8_t proto, uint16_t flags) |
Creates a new raw IPv4/IPv6 sock object. More... | |
void | sock_ip_close (sock_ip_t *sock) |
Closes a raw IPv4/IPv6 sock object. More... | |
int | sock_ip_get_local (sock_ip_t *sock, sock_ip_ep_t *ep) |
Gets the local end point of a raw IPv4/IPv6 sock object. More... | |
int | sock_ip_get_remote (sock_ip_t *sock, sock_ip_ep_t *ep) |
Gets the remote end point of a raw IPv4/IPv6 sock object. More... | |
ssize_t | sock_ip_recv (sock_ip_t *sock, void *data, size_t max_len, uint32_t timeout, sock_ip_ep_t *remote) |
Receives a message over IPv4/IPv6 from remote end point. More... | |
ssize_t | sock_ip_recv_buf (sock_ip_t *sock, void **data, void **buf_ctx, uint32_t timeout, sock_ip_ep_t *remote) |
Provides stack-internal buffer space containing an IPv4/IPv6 message from remote end point. More... | |
ssize_t | sock_ip_send (sock_ip_t *sock, const void *data, size_t len, uint8_t proto, const sock_ip_ep_t *remote) |
Sends a message over IPv4/IPv6 to remote end point. More... | |
void sock_ip_close | ( | sock_ip_t * | sock | ) |
Closes a raw IPv4/IPv6 sock object.
(sock != NULL)
[in] | sock | A raw IPv4/IPv6 sock object. |
int sock_ip_create | ( | sock_ip_t * | sock, |
const sock_ip_ep_t * | local, | ||
const sock_ip_ep_t * | remote, | ||
uint8_t | proto, | ||
uint16_t | flags | ||
) |
Creates a new raw IPv4/IPv6 sock object.
(sock != NULL)
[out] | sock | The resulting sock object. |
[in] | local | Local end point for the sock object. May be NULL. sock_ip_ep_t::netif must either be SOCK_ADDR_ANY_NETIF or equal to sock_ip_ep_t::netif of remote if remote != NULL . If NULL sock_ip_send() may bind implicitly. |
[in] | remote | Remote end point for the sock object. May be NULL but then the remote parameter of sock_ip_send() may not be NULL or it will always error with return value -ENOTCONN. sock_ip_ep_t::port may not be 0 if remote != NULL . sock_ip_ep_t::netif must either be SOCK_ADDR_ANY_NETIF or equal to sock_ip_ep_t::netif of local if local != NULL . |
[in] | proto | Protocol to use in the raw IPv4/IPv6 sock object (the protocol header field in IPv4 and the next_header field in IPv6). |
[in] | flags | Flags for the sock object. See also [sock flags](net_sock_flags). May be 0. |
local != NULL
and local
is already used elsewhere local != NULL
or remote != NULL
and sock_ip_ep_t::family of local
or remote
is not supported. remote
is an invalid address. local
or remote
are not valid interfaces or contradict each other (i.e. `(local->netif != remote->netif) && ((local->netif != SOCK_ADDR_ANY_NETIF) || (remote->netif != SOCK_ADDR_ANY_NETIF))if neither is
NULL). @return -ENOMEM, if not enough resources can be provided for
sock` to be created. local != NULL
or remote != NULL
and proto is not supported by sock_ip_ep_t::family of local
or remote
. int sock_ip_get_local | ( | sock_ip_t * | sock, |
sock_ip_ep_t * | ep | ||
) |
Gets the local end point of a raw IPv4/IPv6 sock object.
This gets the local end point of a raw IPv4/IPv6 sock object. Note that this might not be the same end point you added in sock_ip_create(), but an end point more suitable for the implementation. Examples for this might be that if sock_ip_ep_t::netif is given in sock_ip_create(), the implementation might choose to return the address on this interface the sock
is bound to in ep's
sock_ip_ep_t::addr.
(sock != NULL) && (ep != NULL)
[in] | sock | A raw IPv4/IPv6 sock object. |
[out] | ep | The local end point. |
sock
has no end point bound to it. int sock_ip_get_remote | ( | sock_ip_t * | sock, |
sock_ip_ep_t * | ep | ||
) |
Gets the remote end point of a raw IPv4/IPv6 sock object.
(sock != NULL) && (ep != NULL)
This gets the remote end point of a raw IPv4/IPv6 sock object. Note that this might not be the same end point you added in sock_ip_create(), but an end point more suitable for the implementation. Examples for this might be that if sock_ip_ep_t::netif is given in sock_ip_create(), the implementation might choose to return the address on this interface the sock
is bound to in ep's
sock_ip_ep_t::addr.
[in] | sock | A raw IPv4/IPv6 sock object. |
[out] | ep | The remote end point. |
sock
has no remote end point bound to it. ssize_t sock_ip_recv | ( | sock_ip_t * | sock, |
void * | data, | ||
size_t | max_len, | ||
uint32_t | timeout, | ||
sock_ip_ep_t * | remote | ||
) |
Receives a message over IPv4/IPv6 from remote end point.
(sock != NULL) && (data != NULL) && (max_len > 0)
[in] | sock | A raw IPv4/IPv6 sock object. |
[out] | data | Pointer where the received data should be stored. |
[in] | max_len | Maximum space available at data . |
[in] | timeout | Timeout for receive in microseconds. If 0 and no data is available, the function returns immediately. May be SOCK_NO_TIMEOUT for no timeout (wait until data is available). |
[out] | remote | Remote end point of the received data. May be NULL, if it is not required by the application. |
sock
is not given. timeout
is 0
and no data is available. remote
is invalid or sock
is not properly initialized (or closed while sock_ip_recv() blocks). data
. sock
. timeout
expired. ssize_t sock_ip_recv_buf | ( | sock_ip_t * | sock, |
void ** | data, | ||
void ** | buf_ctx, | ||
uint32_t | timeout, | ||
sock_ip_ep_t * | remote | ||
) |
Provides stack-internal buffer space containing an IPv4/IPv6 message from remote end point.
(sock != NULL) && (data != NULL) && (buf_ctx != NULL)
[in] | sock | A raw IPv4/IPv6 sock object. |
[out] | data | Pointer to a stack-internal buffer space containing the received data. |
[in,out] | buf_ctx | Stack-internal buffer context. If it points to a NULL pointer, the stack returns a new buffer space for a new packet. If it does not point to a NULL pointer, an existing context is assumed to get a next segment in a buffer. |
[in] | timeout | Timeout for receive in microseconds. If 0 and no data is available, the function returns immediately. May be SOCK_NO_TIMEOUT for no timeout (wait until data is available). |
[out] | remote | Remote end point of the received data. May be NULL, if it is not required by the application. |
buf_ctx
to get more buffers until result is 0 or an error. buf_ctx
was provided, it was released. sock
is not given. timeout
is 0
and no data is available. remote
is invalid or sock
is not properly initialized (or closed while sock_ip_recv() blocks). data
. sock
. timeout
expired. ssize_t sock_ip_send | ( | sock_ip_t * | sock, |
const void * | data, | ||
size_t | len, | ||
uint8_t | proto, | ||
const sock_ip_ep_t * | remote | ||
) |
Sends a message over IPv4/IPv6 to remote end point.
((sock != NULL || remote != NULL)) && (if (len != 0): (data != NULL))
[in] | sock | A raw IPv4/IPv6 sock object. May be NULL. A sensible local end point should be selected by the implementation in that case. |
[in] | data | Pointer where the received data should be stored. May be NULL if len == 0 . |
[in] | len | Maximum space available at data . |
[in] | proto | Protocol to use in the packet sent, in case sock == NULL . If sock != NULL this parameter will be ignored. |
[in] | remote | Remote end point for the sent data. May be NULL , if sock has a remote end point. sock_ip_ep_t::family may be AF_UNSPEC, if local end point of sock provides this information. |
remote != NULL
and sock_ip_ep_t::family of remote
is != AF_UNSPEC and not supported. remote
is an invalid address. remote
is not a valid interface or contradicts the local interface of sock
. remote
or remote end point of sock
is not reachable. data
. remote == NULL
, but sock
has no remote end point. sock == NULL
and proto
is not by sock_ip_ep_t::family of remote
.