1 /*
2  * Copyright (C) 2015-2019 Alibaba Group Holding Limited
3  */
4 
5 #include "ulog_api.h"
6 #include "ulog/ulog.h"
7 
8 
9 #if ULOG_POP_UDP_ENABLE
10 
11 #include <string.h>
12 #include <stdlib.h>
13 #include "sys/socket.h"
14 #include "aos/kernel.h"
15 
16 static struct sockaddr_in* syslog_watcher_addr = NULL;
17 static int32_t syslog_watcher_fd = -1;
18 static uint16_t syslog_watcher_port = SYSLOG_WATCHER_DEFAULT_PORT;
19 static uint32_t syslog_watcher_ip_nl = 0x0100007F;
20 static bool     tcpip_service_on = false;
21 
22 /* We have to use sync debug to debug async debug .... */
23 /* #define SESSION_UDP_INFO printf */
24 #define SESSION_UDP_INFO(...)
25 
26 /**
27 * @brief update address for log pop out via udp
28 *       prototype is align to the ulog service mapping(refer ulog_man_handler_service)
29 * @param ip_d ip address of syslog listener, if input 0 then former ip used, MUST BE network byte order
30 * @param port port of syslog listener, is 0 input then before port used. Default is syslog standard 514 used
31 *
32 * @return n.a.
33 *
34 */
on_update_syslog_watcher_addr(const uint32_t ip_nl,const uint32_t port)35 void on_update_syslog_watcher_addr(const uint32_t ip_nl, const uint32_t port)
36 {
37     if (syslog_watcher_addr == NULL) {
38         syslog_watcher_addr = (struct sockaddr_in*)aos_malloc(sizeof(struct sockaddr_in));
39     }
40     if (syslog_watcher_addr != NULL) {
41         memset(syslog_watcher_addr, 0, sizeof(struct sockaddr_in));
42         syslog_watcher_addr->sin_family = AF_INET;
43 
44         if (0xFFFF != (port & 0xFFFF)) {
45             syslog_watcher_port = port;
46             SESSION_UDP_INFO("ulog port %d\n", syslog_watcher_port);
47         }
48         syslog_watcher_addr->sin_port = syslog_watcher_port;
49 
50         if (-1 != ip_nl && 0 != ip_nl) {
51             syslog_watcher_ip_nl = ip_nl;
52             SESSION_UDP_INFO("ulog ip %s\n", inet_ntoa(*(struct in_addr *)(&syslog_watcher_ip_nl)));
53         }
54         syslog_watcher_addr->sin_addr.s_addr = syslog_watcher_ip_nl;
55         SESSION_UDP_INFO("ulog udp ip %s ort %d \r\n", inet_ntoa(*(struct in_addr *)(&syslog_watcher_addr->sin_addr.s_addr)),
56                                 syslog_watcher_addr->sin_port);
57     }
58 }
59 
60 /**
61 * @brief hook function which used notice this module that the tcpip is ready for use
62 *        not thread-safe, but only be used in one task(ulog), so not necessary considering mutex.
63 *        prototype is align to the ulog service mapping(refer ulog_man_handler_service)
64 * @param on
65 * @param off
66 *
67 * @return n.a.
68 *
69 */
on_tcpip_service_on(const uint32_t on,const uint32_t off)70 void on_tcpip_service_on(const uint32_t on, const uint32_t off)
71 {
72     if (on == -1 && off == 1) {
73         /*means turn off syslog pop out*/
74         tcpip_service_on = false;
75         if (syslog_watcher_fd != -1) {
76             close(syslog_watcher_fd);
77             syslog_watcher_fd = -1;
78         }
79     } else if (on == 1 && off == -1) {
80         /*means turn on syslog pop out*/
81         if (NULL == syslog_watcher_addr) {
82             SESSION_UDP_INFO("fail to turn on syslog pop out for syslog server ip info haven't set yet\n");
83             return;
84         }
85 
86         if (syslog_watcher_fd != -1) {
87             SESSION_UDP_INFO("syslog pop out have already started socket\n");
88         } else {
89             syslog_watcher_fd = socket(AF_INET, SOCK_DGRAM, 0);
90             SESSION_UDP_INFO("ulog sys log socket %d\n", syslog_watcher_fd);
91         }
92 
93         tcpip_service_on = true;
94     } else {
95         SESSION_UDP_INFO("ulog sys log start invalid param on %d, off %d\n", on, off);
96     }
97 }
98 
99 /**
100 * @brief not thread-safe, but only be used in one task(ulog), so not necessary considering mutex
101 * @param data
102 * @param len
103 *
104 * @return -1 indicates not send out sucessfully
105 *
106 */
pop_out_on_udp(const char * data,const uint16_t len)107 int32_t pop_out_on_udp(const char* data, const uint16_t len)
108 {
109     int32_t ret = -1;
110     if (tcpip_service_on && syslog_watcher_fd >= 0) {
111         ret = sendto(syslog_watcher_fd, data, len, 0, (struct sockaddr *)syslog_watcher_addr, sizeof(struct sockaddr));
112     }
113     return ret;
114 }
115 
update_net_cli(const char cmd,const char * param)116 void update_net_cli(const char cmd, const char* param)
117 {
118     struct in_addr  listen_addr;
119     uint16_t listen_port = 0x0;
120     char buf[24] = {0};
121     if (param != NULL) {
122         switch (cmd) {
123         case 'a': {
124             inet_aton(param, &listen_addr);
125             snprintf(buf, 24, "listen ip=%u", listen_addr.s_addr);
126             SESSION_UDP_INFO("%s %d ulog set syslog server ip addr %s \r\n", __FILE__, __LINE__, buf);
127             ulog_man(buf);
128         }
129         break;
130 
131         case 'p': {
132             listen_port = strtoul(param, NULL, 10);
133             snprintf(buf, 24, "listen port=%d", listen_port);
134             SESSION_UDP_INFO("%s %d ulog set syslog server ip port %s \r\n", __FILE__, __LINE__, buf);
135             ulog_man(buf);
136         }
137         break;
138 
139         case 'n': {
140             snprintf(buf, 24, "tcpip %s", param);
141             SESSION_UDP_INFO("%s %d ulog set network swtich %s \r\n", __FILE__, __LINE__, buf);
142             ulog_man(buf);
143         }
144         break;
145         default:
146             break;
147         }
148     }
149 }
150 
151 #endif
152 
153