summaryrefslogtreecommitdiff
path: root/components/net/sal/include/sal_socket.h
blob: 7d74310094e87bafd476eafb1af210c91d162b32 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2018-05-24     ChenYong     First version
 */

#ifndef SAL_SOCKET_H__
#define SAL_SOCKET_H__

#include <stddef.h>
#include <arpa/inet.h>

#ifdef __cplusplus
extern "C" {
#endif

#if !defined(socklen_t) && !defined(SOCKLEN_T_DEFINED)
typedef uint32_t socklen_t;
#endif

#if !defined(sa_family_t) && !defined(SA_FAMILY_T_DEFINED)
typedef uint8_t sa_family_t;
#endif

/* If your port already typedef's in_port_t, define IN_PORT_T_DEFINED
   to prevent this code from redefining it. */
#if !defined(in_port_t) && !defined(IN_PORT_T_DEFINED)
typedef uint16_t in_port_t;
#endif

/* Socket protocol types (TCP/UDP/RAW) */
#define SOCK_STREAM 1
#define SOCK_DGRAM  2
#define SOCK_RAW    3
#define SOCK_PACKET 10

#define SOCK_NONBLOCK 04000
#define SOCK_CLOEXEC  02000000

#define SOCK_MAX (SOCK_CLOEXEC + 1)

/* Option flags per-socket. These must match the SOF_ flags in ip.h (checked in init.c) */
#define SO_REUSEADDR 0x0004 /* Allow local address reuse */
#define SO_KEEPALIVE 0x0008 /* keep connections alive */
#define SO_BROADCAST 0x0020 /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */

#define SO_PASSCRED 16
#define SO_PEERCRED 17

#define SO_BINDTODEVICE  25
#define SO_ATTACH_FILTER 26
#define SO_DETACH_FILTER 27

#define SO_SNDBUFFORCE 32
#define SO_RCVBUFFORCE 33
#define SO_PROTOCOL    38
#define SO_DOMAIN      39

/* Additional options, not kept in so_options */
#define SO_DEBUG       0x0001 /* Unimplemented: turn on debugging info recording */
#define SO_ACCEPTCONN  0x0002 /* socket has had listen() */
#define SO_DONTROUTE   0x0010 /* Unimplemented: just use interface addresses */
#define SO_USELOOPBACK 0x0040 /* Unimplemented: bypass hardware when possible */
#define SO_LINGER      0x0080 /* linger on close if data present */
#define SO_DONTLINGER  ((int)(~SO_LINGER))
#define SO_OOBINLINE   0x0100 /* Unimplemented: leave received OOB data in line */
#define SO_REUSEPORT   0x0200 /* Unimplemented: allow local address & port reuse */
#define SO_SNDBUF      0x1001 /* Unimplemented: send buffer size */
#define SO_RCVBUF      0x1002 /* receive buffer size */
#define SO_SNDLOWAT    0x1003 /* Unimplemented: send low-water mark */
#define SO_RCVLOWAT    0x1004 /* Unimplemented: receive low-water mark */
#define SO_SNDTIMEO    0x1005 /* send timeout */
#define SO_RCVTIMEO    0x1006 /* receive timeout */
#define SO_ERROR       0x1007 /* get error status and clear */
#define SO_TYPE        0x1008 /* get socket type */
#define SO_CONTIMEO    0x1009 /* Unimplemented: connect timeout */
#define SO_NO_CHECK    0x100a /* don't create UDP checksum */

/* Level number for (get/set)sockopt() to apply to socket itself */
#define SOL_SOCKET  0xfff    /* options for socket level */
#define SOL_NETLINK 270

#define AF_UNSPEC  0
#define AF_UNIX    1
#define AF_INET    2
#define AF_INET6   10
#define AF_NETLINK 16
#define AF_CAN     29  /* Controller Area Network      */
#define AF_AT      45  /* AT socket */
#define AF_WIZ     46  /* WIZnet socket */
#define PF_UNIX    AF_UNIX
#define PF_INET    AF_INET
#define PF_INET6   AF_INET6
#define PF_NETLINK AF_NETLINK
#define PF_UNSPEC  AF_UNSPEC
#define PF_CAN     AF_CAN
#define PF_AT      AF_AT
#define PF_WIZ     AF_WIZ

#define AF_MAX (AF_WIZ + 1)  /* For now.. */

#define IPPROTO_IP      0
#define IPPROTO_ICMP    1
#define IPPROTO_TCP     6
#define IPPROTO_UDP     17
#define IPPROTO_IPV6    41
#define IPPROTO_ICMPV6  58
#define IPPROTO_UDPLITE 136
#define IPPROTO_RAW     255

/* Flags we can use with send and recv */
#define MSG_PEEK     0x01    /* Peeks at an incoming message */
#define MSG_WAITALL  0x02    /* Unimplemented: Requests that the function block until the full amount of data requested can be returned */
#define MSG_OOB      0x04    /* Unimplemented: Requests out-of-band data. The significance and semantics of out-of-band data are protocol-specific */
#define MSG_DONTWAIT 0x08    /* Nonblocking i/o for this operation only */
#define MSG_MORE     0x10    /* Sender will send more */

/* Output-only flags returned through struct msghdr. */
#define MSG_CTRUNC 0x08    /* Control data was discarded due to truncation */

#define MSG_ERRQUEUE 0x2000  /* Fetch message from error queue */
#define MSG_CONFIRM  0x0800  /* Confirm path validity */

/* Options for level IPPROTO_IP */
#define IP_TOS 1
#define IP_TTL 2

/* Options for level IPPROTO_TCP */
#define TCP_NODELAY   0x01    /* don't delay send to coalesce packets */
#define TCP_KEEPALIVE 0x02    /* send KEEPALIVE probes when idle for pcb->keep_idle milliseconds */
#define TCP_KEEPIDLE  0x03    /* set pcb->keep_idle  - Same as TCP_KEEPALIVE, but use seconds for get/setsockopt */
#define TCP_KEEPINTVL 0x04    /* set pcb->keep_intvl - Use seconds for get/setsockopt */
#define TCP_KEEPCNT   0x05    /* set pcb->keep_cnt   - Use number of probes sent for get/setsockopt */

/* Options and types related to multicast membership */
#define IP_ADD_MEMBERSHIP  3
#define IP_DROP_MEMBERSHIP 4
/* Options and types for UDP multicast traffic handling */
#define IP_MULTICAST_TTL  5
#define IP_MULTICAST_IF   6
#define IP_MULTICAST_LOOP 7

typedef struct ip_mreq
{
    struct in_addr imr_multiaddr; /* IP multicast address of group */
    struct in_addr imr_interface; /* local IP address of interface */
} ip_mreq;

/* The Type of Service provides an indication of the abstract parameters of the quality of service desired */
#define IPTOS_TOS_MASK    0x1E
#define IPTOS_TOS(tos)    ((tos) & IPTOS_TOS_MASK)
#define IPTOS_LOWDELAY    0x10
#define IPTOS_THROUGHPUT  0x08
#define IPTOS_RELIABILITY 0x04
#define IPTOS_LOWCOST     0x02
#define IPTOS_MINCOST     IPTOS_LOWCOST

/* The Network Control precedence designation is intended to be used within a network only */
#define IPTOS_PREC_MASK            0xe0
#define IPTOS_PREC(tos)            ((tos) & IPTOS_PREC_MASK)
#define IPTOS_PREC_NETCONTROL      0xe0
#define IPTOS_PREC_INTERNETCONTROL 0xc0
#define IPTOS_PREC_CRITIC_ECP      0xa0
#define IPTOS_PREC_FLASHOVERRIDE   0x80
#define IPTOS_PREC_FLASH           0x60
#define IPTOS_PREC_IMMEDIATE       0x40
#define IPTOS_PREC_PRIORITY        0x20
#define IPTOS_PREC_ROUTINE         0x00

#define SCM_RIGHTS      0x01        /* rw: access rights (array of int) */
#define SCM_CREDENTIALS 0x02        /* rw: struct ucred     */
#define SCM_SECURITY    0x03        /* rw: security label       */

/* Options for shatdown type */
#ifndef SHUT_RD
#define SHUT_RD   0
#define SHUT_WR   1
#define SHUT_RDWR 2
#endif

struct sockaddr
{
    uint8_t sa_len;
    sa_family_t sa_family;
    char sa_data[14];
};

/* Structure describing the address of an AF_LOCAL (aka AF_UNIX) socket.  */
struct sockaddr_un
{
    unsigned short sa_family;
    char sun_path[108];         /* Path name.  */
};

#if NETDEV_IPV4
/* members are in network byte order */
struct sockaddr_in
{
    uint8_t sin_len;
    sa_family_t sin_family;
    in_port_t sin_port;
    struct in_addr sin_addr;
#define SIN_ZERO_LEN 8
    char sin_zero[SIN_ZERO_LEN];
};
#endif /* NETDEV_IPV4 */

#if NETDEV_IPV6
struct sockaddr_in6
{
    uint8_t sin6_len;      /* length of this structure    */
    sa_family_t sin6_family;   /* AF_INET6                    */
    in_port_t sin6_port;     /* Transport layer port #      */
    uint32_t sin6_flowinfo; /* IPv6 flow information       */
    struct in6_addr sin6_addr;     /* IPv6 address                */
    uint32_t sin6_scope_id; /* Set of interfaces for scope */
};
#endif /* NETDEV_IPV6 */

struct sockaddr_storage
{
    uint8_t s2_len;
    sa_family_t ss_family;
    char s2_data1[2];
    uint32_t s2_data2[3];
#if NETDEV_IPV6
    uint32_t s2_data3[3];
#endif /* NETDEV_IPV6 */
};

#ifdef RT_USING_MUSLLIBC
#ifndef __DEFINED_struct_iovec
struct iovec
{
    void *iov_base;
    size_t iov_len;
};
#endif
#endif

struct msghdr
{
    void *msg_name;
    socklen_t msg_namelen;
    struct iovec *msg_iov;
    int msg_iovlen;
    void *msg_control;
    socklen_t msg_controllen;
    int msg_flags;
};

/* RFC 3542, Section 20: Ancillary Data */
struct cmsghdr
{
    size_t cmsg_len;   /* number of bytes, including header */
    int cmsg_level; /* originating protocol */
    int cmsg_type;  /* protocol-specific type */
};

#define CMSG_NXTHDR(mhdr, cmsg) cmsg_nxthdr((mhdr), (cmsg))

#define CMSG_ALIGN(len) (((len) + sizeof(long) - 1) & ~(sizeof(long) - 1))

#define CMSG_DATA(cmsg) ((void *)(cmsg) + sizeof(struct cmsghdr))
#define CMSG_SPACE(len) (sizeof(struct cmsghdr) + CMSG_ALIGN(len))
#define CMSG_LEN(len)   (sizeof(struct cmsghdr) + (len))

#define __CMSG_FIRSTHDR(ctl, len) \
    ((len) >= sizeof(struct cmsghdr) ? (struct cmsghdr *)(ctl) : (struct cmsghdr *)NULL)

#define CMSG_FIRSTHDR(msg) __CMSG_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen)
#define CMSG_OK(mhdr, cmsg)                        \
    ((cmsg)->cmsg_len >= sizeof(struct cmsghdr) && \
     (cmsg)->cmsg_len <= (unsigned long)((mhdr)->msg_controllen - ((char *)(cmsg) - (char *)(mhdr)->msg_control)))

#define for_each_cmsghdr(cmsg, msg) \
    for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg))

static inline struct cmsghdr *__cmsg_nxthdr(void *_ctl, size_t _size, struct cmsghdr *_cmsg)
{
    struct cmsghdr *_ptr;

    _ptr = (struct cmsghdr *)(((unsigned char *)_cmsg) + CMSG_ALIGN(_cmsg->cmsg_len));

    if ((unsigned long)((char *)(_ptr + 1) - (char *)_ctl) > _size)
    {
        return (struct cmsghdr *)NULL;
    }

    return _ptr;
}

static inline struct cmsghdr *cmsg_nxthdr(struct msghdr *_msg, struct cmsghdr *_cmsg)
{
    return __cmsg_nxthdr(_msg->msg_control, _msg->msg_controllen, _cmsg);
}

#define IFNAMSIZ 16
struct sal_ifmap
{
    unsigned long int mem_start;
    unsigned long int mem_end;
    unsigned short int base_addr;
    unsigned char irq;
    unsigned char dma;
    unsigned char port;
};

struct sal_ifreq
{
    union
    {
        char ifrn_name[IFNAMSIZ];
    } ifr_ifrn;
    union
    {
        struct sockaddr ifru_addr;
        struct sockaddr ifru_dstaddr;
        struct sockaddr ifru_broadaddr;
        struct sockaddr ifru_netmask;
        struct sockaddr ifru_hwaddr;
        short int ifru_flags;
        int ifru_ivalue;
        int ifru_mtu;
        struct sal_ifmap ifru_map;
        char ifru_slave[IFNAMSIZ];
        char ifru_newname[IFNAMSIZ];
        char *ifru_data;
    } ifr_ifru;
};

int sal_accept(int socket, struct sockaddr *addr, socklen_t *addrlen);
int sal_bind(int socket, const struct sockaddr *name, socklen_t namelen);
int sal_shutdown(int socket, int how);
int sal_getpeername(int socket, struct sockaddr *name, socklen_t *namelen);
int sal_getsockname(int socket, struct sockaddr *name, socklen_t *namelen);
int sal_getsockopt(int socket, int level, int optname, void *optval, socklen_t *optlen);
int sal_setsockopt(int socket, int level, int optname, const void *optval, socklen_t optlen);
int sal_connect(int socket, const struct sockaddr *name, socklen_t namelen);
int sal_listen(int socket, int backlog);
int sal_sendmsg(int socket, const struct msghdr *message, int flags);
int sal_recvmsg(int socket, struct msghdr *message, int flags);
int sal_recvfrom(int socket, void *mem, size_t len, int flags,
                 struct sockaddr *from, socklen_t *fromlen);
int sal_sendto(int socket, const void *dataptr, size_t size, int flags,
               const struct sockaddr *to, socklen_t tolen);
int sal_socket(int domain, int type, int protocol);
int sal_socketpair(int domain, int type, int protocol, int *fds);
int sal_closesocket(int socket);
int sal_ioctlsocket(int socket, long cmd, void *arg);

#ifdef __cplusplus
}
#endif

#endif /* SAL_SOCKET_H__ */