1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Log to syslog. 4 * 5 * Copyright (c) 2020, Heinrich Schuchardt <xypron.glpk@gmx.de> 6 */ 7 8#include <common.h> 9#include <log.h> 10#include <net.h> 11#include <asm/global_data.h> 12 13DECLARE_GLOBAL_DATA_PTR; 14 15#define BUFFER_SIZE 480 16 17static void append(char **buf, char *buf_end, const char *fmt, ...) 18{ 19 va_list args; 20 size_t size = buf_end - *buf; 21 22 va_start(args, fmt); 23 vsnprintf(*buf, size, fmt, args); 24 va_end(args); 25 *buf += strlen(*buf); 26} 27 28static int log_syslog_emit(struct log_device *ldev, struct log_rec *rec) 29{ 30 int ret; 31 int fmt = gd->log_fmt; 32 char msg[BUFFER_SIZE]; 33 char *msg_end = msg + BUFFER_SIZE; 34 char *ptr = msg; 35 char *iphdr; 36 char *log_msg; 37 int eth_hdr_size; 38 struct in_addr bcast_ip; 39 unsigned int log_level; 40 char *log_hostname; 41 42 /* Setup packet buffers */ 43 ret = net_init(); 44 if (ret) 45 return ret; 46 /* Disable hardware and put it into the reset state */ 47 eth_halt(); 48 /* Set current device according to environment variables */ 49 eth_set_current(); 50 /* Get hardware ready for send and receive operations */ 51 ret = eth_init(); 52 if (ret < 0) { 53 eth_halt(); 54 goto out; 55 } 56 57 memset(msg, 0, BUFFER_SIZE); 58 59 /* Set ethernet header */ 60 eth_hdr_size = net_set_ether((uchar *)ptr, net_bcast_ethaddr, PROT_IP); 61 ptr += eth_hdr_size; 62 iphdr = ptr; 63 ptr += IP_UDP_HDR_SIZE; 64 log_msg = ptr; 65 66 /* 67 * The syslog log levels defined in RFC 5424 match the U-Boot ones up to 68 * level 7 (debug). 69 */ 70 log_level = rec->level; 71 if (log_level > 7) 72 log_level = 7; 73 /* Leave high bits as 0 to write a 'kernel message' */ 74 75 /* Write log message to buffer */ 76 append(&ptr, msg_end, "<%u>", log_level); 77 log_hostname = env_get("log_hostname"); 78 if (log_hostname) 79 append(&ptr, msg_end, "%s ", log_hostname); 80 append(&ptr, msg_end, "uboot: "); 81 if (fmt & BIT(LOGF_LEVEL)) 82 append(&ptr, msg_end, "%s.", 83 log_get_level_name(rec->level)); 84 if (fmt & BIT(LOGF_CAT)) 85 append(&ptr, msg_end, "%s,", 86 log_get_cat_name(rec->cat)); 87 if (fmt & BIT(LOGF_FILE)) 88 append(&ptr, msg_end, "%s:", rec->file); 89 if (fmt & BIT(LOGF_LINE)) 90 append(&ptr, msg_end, "%d-", rec->line); 91 if (fmt & BIT(LOGF_FUNC)) 92 append(&ptr, msg_end, "%s()", rec->func); 93 if (fmt & BIT(LOGF_MSG)) 94 append(&ptr, msg_end, "%s%s", 95 fmt != BIT(LOGF_MSG) ? " " : "", rec->msg); 96 /* Consider trailing 0x00 */ 97 ptr++; 98 99 debug("log message: '%s'\n", log_msg); 100 101 /* Broadcast message */ 102 bcast_ip.s_addr = 0xFFFFFFFFL; 103 net_set_udp_header((uchar *)iphdr, bcast_ip, 514, 514, ptr - log_msg); 104 net_send_packet((uchar *)msg, ptr - msg); 105 106out: 107 return ret; 108} 109 110LOG_DRIVER(syslog) = { 111 .name = "syslog", 112 .emit = log_syslog_emit, 113}; 114