diff --git a/Makefile b/Makefile index ee4ae41..5c58753 100644 --- a/Makefile +++ b/Makefile @@ -28,7 +28,7 @@ create_build_dir: mkdir -p $(BUILDDIR)/httpd SRCS = rtlplayground.c rtl837x_flash.c rtl837x_leds.c rtl837x_phy.c rtl837x_port.c cmd_parser.c html_data.c rtl837x_igmp.c -SRCS += rtl837x_stp.c rtl837x_pins.c dhcp.c machine.c cmd_editor.c rtl837x_bandwidth.c +SRCS += rtl837x_stp.c rtl837x_pins.c dhcp.c machine.c cmd_editor.c rtl837x_bandwidth.c syslog.c SRCS += uip/timer.c uip/uip.c uip/uip_arp.c uip/uiplib.c uip/uip-fw.c uip/uip-neighbor.c uip/uip-split.c SRCS += httpd/httpd.c httpd/page_impl.c OBJS = ${SRCS:%.c=$(BUILDDIR)/%.rel} diff --git a/cmd_parser.c b/cmd_parser.c index 209a689..f225a39 100644 --- a/cmd_parser.c +++ b/cmd_parser.c @@ -41,6 +41,8 @@ extern __xdata char passwd[21]; extern __xdata struct dhcp_state dhcp_state; +extern __xdata uint8_t syslog_enabled; + __xdata uint8_t vlan_names[VLAN_NAMES_SIZE]; __xdata uint16_t vlan_ptr; extern __xdata uint16_t management_vlan; @@ -1198,6 +1200,21 @@ void cmd_parser(void) __banked parse_port(); } else if (cmd_compare(0, "mtu") && cmd_words_b[1] > 0) { parse_mtu(); + } else if (cmd_compare(0, "log")) { + print_string("Logging to UDP.\n"); + uip_len = 100; + for (uint8_t i=0; i 0 && cmd_compare(1, "on")) { + print_string("UDP syslog enabled\n"); + syslog_enabled = 1; + } else { + print_string("UDP syslog disabled\n"); + syslog_enabled = 0; + } } else if (cmd_compare(0, "ip")) { if (cmd_compare(1, "dhcp")) { dhcp_start(); diff --git a/rtlplayground.c b/rtlplayground.c index f0cf525..7baa8cd 100644 --- a/rtlplayground.c +++ b/rtlplayground.c @@ -23,6 +23,7 @@ #include "uip/uip_arp.h" #include "machine.h" #include "phy.h" +#include "syslog.h" extern __code const struct machine machine; extern __xdata uint32_t flash_size; @@ -33,6 +34,12 @@ void crc16(__xdata uint8_t *v) __naked; void flash_default_config(void); void early_boot_handle_button(void); +extern __xdata char logbuf[LOGBUF_SIZE]; +extern __xdata uint16_t logptr_w; +extern __xdata uint8_t full_line_available; +extern __xdata uint8_t syslog_enabled; +extern __xdata char char_to_write; + // See setup_serial_timer1() for valid baudrate settings! #define SERIAL_BAUD_RATE 115200 @@ -185,8 +192,17 @@ void write_char(char c) } tx_buf_empty = 0; SBUF = c; -} + char_to_write = c; + // syslog_write_char(); // why does this gives a linker error? + + if (syslog_enabled) { + logbuf[logptr_w++] = c; + logptr_w &= (LOGBUF_SIZE - 1); + if (c == '\n') + full_line_available = 1; + } +} void itoa(uint8_t v) { @@ -1013,7 +1029,7 @@ void handle_rx(void) if (uip_len) { tcpip_output(); } - } else if (uip_buf[ETHERTYPE_OFFSET] == 0x08 && uip_buf[ETHERTYPE_OFFSET + 1] == 0x00) { // TCP? + } else if (uip_buf[ETHERTYPE_OFFSET] == 0x08 && uip_buf[ETHERTYPE_OFFSET + 1] == 0x00) { // IP? if (!management_vlan || management_vlan == rx_packet_vlan) { uip_arp_ipin(); // Learn MAC addresses in TCP packets uip_input(); @@ -1311,6 +1327,8 @@ void idle(void) cmd_parser(); print_string("\n> "); } + + handle_syslog(); } @@ -2177,6 +2195,7 @@ void main(void) uip_init(); uip_arp_init(); httpd_init(); + syslog_init(); management_vlan = 0; // Disabled @@ -2203,6 +2222,7 @@ void main(void) set_sys_led_state(SYS_LED_ON); cmd_editor_init(); + while (1) { cmd_edit(); idle(); // Enter Idle mode until interrupt occurs diff --git a/syslog.c b/syslog.c new file mode 100644 index 0000000..c28224d --- /dev/null +++ b/syslog.c @@ -0,0 +1,101 @@ +#include "machine.h" +#include "syslog.h" +#include "uip/uip.h" +#include "rtl837x_common.h" + +#pragma codeseg BANK2 +#pragma constseg BANK2 + +#define SYSLOG_O ((__xdata uint8_t *)&uip_buf[RTL_TAG_SIZE + VLAN_TAG_SIZE]) + +__xdata char logbuf[LOGBUF_SIZE]; +__xdata uint16_t logptr_w = 0; +__xdata uint16_t logptr_r = 0; +__xdata uint8_t full_line_available = 0; +__xdata uint8_t syslog_enabled = 0; +__xdata char char_to_write = 0; + +#define DEST_OFFSET (0) +#define SOURCE_OFFSET (DEST_OFFSET + 6) +#define ETHERTYPE_OFFSET (SOURCE_OFFSET + 6) +#define IP_HEADER_OFFSET (ETHERTYPE_OFFSET + 2) +#define UDP_HEADER_OFFSET (IP_HEADER_OFFSET + 20) +#define UDP_PAYLOAD_OFFSET (UDP_HEADER_OFFSET + 8) + +void syslog_init(void) __banked +{ + logptr_r = 0; + logptr_w = 0; + full_line_available = 0; +} + +void syslog_write_char(void) __banked +{ + if (syslog_enabled) { + logbuf[logptr_w++] = char_to_write; + logptr_w &= (LOGBUF_SIZE - 1); + if (char_to_write == '\n') + full_line_available = 1; + } +} + +void handle_syslog(void) __banked +{ + if ((logptr_r != logptr_w) && full_line_available) + { + int16_t log_size = logptr_w - logptr_r; + if (log_size < 0) + log_size += LOGBUF_SIZE; + + if (log_size <= 4) { + // Only some newline; not worth sending to syslog, skip it + logptr_r = logptr_w; + full_line_available = 0; + return; + } + + SYSLOG_O[DEST_OFFSET] = 255; SYSLOG_O[DEST_OFFSET + 1] = 255; SYSLOG_O[DEST_OFFSET + 2] = 255; + SYSLOG_O[DEST_OFFSET + 3] = 255; SYSLOG_O[DEST_OFFSET + 4] = 255; SYSLOG_O[DEST_OFFSET + 5] = 255; // broadcast + memcpy(SYSLOG_O + SOURCE_OFFSET, uip_ethaddr.addr, 6); // Source MAC address +/* + SYSLOG_O[SOURCE_OFFSET] = uip_ethaddr.addr[0]; SYSLOG_O[SOURCE_OFFSET + 1] = uip_ethaddr.addr[1]; + SYSLOG_O[SOURCE_OFFSET + 2] = uip_ethaddr.addr[2]; SYSLOG_O[SOURCE_OFFSET + 3] = uip_ethaddr.addr[3]; + SYSLOG_O[SOURCE_OFFSET + 4] = uip_ethaddr.addr[4]; SYSLOG_O[SOURCE_OFFSET + 5] = uip_ethaddr.addr[5]; +*/ + SYSLOG_O[ETHERTYPE_OFFSET] = 0x08; SYSLOG_O[ETHERTYPE_OFFSET + 1] = 0x00; // Ethertype: IPv4 + + SYSLOG_O[IP_HEADER_OFFSET ] = 0x45; SYSLOG_O[IP_HEADER_OFFSET + 1] = 0x00; // IPv4, no options + SYSLOG_O[IP_HEADER_OFFSET + 2] = (20+8+4+log_size)>>8; SYSLOG_O[IP_HEADER_OFFSET + 3] = (20+8+4+log_size)&0xff; // Total Length + SYSLOG_O[IP_HEADER_OFFSET + 4] = 0x00; SYSLOG_O[IP_HEADER_OFFSET + 5] = 0x00; // Identification + SYSLOG_O[IP_HEADER_OFFSET + 6] = 0x00; SYSLOG_O[IP_HEADER_OFFSET + 7] = 0x00; // Flags, Fragment Offset + SYSLOG_O[IP_HEADER_OFFSET + 8] = 0x40; SYSLOG_O[IP_HEADER_OFFSET + 9] = 0x11; // TTL, Protocol (UDP) + SYSLOG_O[IP_HEADER_OFFSET + 10] = 0x00; SYSLOG_O[IP_HEADER_OFFSET + 11] = 0x00; // Header Checksum (not calculated) + SYSLOG_O[IP_HEADER_OFFSET + 12] = uip_hostaddr[0]&0xff; SYSLOG_O[IP_HEADER_OFFSET + 13] = uip_hostaddr[0]>>8; + SYSLOG_O[IP_HEADER_OFFSET + 14] = uip_hostaddr[1]&0xff; SYSLOG_O[IP_HEADER_OFFSET + 15] = uip_hostaddr[1]>>8; // Source IP + SYSLOG_O[IP_HEADER_OFFSET + 16] = 192; SYSLOG_O[IP_HEADER_OFFSET + 17] = 168; + SYSLOG_O[IP_HEADER_OFFSET + 18] = 10; SYSLOG_O[IP_HEADER_OFFSET + 19] = 240; // Destination IP + + SYSLOG_O[UDP_HEADER_OFFSET ] = 0x02; SYSLOG_O[UDP_HEADER_OFFSET + 1] = 0x02; // Source Port + SYSLOG_O[UDP_HEADER_OFFSET + 2] = 0x02; SYSLOG_O[UDP_HEADER_OFFSET + 3] = 0x02; // Destination Port + SYSLOG_O[UDP_HEADER_OFFSET + 4] = (8+4+log_size)>>8; SYSLOG_O[UDP_HEADER_OFFSET + 5] = (8+4+log_size)&0xff; // Length + SYSLOG_O[UDP_HEADER_OFFSET + 6] = 0x00; SYSLOG_O[UDP_HEADER_OFFSET + 7] = 0x00; // Header Checksum (not calculated) + + memcpyc(SYSLOG_O + UDP_PAYLOAD_OFFSET, "<14>", 4); // Syslog priority prefix + + if (logptr_w < logptr_r) { + memcpy(SYSLOG_O + UDP_PAYLOAD_OFFSET + 4, logbuf + logptr_r, LOGBUF_SIZE - logptr_r); + memcpy(SYSLOG_O + UDP_PAYLOAD_OFFSET + 4 + LOGBUF_SIZE - logptr_r, logbuf, logptr_w); + } else { + memcpy(SYSLOG_O + UDP_PAYLOAD_OFFSET + 4, logbuf + logptr_r, logptr_w - logptr_r); + } + // SYSLOG_O[UDP_PAYLOAD_OFFSET + 4 + log_size - 1] = 0; // Null-terminate the payload + + uip_len = UDP_PAYLOAD_OFFSET+4+log_size; + tcpip_output(); + + logptr_r += log_size; + logptr_r &= (LOGBUF_SIZE - 1); + + full_line_available = 0; + } +} diff --git a/syslog.h b/syslog.h new file mode 100644 index 0000000..c622343 --- /dev/null +++ b/syslog.h @@ -0,0 +1,12 @@ +#ifndef _SYSLOG_H_ +#define _SYSLOG_H_ + +#include + +#define LOGBUF_SIZE 512 + +void syslog_init(void) __banked; +void syslog_write_char(void) __banked; +void handle_syslog(void) __banked; + +#endif diff --git a/uip/uip.c b/uip/uip.c index 40c018c..d50ead7 100644 --- a/uip/uip.c +++ b/uip/uip.c @@ -96,6 +96,8 @@ #include "../rtl837x_common.h" +extern __xdata uint8_t syslog_enabled; + /*---------------------------------------------------------------------------*/ /* Variable definitions. */ @@ -234,7 +236,7 @@ __xdata struct uip_stats uip_stat; #endif /* UIP_STATISTICS == 1 */ #if UIP_LOGGING == 1 -#define UIP_LOG(m) print_string(m) +#define UIP_LOG(m) uint8_t tmp = syslog_enabled; syslog_enabled = 0; print_string(m); syslog_enabled = tmp; #else #define UIP_LOG(m) #endif /* UIP_LOGGING == 1 */