📄 olsrd_httpinfo.c
字号:
/* * HTTP Info plugin for the olsr.org OLSR daemon * Copyright (c) 2004, Andreas T鴑nesen(andreto@olsr.org) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of olsr.org, olsrd nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * Visit http://www.olsr.org for more information. * * If you find this software useful feel free to make a donation * to the project. For more information see the website or contact * the copyright holders. * * $Id: olsrd_httpinfo.c,v 1.80 2007/10/14 22:46:03 bernd67 Exp $ *//* * Dynamic linked library for the olsr.org olsr daemon */#include <stdio.h>#include <string.h>#include <stdlib.h>#include <stdarg.h>#include <unistd.h>#include <errno.h>#ifdef WIN32#include <io.h>#else#include <netdb.h>#endif#include "olsr.h"#include "olsr_cfg.h"#include "interfaces.h"#include "olsr_protocol.h"#include "net_olsr.h"#include "link_set.h"#include "socket_parser.h"#include "olsrd_httpinfo.h"#include "admin_interface.h"#include "html.h"#include "gfx.h"#ifdef OS#undef OS#endif#ifdef WIN32#define close(x) closesocket(x)#define OS "Windows"#endif#ifdef linux#define OS "GNU/Linux"#endif#ifdef __FreeBSD__#define OS "FreeBSD"#endif#ifndef OS#define OS "Undefined"#endifstatic char copyright_string[] __attribute__((unused)) = "olsr.org HTTPINFO plugin Copyright (c) 2004, Andreas T鴑nesen(andreto@olsr.org) All rights reserved.";#define MAX_CLIENTS 3#define MAX_HTTPREQ_SIZE (1024 * 10)#define DEFAULT_TCP_PORT 1978#define HTML_BUFSIZE (1024 * 4000)#define FRAMEWIDTH 800#define FILENREQ_MATCH(req, filename) \ !strcmp(req, filename) || \ (strlen(req) && !strcmp(&req[1], filename))struct tab_entry{ char *tab_label; char *filename; int(*build_body_cb)(char *, olsr_u32_t); olsr_bool display_tab;};struct static_bin_file_entry{ char *filename; unsigned char *data; unsigned int data_size;};struct static_txt_file_entry{ char *filename; const char **data;};struct dynamic_file_entry{ char *filename; int(*process_data_cb)(char *, olsr_u32_t, char *, olsr_u32_t);};static int get_http_socket(int);static int build_tabs(char *, olsr_u32_t, int);static void parse_http_request(int);static int build_http_header(http_header_type, olsr_bool, olsr_u32_t, char *, olsr_u32_t);static int build_frame(char *, olsr_u32_t, char *, char *, int, int(*frame_body_cb)(char *, olsr_u32_t));static int build_routes_body(char *, olsr_u32_t);static int build_config_body(char *, olsr_u32_t);static int build_neigh_body(char *, olsr_u32_t);static int build_topo_body(char *, olsr_u32_t);static int build_mid_body(char *, olsr_u32_t);static int build_nodes_body(char *, olsr_u32_t);static int build_all_body(char *, olsr_u32_t);static int build_about_body(char *, olsr_u32_t);static int build_cfgfile_body(char *, olsr_u32_t);static int check_allowed_ip(const struct allowed_net * const allowed_nets, const union olsr_ip_addr * const addr);static int build_ip_txt(char *buf, const olsr_u32_t bufsize, const olsr_bool want_link, const union olsr_ip_addr * const ipaddr, const int prefix_len);static int build_ipaddr_link(char *buf, const olsr_u32_t bufsize, const olsr_bool want_link, const union olsr_ip_addr * const ipaddr, const int prefix_len);static int section_title(char *buf, olsr_u32_t bufsize, const char *title);static ssize_t writen(int fd, const void *buf, size_t count);static struct timeval start_time;static struct http_stats stats;static int client_sockets[MAX_CLIENTS];static int curr_clients;static int http_socket;#if 0int netsprintf(char *str, const char* format, ...) __attribute__((format(printf, 2, 3)));static int netsprintf_direct = 0;static int netsprintf_error = 0;#define sprintf netsprintf#define NETDIRECT#endifstatic const struct tab_entry tab_entries[] = { {"Configuration", "config", build_config_body, OLSR_TRUE}, {"Routes", "routes", build_routes_body, OLSR_TRUE}, {"Links/Topology", "nodes", build_nodes_body, OLSR_TRUE}, {"All", "all", build_all_body, OLSR_TRUE},#ifdef ADMIN_INTERFACE {"Admin", "admin", build_admin_body, OLSR_TRUE},#endif {"About", "about", build_about_body, OLSR_TRUE}, {"FOO", "cfgfile", build_cfgfile_body, OLSR_FALSE}, {NULL, NULL, NULL, OLSR_FALSE}};static const struct static_bin_file_entry static_bin_files[] = { {"favicon.ico", favicon_ico, 1406/*favicon_ico_len*/}, {"logo.gif", logo_gif, 2801/*logo_gif_len*/}, {"grayline.gif", grayline_gif, 43/*grayline_gif_len*/}, {NULL, NULL, 0}};static const struct static_txt_file_entry static_txt_files[] = { {"httpinfo.css", httpinfo_css}, {NULL, NULL}};static const struct dynamic_file_entry dynamic_files[] = {#ifdef ADMIN_INTERFACE {"set_values", process_set_values},#endif {NULL, NULL} };/** *Do initialization here * *This function is called by the my_init *function in uolsrd_plugin.c */intolsrd_plugin_init(void){ /* Get start time */ gettimeofday(&start_time, NULL); curr_clients = 0; /* set up HTTP socket */ http_socket = get_http_socket(http_port != 0 ? http_port : DEFAULT_TCP_PORT); if(http_socket < 0) { fprintf(stderr, "(HTTPINFO) could not initialize HTTP socket\n"); exit(0); } /* Register socket */ add_olsr_socket(http_socket, &parse_http_request); return 1;}static intget_http_socket(int port){ struct sockaddr_in sin; olsr_u32_t yes = 1; int s; /* Init ipc socket */ if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) { olsr_printf(1, "(HTTPINFO)socket %s\n", strerror(errno)); return -1; } if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&yes, sizeof(yes)) < 0) { olsr_printf(1, "(HTTPINFO)SO_REUSEADDR failed %s\n", strerror(errno)); close(s); return -1; } /* Bind the socket */ /* complete the socket structure */ memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = INADDR_ANY; sin.sin_port = htons(port); /* bind the socket to the port number */ if (bind(s, (struct sockaddr *) &sin, sizeof(sin)) == -1) { olsr_printf(1, "(HTTPINFO) bind failed %s\n", strerror(errno)); close(s); return -1; } /* show that we are willing to listen */ if (listen(s, 1) == -1) { olsr_printf(1, "(HTTPINFO) listen failed %s\n", strerror(errno)); close(s); return -1; } return s;}/* Non reentrant - but we are not multithreaded anyway */voidparse_http_request(int fd){ struct sockaddr_in pin; socklen_t addrlen; char *addr; char req[MAX_HTTPREQ_SIZE]; static char body[HTML_BUFSIZE]; char req_type[11]; char filename[251]; char http_version[11]; int c = 0, r = 1, size = 0; if(curr_clients >= MAX_CLIENTS) return; curr_clients++; addrlen = sizeof(struct sockaddr_in); if ((client_sockets[curr_clients] = accept(fd, (struct sockaddr *) &pin, &addrlen)) == -1) { olsr_printf(1, "(HTTPINFO) accept: %s\n", strerror(errno)); goto close_connection; } if(!check_allowed_ip(allowed_nets, (union olsr_ip_addr *)&pin.sin_addr.s_addr)) { olsr_printf(1, "HTTP request from non-allowed host %s!\n", olsr_ip_to_string((union olsr_ip_addr *)&pin.sin_addr.s_addr)); close(client_sockets[curr_clients]); } addr = inet_ntoa(pin.sin_addr); memset(req, 0, MAX_HTTPREQ_SIZE); memset(body, 0, 1024*10); while((r = recv(client_sockets[curr_clients], &req[c], 1, 0)) > 0 && (c < (MAX_HTTPREQ_SIZE-1))) { c++; if((c > 3 && !strcmp(&req[c-4], "\r\n\r\n")) || (c > 1 && !strcmp(&req[c-2], "\n\n"))) break; } if(r < 0) { olsr_printf(1, "(HTTPINFO) Failed to recieve data from client!\n"); stats.err_hits++; goto close_connection; } /* Get the request */ if(sscanf(req, "%10s %250s %10s\n", req_type, filename, http_version) != 3) { /* Try without HTTP version */ if(sscanf(req, "%10s %250s\n", req_type, filename) != 2) { olsr_printf(1, "(HTTPINFO) Error parsing request %s!\n", req); stats.err_hits++; goto close_connection; } } olsr_printf(1, "Request: %s\nfile: %s\nVersion: %s\n\n", req_type, filename, http_version); if(!strcmp(req_type, "POST")) {#ifdef ADMIN_INTERFACE int i = 0; while(dynamic_files[i].filename) { printf("POST checking %s\n", dynamic_files[i].filename); if(FILENREQ_MATCH(filename, dynamic_files[i].filename)) { olsr_u32_t param_size; stats.ok_hits++; param_size = recv(client_sockets[curr_clients], req, MAX_HTTPREQ_SIZE-1, 0); req[param_size] = '\0'; printf("Dynamic read %d bytes\n", param_size); //memcpy(body, dynamic_files[i].data, static_bin_files[i].data_size); size += dynamic_files[i].process_data_cb(req, param_size, &body[size], sizeof(body)-size); c = build_http_header(HTTP_OK, OLSR_TRUE, size, req, MAX_HTTPREQ_SIZE); goto send_http_data; } i++; }#endif /* We only support GET */ strcpy(body, HTTP_400_MSG); stats.ill_hits++; c = build_http_header(HTTP_BAD_REQ, OLSR_TRUE, strlen(body), req, MAX_HTTPREQ_SIZE); } else if(!strcmp(req_type, "GET")) { int i = 0; int y = 0; while(static_bin_files[i].filename) { if(FILENREQ_MATCH(filename, static_bin_files[i].filename)) break; i++; } if(static_bin_files[i].filename) { stats.ok_hits++; memcpy(body, static_bin_files[i].data, static_bin_files[i].data_size);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -