Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update openssl-server.c #2882

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,7 @@ option(LWS_HTTP_HEADERS_ALL "Override header reduction optimization and include
option(LWS_WITH_SUL_DEBUGGING "Enable zombie lws_sul checking on object deletion" OFF)
option(LWS_WITH_PLUGINS_API "Build generic lws_plugins apis (see LWS_WITH_PLUGINS to also build protocol plugins)" OFF)
option(LWS_WITH_CONMON "Collect introspectable connection latency stats on individual client connections" ON)
option(LWS_WITH_WOL "Wake On Lan support" ON)
option(LWS_WITHOUT_EVENTFD "Force using pipe instead of eventfd" OFF)
if (UNIX OR WIN32)
option(LWS_WITH_CACHE_NSCOOKIEJAR "Build file-backed lws-cache-ttl that uses netscape cookie jar format (linux-only)" ON)
Expand Down
12 changes: 12 additions & 0 deletions include/libwebsockets/lws-misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -1250,3 +1250,15 @@ lws_minilex_parse(const uint8_t *lex, int16_t *ps, const uint8_t c,

LWS_VISIBLE LWS_EXTERN unsigned int
lws_sigbits(uintptr_t u);

/**
* lws_wol() - broadcast a magic WOL packet to MAC, optionally binding to if IP
*
* \p ctx: The lws context
* \p ip_or_NULL: The IP address to bind to at the client side, to send the
* magic packet on. If NULL, the system chooses, probably the
* interface with the default route.
* \p mac_6_bytes: Points to a 6-byte MAC address to direct the magic packet to
*/
LWS_VISIBLE LWS_EXTERN int
lws_wol(struct lws_context *ctx, const char *ip_or_NULL, uint8_t *mac_6_bytes);
14 changes: 13 additions & 1 deletion include/libwebsockets/lws-network-helper.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2020 Andy Green <[email protected]>
* Copyright (C) 2010 - 2023 Andy Green <[email protected]>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
Expand Down Expand Up @@ -246,4 +246,16 @@ lws_write_numeric_address(const uint8_t *ads, int size, char *buf, size_t len);
LWS_VISIBLE LWS_EXTERN int
lws_sa46_write_numeric_address(lws_sockaddr46 *sa46, char *buf, size_t len);

/**
* lws_parse_mac() - convert XX:XX:XX:XX:XX:XX to 6-byte MAC address
*
* \param ads: mac address as XX:XX:XX:XX:XX:XX string
* \param result_6_bytes: result buffer to take 6 bytes
*
* Converts a string representation of a 6-byte hex mac address to a 6-byte
* array.
*/
LWS_VISIBLE LWS_EXTERN int
lws_parse_mac(const char *ads, uint8_t *result_6_bytes);

///@}
5 changes: 5 additions & 0 deletions lib/core-net/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ if (LWS_WITH_LWS_DSH)
core-net/lws-dsh.c)
endif()

if (LWS_WITH_WOL)
list(APPEND SOURCES
core-net/wol.c)
endif()

if (LWS_WITH_CLIENT)
list(APPEND SOURCES
core-net/client/client.c
Expand Down
59 changes: 59 additions & 0 deletions lib/core-net/network.c
Original file line number Diff line number Diff line change
Expand Up @@ -1104,3 +1104,62 @@ lws_system_get_state_manager(struct lws_context *context)
return &context->mgr_system;
}
#endif

int
lws_parse_mac(const char *ads, uint8_t *result_6_bytes)
{
uint8_t *p = result_6_bytes;
struct lws_tokenize ts;
char t[3];
size_t n;
long u;

lws_tokenize_init(&ts, ads, LWS_TOKENIZE_F_NO_INTEGERS |
LWS_TOKENIZE_F_MINUS_NONTERM);
ts.len = strlen(ads);

do {
ts.e = (int8_t)lws_tokenize(&ts);
switch (ts.e) {
case LWS_TOKZE_TOKEN:
if (ts.token_len != 2)
return -1;
if (p - result_6_bytes == 6)
return -2;
t[0] = ts.token[0];
t[1] = ts.token[1];
t[2] = '\0';
for (n = 0; n < 2; n++)
if (t[n] < '0' || t[n] > 'f' ||
(t[n] > '9' && t[n] < 'A') ||
(t[n] > 'F' && t[n] < 'a'))
return -1;
u = strtol(t, NULL, 16);
if (u > 0xff)
return -5;
*p++ = (uint8_t)u;
break;

case LWS_TOKZE_DELIMITER:
if (*ts.token != ':')
return -10;
if (p - result_6_bytes > 5)
return -11;
break;

case LWS_TOKZE_ENDED:
if (p - result_6_bytes != 6)
return -12;
return 0;

default:
lwsl_err("%s: malformed mac\n", __func__);

return -13;
}
} while (ts.e > 0);

lwsl_err("%s: ended on e %d\n", __func__, ts.e);

return -14;
}
84 changes: 84 additions & 0 deletions lib/core-net/wol.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* libwebsockets - small server side websockets and web server implementation
*
* Copyright (C) 2010 - 2023 Andy Green <[email protected]>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/

#include "private-lib-core.h"

int
lws_wol(struct lws_context *ctx, const char *ip_or_NULL, uint8_t *mac_6_bytes)
{
int n, m, ofs = 0, fd, optval = 1, ret = 1;
uint8_t pkt[17 * IFHWADDRLEN];
struct sockaddr_in addr;

fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (fd < 0) {
lwsl_cx_err(ctx, "failed to open UDP, errno %d\n", errno);
goto bail;
}

if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST,
(char *)&optval, sizeof(optval)) < 0) {
lwsl_cx_err(ctx, "failed to set broadcast, errno %d\n", errno);
goto bail;
}

/*
* Lay out the magic packet
*/

for (n = 0; n < IFHWADDRLEN; n++)
pkt[ofs++] = 0xff;
for (m = 0; m < 16; m++)
for (n = 0; n < IFHWADDRLEN; n++)
pkt[ofs++] = mac_6_bytes[n];

memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(9);

if (!inet_aton(ip_or_NULL ? ip_or_NULL : "255.255.255.255",
&addr.sin_addr)) {
lwsl_cx_err(ctx, "failed to convert broadcast ads, errno %d\n",
errno);
goto bail;
}

lwsl_cx_notice(ctx, "Sending WOL to %02X:%02X:%02X:%02X:%02X:%02X %s\n",
mac_6_bytes[0], mac_6_bytes[1], mac_6_bytes[2], mac_6_bytes[3],
mac_6_bytes[4], mac_6_bytes[5], ip_or_NULL ? ip_or_NULL : "");

if (sendto(fd, pkt, sizeof(pkt), 0, (struct sockaddr *)&addr,
sizeof(addr)) < 0) {
lwsl_cx_err(ctx, "failed to sendto broadcast ads, errno %d\n",
errno);
goto bail;
}

ret = 0;

bail:
close(fd);

return ret;
}
4 changes: 3 additions & 1 deletion lib/core/buflist.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ lws_buflist_append_segment(struct lws_buflist **head, const uint8_t *buf,
void *p = *head;
int sanity = 1024;

assert(buf);
if (!buf)
return -1;

assert(len);

/* append at the tail */
Expand Down
2 changes: 1 addition & 1 deletion lib/misc/base64-decode.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ lws_b64_decode_stateful(struct lws_b64state *s, const char *in, size_t *in_len,
uint8_t *orig_out = out, *end_out = out + *out_size;
int equals = 0;

while (in < end_in && *in && out + 4 < end_out) {
while (in < end_in && *in && out + 3 <= end_out) {

for (; s->i < 4 && in < end_in && *in; s->i++) {
uint8_t v;
Expand Down
2 changes: 1 addition & 1 deletion lib/roles/h2/http2.c
Original file line number Diff line number Diff line change
Expand Up @@ -2816,7 +2816,6 @@ int
lws_read_h2(struct lws *wsi, unsigned char *buf, lws_filepos_t len)
{
unsigned char *oldbuf = buf;
lws_filepos_t body_chunk_len;

// lwsl_notice("%s: h2 path: wsistate 0x%x len %d\n", __func__,
// wsi->wsistate, (int)len);
Expand All @@ -2832,6 +2831,7 @@ lws_read_h2(struct lws *wsi, unsigned char *buf, lws_filepos_t len)
* case.
*/
while (len) {
lws_filepos_t body_chunk_len = 0;
int m;

/*
Expand Down
1 change: 1 addition & 0 deletions lib/roles/ws/client-parser-ws.c
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,7 @@ int lws_ws_client_rx_sm(struct lws *wsi, unsigned char c)

if (n == PMDR_DID_NOTHING
#if !defined(LWS_WITHOUT_EXTENSIONS)
|| n == PMDR_NOTHING_WE_SHOULD_DO
|| n == PMDR_UNKNOWN
#endif
)
Expand Down
35 changes: 35 additions & 0 deletions minimal-examples-lowlevel/api-tests/api-test-async-dns/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,7 @@ main(int argc, const char **argv)
{
int n = 1, logs = LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE;
struct lws_context_creation_info info;
uint8_t mac[6];
const char *p;

/* fixup dynamic target addresses we're testing against */
Expand Down Expand Up @@ -517,6 +518,40 @@ main(int argc, const char **argv)
ok++;
}

/* mac address parser tests */

if (lws_parse_mac("11:ff:ce:CE:22:33", mac)) {
lwsl_err("%s: mac fail 1\n", __func__);
lwsl_hexdump_notice(mac, 6);
fail++;
} else
if (mac[0] != 0x11 || mac[1] != 0xff || mac[2] != 0xce ||
mac[3] != 0xce || mac[4] != 0x22 || mac[5] != 0x33) {
lwsl_err("%s: mac fail 2\n", __func__);
lwsl_hexdump_notice(mac, 6);
fail++;
}
if (!lws_parse_mac("11:ff:ce:CE:22:3", mac)) {
lwsl_err("%s: mac fail 3\n", __func__);
lwsl_hexdump_notice(mac, 6);
fail++;
}
if (!lws_parse_mac("11:ff:ce:CE:22", mac)) {
lwsl_err("%s: mac fail 4\n", __func__);
lwsl_hexdump_notice(mac, 6);
fail++;
}
if (!lws_parse_mac("11:ff:ce:CE:22:", mac)) {
lwsl_err("%s: mac fail 5\n", __func__);
lwsl_hexdump_notice(mac, 6);
fail++;
}
if (!lws_parse_mac("11:ff:ce:CE22", mac)) {
lwsl_err("%s: mac fail 6\n", __func__);
lwsl_hexdump_notice(mac, 6);
fail++;
}

#if !defined(LWS_WITH_IPV6)
_exp -= 2;
#endif
Expand Down
23 changes: 23 additions & 0 deletions minimal-examples-lowlevel/raw/minimal-raw-wol/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
project(lws-minimal-raw-wol C)
cmake_minimum_required(VERSION 3.6)
find_package(libwebsockets CONFIG REQUIRED)
list(APPEND CMAKE_MODULE_PATH ${LWS_CMAKE_DIR})
include(CheckCSourceCompiles)
include(LwsCheckRequirements)

set(SAMP lws-minimal-raw-wol)
set(SRCS minimal-raw-wol.c)

set(requirements 1)
require_lws_config(LWS_WITH_WOL 1 requirements)

if (requirements)
add_executable(${SAMP} ${SRCS})

if (websockets_shared)
target_link_libraries(${SAMP} websockets_shared ${LIBWEBSOCKETS_DEP_LIBS})
add_dependencies(${SAMP} websockets_shared)
else()
target_link_libraries(${SAMP} websockets ${LIBWEBSOCKETS_DEP_LIBS})
endif()
endif()
34 changes: 34 additions & 0 deletions minimal-examples-lowlevel/raw/minimal-raw-wol/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# lws minimal raw wol

This example shows how to send a Wake On Lan magic packet to a given mac.

## build

```
$ cmake . && make
```

## usage

```
$ bin/lws-minimal-raw-wol b4:2e:99:a9:22:90
[2023/11/09 12:25:24:2255] N: lws_create_context: LWS: 4.3.99-v4.3.0-295-g60d671c7, NET CLI SRV H1 H2 WS SS-JSON-POL ConMon ASYNC_DNS IPv6-absent
[2023/11/09 12:25:24:2256] N: __lws_lc_tag: ++ [wsi|0|pipe] (1)
[2023/11/09 12:25:24:2256] N: __lws_lc_tag: ++ [vh|0|netlink] (1)
[2023/11/09 12:25:24:2256] N: __lws_lc_tag: ++ [vh|1|system||-1] (2)
[2023/11/09 12:25:24:2257] N: __lws_lc_tag: ++ [wsisrv|0|system|asyncdns] (1)
[2023/11/09 12:25:24:2257] N: __lws_lc_tag: ++ [wsisrv|1|system|asyncdns] (2)
[2023/11/09 12:25:24:2257] N: __lws_lc_tag: ++ [vh|2|default||0] (3)
[2023/11/09 12:25:24:2257] N: [vh|2|default||0]: lws_socket_bind: source ads 0.0.0.0
[2023/11/09 12:25:24:2257] N: __lws_lc_tag: ++ [wsi|1|listen|default||33749] (2)
[2023/11/09 12:25:24:2257] N: lws_wol: Sending WOL to B4:2E:99:A9:22:90
[2023/11/09 12:25:24:2258] N: __lws_lc_untag: -- [wsi|0|pipe] (1) 190μs
[2023/11/09 12:25:24:2258] N: __lws_lc_untag: -- [wsi|1|listen|default||33749] (0) 80μs
[2023/11/09 12:25:24:2258] N: __lws_lc_untag: -- [wsisrv|1|system|asyncdns] (1) 118μs
[2023/11/09 12:25:24:2258] N: __lws_lc_untag: -- [wsisrv|0|system|asyncdns] (0) 155μs
[2023/11/09 12:25:24:2258] N: __lws_lc_untag: -- [vh|0|netlink] (2) 198μs
[2023/11/09 12:25:24:2258] N: __lws_lc_untag: -- [vh|1|system||-1] (1) 182μs
[2023/11/09 12:25:24:2258] N: __lws_lc_untag: -- [vh|2|default||0] (0) 125μs

$
```
Loading