aboutsummaryrefslogtreecommitdiff
path: root/project/dclib/dclib-network-linux.c
diff options
context:
space:
mode:
authorWiimm <wiimm@wiimm.de>2020-11-30 16:16:56 +0100
committerWiimm <wiimm@wiimm.de>2020-11-30 16:16:56 +0100
commit9c0078c6b9c1309b48f9ece8b5cad1b9be9a75c5 (patch)
tree0abd3b6a244076650e40a07e42adae9c2a6b2d8c /project/dclib/dclib-network-linux.c
parenta0815499b2d9014695e6e261c909476729445360 (diff)
SZS v2.21a
Diffstat (limited to '')
-rw-r--r--project/dclib/dclib-network-linux.c105
1 files changed, 105 insertions, 0 deletions
diff --git a/project/dclib/dclib-network-linux.c b/project/dclib/dclib-network-linux.c
index 900714e..b913aa4 100644
--- a/project/dclib/dclib-network-linux.c
+++ b/project/dclib/dclib-network-linux.c
@@ -49,6 +49,111 @@
//
///////////////////////////////////////////////////////////////////////////////
+/////////////// IP/UDP ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+ssize_t ReceiveUDPv4
+(
+ int sock, // valid socket
+ void *buf, // buffer tostore incoming data
+ size_t buf_size, // size of buffer
+ int flags, // flags for recffrom() or recvmsg()
+ struct sockaddr_in *src_addr, // not NULL: store source address
+ in_addr_t *dest_addr // not NULL: store destination IPv4 (NBO)
+)
+{
+ DASSERT(buf);
+
+ if (!dest_addr)
+ {
+ socklen_t src_len = sizeof(*src_addr);
+ return recvfrom( sock, buf, buf_size, flags,
+ (struct sockaddr*)src_addr, &src_len );
+ }
+
+ struct sockaddr_in sa_temp;
+ if (!src_addr)
+ src_addr = &sa_temp;
+
+ *dest_addr = 0;
+ u8 control[CMSG_SPACE(sizeof(struct in_pktinfo))];
+
+ struct iovec iov;
+ iov.iov_base = buf;
+ iov.iov_len = buf_size;
+
+ struct msghdr msg = {0};
+ msg.msg_name = src_addr;
+ msg.msg_namelen = sizeof(*src_addr);
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = control;
+ msg.msg_controllen = sizeof(control);
+
+ ssize_t stat = recvmsg(sock,&msg,flags);
+ if ( stat < 0 )
+ return stat;
+
+ struct cmsghdr *cp;
+ for ( cp = CMSG_FIRSTHDR(&msg); cp; cp = CMSG_NXTHDR(&msg,cp))
+ {
+ if ( cp->cmsg_level == IPPROTO_IP && cp->cmsg_type == IP_PKTINFO )
+ {
+ struct in_pktinfo *pktinfo = (struct in_pktinfo*) CMSG_DATA(cp);
+ *dest_addr = pktinfo->ipi_spec_dst.s_addr;
+ break;
+ }
+ }
+
+ return stat;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+ssize_t SendUDPv4
+(
+ int sock, // valid socket
+ const void *data, // data to send
+ size_t data_size, // size of data
+ int flags, // flags for sendto() or sendmsg()
+ struct sockaddr_in *dest_addr, // destination address (NULL possible)
+ in_addr_t src_addr // not 0: source IPv4 (NBO)
+)
+{
+ DASSERT(data);
+ DASSERT(dest_addr);
+
+ if (!src_addr)
+ return sendto(sock,data,data_size,flags,dest_addr,sizeof(*dest_addr));
+
+ u8 control[CMSG_SPACE(sizeof(struct in_pktinfo))];
+
+ struct iovec iov;
+ iov.iov_base = (void*)data;
+ iov.iov_len = data_size;
+
+ struct msghdr msg = {0};
+ msg.msg_name = dest_addr;
+ msg.msg_namelen = sizeof(*dest_addr);
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = control;
+ msg.msg_controllen = sizeof(control);
+
+ struct cmsghdr *cp = CMSG_FIRSTHDR(&msg);
+ cp->cmsg_level = IPPROTO_IP;
+ cp->cmsg_type = IP_PKTINFO;
+ cp->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
+
+ struct in_pktinfo *pki = (struct in_pktinfo*) CMSG_DATA(cp);
+ pki->ipi_ifindex = 0;
+ pki->ipi_spec_dst.s_addr = src_addr;
+
+ return sendmsg(sock,&msg,flags);
+}
+
+//
+///////////////////////////////////////////////////////////////////////////////
/////////////// SendRawUDP() ///////////////
///////////////////////////////////////////////////////////////////////////////