diff options
Diffstat (limited to 'contrib')
27 files changed, 0 insertions, 6926 deletions
diff --git a/contrib/fwd/Makefile b/contrib/fwd/Makefile deleted file mode 100644 index f7fac7740..000000000 --- a/contrib/fwd/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -include ../../build/config.mk -include ../../build/module.mk diff --git a/contrib/fwd/src/Makefile b/contrib/fwd/src/Makefile deleted file mode 100644 index 43749124a..000000000 --- a/contrib/fwd/src/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -CFLAGS := -ggdb3 -O0 -Wall -I./uci -I./iptables-1.4.5/include -LDFLAGS := -luci -liptc -lxtables -ldl -L./iptables-1.4.5/libiptc/.libs -L./iptables-1.4.5/.libs -Wl,--export-dynamic - -fwd: - $(CC) $(CFLAGS) -c -o ucix.o ucix.c - $(CC) $(CFLAGS) -c -o fwd_addr.o fwd_addr.c - $(CC) $(CFLAGS) -c -o fwd_rules.o fwd_rules.c - $(CC) $(CFLAGS) -c -o fwd_config.o fwd_config.c - $(CC) $(CFLAGS) -c -o fwd_xtables.o fwd_xtables.c - $(CC) $(CFLAGS) -c -o fwd_ipc.o fwd_ipc.c - $(CC) $(CFLAGS) -c -o fwd_utils.o fwd_utils.c - $(CC) $(CFLAGS) -c -o fwd.o fwd.c - $(CC) $(LDFLAGS) -o fwd fwd.o fwd_addr.o fwd_rules.o fwd_config.o fwd_xtables.o fwd_ipc.o fwd_utils.o ucix.o - ln -s fwd fw - -clean: - rm -f *~ fwd fw *.o - diff --git a/contrib/fwd/src/fwd.c b/contrib/fwd/src/fwd.c deleted file mode 100644 index 662524e35..000000000 --- a/contrib/fwd/src/fwd.c +++ /dev/null @@ -1,320 +0,0 @@ -/* - * fwd - OpenWrt firewall daemon - main part - * - * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org> - * - * The fwd program is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * The fwd program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with the fwd program. If not, see http://www.gnu.org/licenses/. - */ - - -#include "fwd.h" -#include "fwd_addr.h" -#include "fwd_rules.h" -#include "fwd_config.h" -#include "fwd_xtables.h" -#include "fwd_ipc.h" -#include "fwd_utils.h" - - -static void fwd_foreach_network( - struct fwd_handle *h, - void (*cb)(struct fwd_handle *h, struct fwd_network *net) -) { - struct fwd_data *data; - struct fwd_network *net; - - for( data = h->conf; data; data = data->next ) - { - if( data->type != FWD_S_ZONE ) - continue; - - for( net = data->section.zone.networks; net; net = net->next ) - cb(h, net); - } -} - -static void fwd_addif_all_cb(struct fwd_handle *h, struct fwd_network *net) -{ - fwd_ipt_addif(h, net->name); -} - -static void fwd_delif_all_cb(struct fwd_handle *h, struct fwd_network *net) -{ - fwd_ipt_delif(h, net->name); -} - -#define fwd_addif_all(h) fwd_foreach_network(h, fwd_addif_all_cb) -#define fwd_delif_all(h) fwd_foreach_network(h, fwd_delif_all_cb) - - -static int fwd_server_main(int argc, const char *argv[]) -{ - struct fwd_handle *h; - struct fwd_network *net; - struct fwd_addr *addrs; - struct fwd_data *data; - struct fwd_cidr *addr_old, *addr_new; - struct sigaction sa; - int unix_client; - - sa.sa_handler = SIG_IGN; - sigaction(SIGPIPE, &sa, NULL); - - if( getuid() > 0 ) - fwd_fatal("Need root permissions!"); - - if( !(h = fwd_alloc_ptr(struct fwd_handle)) ) - fwd_fatal("Out of memory"); - - if( (h->rtnl_socket = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) == -1 ) - fwd_fatal("Failed to create AF_NETLINK socket (%m)"); - - if( (h->unix_socket = fwd_ipc_listen()) == -1 ) - fwd_fatal("Failed to create AF_UNIX socket (%m)"); - - if( !(h->conf = fwd_read_config(h)) ) - fwd_fatal("Failed to read configuration"); - - fwd_log_init(); - - fwd_ipt_build_ruleset(h); - fwd_addif_all(h); - - while(1) - { - if( (addrs = fwd_get_addrs(h->rtnl_socket, AF_INET)) != NULL ) - { - for( data = h->conf; data; data = data->next ) - { - if( data->type != FWD_S_ZONE ) - continue; - - for( net = data->section.zone.networks; net; net = net->next ) - { - addr_new = fwd_lookup_addr(addrs, net->ifname); - addr_old = net->addr; - - if( !fwd_empty_cidr(addr_new) && fwd_empty_cidr(addr_old) ) - { - fwd_log_info( - "Interface %s brought up - adding rules", - net->ifname - ); - - fwd_update_cidr(addr_old, addr_new); - fwd_ipt_addif(h, net->name); - } - else if( fwd_empty_cidr(addr_new) && !fwd_empty_cidr(addr_old) ) - { - fwd_log_info( - "Interface %s went down - removing rules", - net->ifname - ); - - fwd_update_cidr(addr_old, NULL); - fwd_ipt_delif(h, net->name); - } - else if( ! fwd_equal_cidr(addr_old, addr_new) ) - { - fwd_log_info( - "Interface %s changed IP - rebuilding rules", - net->ifname - ); - - fwd_update_cidr(addr_old, addr_new); - fwd_ipt_chgif(h, net->name); - } - } - } - - fwd_free_addrs(addrs); - } - - - if( (unix_client = fwd_ipc_accept(h->unix_socket)) > -1 ) - { - struct fwd_ipc_msg msg; - memset(&msg, 0, sizeof(struct fwd_ipc_msg)); - - while( fwd_ipc_recvmsg(unix_client, &msg, sizeof(struct fwd_ipc_msg)) > 0 ) - { - fwd_log_info("Got message [%i]", msg.type); - - switch(msg.type) - { - case FWD_IPC_FLUSH: - fwd_log_info("Flushing rules ..."); - fwd_ipt_clear_ruleset(h); - fwd_ipc_sendtype(unix_client, FWD_IPC_OK); - break; - - case FWD_IPC_BUILD: - fwd_log_info("Building rules ..."); - fwd_ipt_clear_ruleset(h); - fwd_ipt_build_ruleset(h); - fwd_addif_all(h); - fwd_ipc_sendtype(unix_client, FWD_IPC_OK); - break; - - case FWD_IPC_RELOAD: - if( (data = fwd_read_config(h)) != NULL ) - { - fwd_log_info("Flushing rules ..."); - fwd_ipt_clear_ruleset(h); - fwd_free_config(h->conf); - h->conf = data; - fwd_log_info("Building rules ..."); - fwd_ipt_build_ruleset(h); - fwd_addif_all(h); - fwd_ipc_sendtype(unix_client, FWD_IPC_OK); - } - else - { - fwd_log_err("Cannot reload configuration!"); - fwd_ipc_sendtype(unix_client, FWD_IPC_ERROR); - } - break; - - case FWD_IPC_ADDIF: - case FWD_IPC_DELIF: - if( strlen(msg.data.network) > 0 ) - { - fwd_ipt_delif(h, msg.data.network); - - if( msg.type == FWD_IPC_ADDIF ) - fwd_ipt_addif(h, msg.data.network); - - fwd_ipc_sendtype(unix_client, FWD_IPC_OK); - } - else - { - fwd_log_err("No network name provided!"); - fwd_ipc_sendtype(unix_client, FWD_IPC_ERROR); - } - break; - - case FWD_IPC_OK: - case FWD_IPC_ERROR: - break; - } - } - - fwd_ipc_shutdown(unix_client); - } - - - sleep(1); - } - - fwd_delif_all(h); - fwd_ipt_clear_ruleset(h); - - close(h->rtnl_socket); - fwd_free_config(h->conf); - fwd_free_ptr(h); - - return 0; -} - -static void fwd_client_usage(const char *msg) -{ - printf( - "%s\n\n" - "Usage:\n" - " fw flush\n" - " Flush all rules in the firewall and reset policy\n\n" - " fw build\n" - " Rebuild firewall rules\n\n" - " fw reload\n" - " Reload configuration and rebuild firewall rules\n\n" - " fw addif {network}\n" - " Add rules for given network\n\n" - " fw delif {network}\n" - " Remove rules for given network\n\n" - "", msg - ); - - exit(1); -} - -static int fwd_client_main(int argc, const char *argv[]) -{ - int unix_server; - struct fwd_ipc_msg msg; - enum fwd_ipc_msgtype type; - - if( argc < 2 ) - fwd_client_usage("Command required"); - - if( (unix_server = fwd_ipc_connect()) < 0 ) - fwd_fatal("Cannot connect to server instance (%m)"); - - - memset(&msg, 0, sizeof(struct fwd_ipc_msg)); - - if( !strcmp(argv[1], "flush") ) - type = FWD_IPC_FLUSH; - - else if( !strcmp(argv[1], "build") ) - type = FWD_IPC_BUILD; - - else if( !strcmp(argv[1], "reload") ) - type = FWD_IPC_RELOAD; - - else if( !strcmp(argv[1], "addif") || !strcmp(argv[1], "delif") ) - { - if( argc < 3 ) - fwd_client_usage("The command requires a parameter."); - - type = strcmp(argv[1], "addif") ? FWD_IPC_DELIF : FWD_IPC_ADDIF; - strncpy(msg.data.network, argv[2], sizeof(msg.data.network)); - } - - else - fwd_client_usage("Invalid command given."); - - msg.type = type; - fwd_ipc_sendmsg(unix_server, &msg, sizeof(struct fwd_ipc_msg)); - - memset(&msg, 0, sizeof(struct fwd_ipc_msg)); - - while( fwd_ipc_recvmsg(unix_server, &msg, sizeof(struct fwd_ipc_msg)) == 0 ) - continue; - - switch(msg.type) - { - case FWD_IPC_OK: - printf("Success\n"); - break; - - case FWD_IPC_ERROR: - printf("The server reported an error, check logread!\n"); - break; - - default: - fwd_fatal("Unexpected response type %i", msg.type); - } - - fwd_ipc_shutdown(unix_server); - - return 0; -} - -int main(int argc, const char *argv[]) -{ - if( strstr(argv[0], "fwd") ) - return fwd_server_main(argc, argv); - else - return fwd_client_main(argc, argv); -} - diff --git a/contrib/fwd/src/fwd.h b/contrib/fwd/src/fwd.h deleted file mode 100644 index 6de8b880c..000000000 --- a/contrib/fwd/src/fwd.h +++ /dev/null @@ -1,182 +0,0 @@ -/* - * fwd - OpenWrt firewall daemon - data structures - * - * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org> - * - * The fwd program is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * The fwd program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with the fwd program. If not, see http://www.gnu.org/licenses/. - */ - -#ifndef __FWD_H__ -#define __FWD_H__ - -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <stdarg.h> -#include <stdlib.h> -#include <getopt.h> -#include <signal.h> -#include <netinet/in.h> - - -enum fwd_policy { - FWD_P_UNSPEC = 0, - FWD_P_DROP = 1, - FWD_P_REJECT = 2, - FWD_P_ACCEPT = 3 -}; - -enum fwd_stype { - FWD_S_DEFAULTS = 0, - FWD_S_ZONE = 1, - FWD_S_FORWARD = 2, - FWD_S_REDIRECT = 3, - FWD_S_RULE = 4, - FWD_S_INCLUDE = 5 -}; - -enum fwd_ptype { - FWD_PR_CUSTOM = 0, - FWD_PR_TCP = 1, - FWD_PR_UDP = 2, - FWD_PR_TCPUDP = 3, - FWD_PR_ICMP = 4, - FWD_PR_ALL = 5 -}; - -struct fwd_portrange { - unsigned short min; - unsigned short max; -}; - -struct fwd_cidr { - struct in_addr addr; - int prefix; -}; - -struct fwd_mac { - unsigned char mac[6]; -}; - -struct fwd_proto { - enum fwd_ptype type; - int proto; -}; - -struct fwd_icmptype { - char name[32]; - int type; - int code; -}; - -struct fwd_network { - char *name; - char *ifname; - int isalias; - struct fwd_cidr *addr; - struct fwd_network *next; -}; - -struct fwd_defaults { - enum fwd_policy input; - enum fwd_policy forward; - enum fwd_policy output; - int syn_flood; - int syn_rate; - int syn_burst; - int drop_invalid; -}; - -struct fwd_zone { - char *name; - struct fwd_network *networks; - struct fwd_data *forwardings; - struct fwd_data *redirects; - struct fwd_data *rules; - enum fwd_policy input; - enum fwd_policy forward; - enum fwd_policy output; - int masq; - int mtu_fix; - int conntrack; -}; - -struct fwd_forwarding { - struct fwd_zone *src; - struct fwd_zone *dest; - int mtu_fix; /* legacy */ - int masq; /* new */ -}; - -struct fwd_redirect { - struct fwd_zone *src; - struct fwd_cidr *src_ip; - struct fwd_mac *src_mac; - struct fwd_portrange *src_port; - struct fwd_portrange *src_dport; - struct fwd_cidr *dest_ip; - struct fwd_portrange *dest_port; - struct fwd_proto *proto; - int clone; /* true if rule is cloned (tcpudp -> tcp + udp) */ -}; - -struct fwd_rule { - struct fwd_zone *src; - struct fwd_zone *dest; - struct fwd_cidr *src_ip; - struct fwd_mac *src_mac; - struct fwd_portrange *src_port; - struct fwd_cidr *dest_ip; - struct fwd_portrange *dest_port; - struct fwd_proto *proto; - struct fwd_icmptype *icmp_type; - enum fwd_policy target; - int clone; /* true if rule is cloned (tcpudp -> tcp + udp) */ -}; - -struct fwd_include { - char *path; -}; - -struct fwd_data { - enum fwd_stype type; - struct fwd_data *next; - union { - struct fwd_defaults defaults; - struct fwd_zone zone; - struct fwd_forwarding forwarding; - struct fwd_redirect redirect; - struct fwd_rule rule; - struct fwd_include include; - } section; -}; - - -struct fwd_handle { - int rtnl_socket; - int unix_socket; - struct fwd_data *conf; -}; - - -/* fwd_fatal(fmt, ...) - * Prints message to stderr and termintes program. */ -#define fwd_fatal(...) do { \ - fprintf(stderr, "ERROR: "); \ - fprintf(stderr, __VA_ARGS__); \ - fprintf(stderr, "\n"); \ - exit(1); \ -} while(0) - - -#endif diff --git a/contrib/fwd/src/fwd_addr.c b/contrib/fwd/src/fwd_addr.c deleted file mode 100644 index 62e65aa62..000000000 --- a/contrib/fwd/src/fwd_addr.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * fwd - OpenWrt firewall daemon - rtnetlink communication - * - * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org> - * - * The fwd program is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * The fwd program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with the fwd program. If not, see http://www.gnu.org/licenses/. - */ - - -#include "fwd.h" -#include "fwd_addr.h" -#include "fwd_utils.h" - -struct fwd_addr * fwd_get_addrs(int fd, int family) -{ - struct { - struct nlmsghdr n; - struct ifaddrmsg r; - } req; - - int offlen; - int rtattrlen; - int dump_done; - char buf[16384]; - - struct rtattr *rta; - struct rtattr *rtatp; - struct nlmsghdr *nlmp; - struct ifaddrmsg *rtmp; - - struct fwd_addr *head, *entry; - - /* Build request */ - memset(&req, 0, sizeof(req)); - req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)); - req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT; - req.n.nlmsg_type = RTM_GETADDR; - req.r.ifa_family = family; - - rta = (struct rtattr *)(((char *)&req) + NLMSG_ALIGN(req.n.nlmsg_len)); - rta->rta_len = RTA_LENGTH(family == AF_INET ? 4 : 16); - - head = entry = NULL; - - /* Send request */ - if( send(fd, &req, sizeof(req), 0) <= 0 ) - goto error; - - /* Receive responses */ - for( dump_done = 0; !dump_done; ) - { - if( (offlen = recv(fd, buf, sizeof(buf), 0)) <= 0 ) - goto error; - - /* Parse message */ - for(nlmp = (struct nlmsghdr *)buf; offlen > sizeof(*nlmp);) - { - /* Dump finished? */ - if( nlmp->nlmsg_type == NLMSG_DONE ) - { - dump_done = 1; - break; - } - - int len = nlmp->nlmsg_len; - int req_len = len - sizeof(*nlmp); - - if( req_len<0 || len>offlen ) - goto error; - - if( !NLMSG_OK(nlmp, offlen) ) - goto error; - - rtmp = (struct ifaddrmsg *) NLMSG_DATA(nlmp); - rtatp = (struct rtattr *) IFA_RTA(rtmp); - - if( !(entry = fwd_alloc_ptr(struct fwd_addr)) ) - goto error; - - entry->index = rtmp->ifa_index; - if_indextoname(rtmp->ifa_index, (char *)&entry->ifname); - - rtattrlen = IFA_PAYLOAD(nlmp); - - for( ; RTA_OK(rtatp, rtattrlen); rtatp = RTA_NEXT(rtatp, rtattrlen) ) - { - if( rtatp->rta_type == IFA_ADDRESS ) - { - memcpy(&entry->ipaddr.addr, (char *) RTA_DATA(rtatp), rtatp->rta_len); - entry->ipaddr.prefix = rtmp->ifa_prefixlen; - entry->family = family; - } - else if( rtatp->rta_type == IFA_LABEL) - { - memcpy(&entry->label, (char *) RTA_DATA(rtatp), rtatp->rta_len); - } - } - - entry->next = head; - head = entry; - - offlen -= NLMSG_ALIGN(len); - nlmp = (struct nlmsghdr*)((char*)nlmp + NLMSG_ALIGN(len)); - } - } - - return head; - - - error: - - fwd_free_addrs(head); - head = entry = NULL; - - return NULL; -} - -struct fwd_cidr * fwd_lookup_addr(struct fwd_addr *head, const char *ifname) -{ - struct fwd_addr *entry; - - for( entry = head; entry; entry = entry->next ) - if( !strncmp(entry->ifname, ifname, IFNAMSIZ) ) - return &entry->ipaddr; - - return NULL; -} - -void fwd_free_addrs(struct fwd_addr *head) -{ - struct fwd_addr *entry = head; - - while( entry != NULL ) - { - head = entry->next; - free(entry); - entry = head; - } - - head = entry = NULL; -} - -struct fwd_addr * fwd_append_addrs(struct fwd_addr *head, struct fwd_addr *add) -{ - struct fwd_addr *entry = head; - - while( entry->next != NULL ) - entry = entry->next; - - return (entry->next = add); -} - diff --git a/contrib/fwd/src/fwd_addr.h b/contrib/fwd/src/fwd_addr.h deleted file mode 100644 index 3cabe09a0..000000000 --- a/contrib/fwd/src/fwd_addr.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * fwd - OpenWrt firewall daemon - header for rtnetlink communication - * - * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org> - * - * The fwd program is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * The fwd program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with the fwd program. If not, see http://www.gnu.org/licenses/. - */ - -#ifndef __FWD_ADDR_H__ -#define __FWD_ADDR_H__ - -#include <netinet/in.h> -#include <sys/socket.h> -#include <sys/ioctl.h> -#include <net/if.h> -#include <linux/netlink.h> -#include <linux/rtnetlink.h> -#include <arpa/inet.h> - - -struct fwd_addr { - char ifname[IFNAMSIZ]; - char label[IFNAMSIZ]; - int family; - int index; - struct fwd_cidr ipaddr; - struct fwd_addr *next; -}; - - -struct fwd_addr * fwd_get_addrs(int, int); -struct fwd_addr * fwd_append_addrs(struct fwd_addr *, struct fwd_addr *); -void fwd_free_addrs(struct fwd_addr *); - -struct fwd_cidr * fwd_lookup_addr(struct fwd_addr *, const char *); - -#define fwd_foreach_addrs(head, entry) for(entry = head; entry; entry = entry->next) - -#endif - diff --git a/contrib/fwd/src/fwd_config.c b/contrib/fwd/src/fwd_config.c deleted file mode 100644 index 320e9ffca..000000000 --- a/contrib/fwd/src/fwd_config.c +++ /dev/null @@ -1,987 +0,0 @@ -/* - * fwd - OpenWrt firewall daemon - config parsing - * - * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org> - * - * The fwd program is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * The fwd program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with the fwd program. If not, see http://www.gnu.org/licenses/. - */ - - -#include "fwd.h" -#include "fwd_addr.h" -#include "fwd_config.h" -#include "fwd_utils.h" - -#include "ucix.h" - - -#define fwd_read_error(...) do { \ - fwd_log_err(__VA_ARGS__); \ - return; \ -} while(0) - - -/* - * Parse helpers - */ -static int -fwd_read_policy(struct uci_context *uci, const char *s, const char *o) -{ - const char *val = ucix_get_option(uci, "firewall", s, o); - - if( val != NULL ) - { - switch( val[0] ) - { - case 'D': - case 'd': - return FWD_P_DROP; - - case 'R': - case 'r': - return FWD_P_REJECT; - - case 'A': - case 'a': - return FWD_P_ACCEPT; - } - } - - return FWD_P_UNSPEC; -} - -static int -fwd_read_bool(struct uci_context *uci, const char *s, const char *o, int d) -{ - const char *val = ucix_get_option(uci, "firewall", s, o); - - if( val != NULL ) - { - if( !strcmp(val, "yes") || !strcmp(val, "true") || !strcmp(val, "1") ) - return 1; - else - return 0; - } - - return d; -} - -static unsigned int -fwd_read_uint(struct uci_context *uci, const char *s, const char *o, unsigned int d) -{ - const char *val = ucix_get_option(uci, "firewall", s, o); - - if( val != NULL ) - { - return atoi(val); - } - - return d; -} - -static int -fwd_read_cidr(struct uci_context *uci, const char *s, const char *o, struct fwd_cidr **c) -{ - const char *val = ucix_get_option(uci, "firewall", s, o); - char ip[32], prefix[32]; - struct in_addr ina; - - memset(ip, 0, 32); - memset(prefix, 0, 32); - - if( val == NULL ) - { - return 0; - } - else if( (strlen(val) < 32) && (sscanf(val, "%[^/]/%s", ip, prefix) > 0) ) - { - if( !(*c = fwd_alloc_ptr(struct fwd_cidr)) ) - goto inval; - - if( inet_aton(ip, &ina) ) - { - (*c)->addr.s_addr = ina.s_addr; - - if( strchr(prefix, '.') ) - { - if( inet_aton(prefix, &ina) ) - { - (*c)->prefix = 32; - ina.s_addr = ntohl(ina.s_addr); - - while( !(ina.s_addr & 1) ) - { - ina.s_addr >>= 1; - (*c)->prefix--; - } - } - else - { - goto inval; - } - } - else - { - (*c)->prefix = prefix[0] ? atoi(prefix) : 32; - - if( ((*c)->prefix < 0) || ((*c)->prefix > 32) ) - { - goto inval; - } - } - - return 0; - } - } - - inval: - fwd_free_ptr(*c); - return -1; -} - -static int -fwd_read_mac(struct uci_context *uci, const char *s, const char *o, struct fwd_mac **m) -{ - const char *val = ucix_get_option(uci, "firewall", s, o); - - if( val == NULL ) - { - return 0; - } - else - { - if( (*m = fwd_alloc_ptr(struct fwd_mac)) != NULL ) - { - unsigned int i1, i2, i3, i4, i5, i6; - - if( sscanf(val, "%2x:%2x:%2x:%2x:%2x:%2x", - &i1, &i2, &i3, &i4, &i5, &i6) == 6 - ) { - (*m)->mac[0] = (unsigned char)i1; - (*m)->mac[1] = (unsigned char)i2; - (*m)->mac[2] = (unsigned char)i3; - (*m)->mac[3] = (unsigned char)i4; - (*m)->mac[4] = (unsigned char)i5; - (*m)->mac[5] = (unsigned char)i6; - return 0; - } - } - } - - fwd_free_ptr(*m); - return -1; -} - -static int -fwd_read_portrange(struct uci_context *uci, const char *s, const char *o, struct fwd_portrange **p) -{ - const char *val = ucix_get_option(uci, "firewall", s, o); - int min = -1; - int max = -1; - unsigned int tmp; - - if( val == NULL ) - { - return 0; - } - else if( sscanf(val, "%u%*[:-]%u", &min, &max) > 0 ) - { - if( max == -1 ) - { - max = min; - } - else if( min > max ) - { - tmp = max; - max = min; - min = tmp; - } - - if( (min >= 0) && (min <= 65535) && (max >= 0) && (max <= 65535) ) - { - if( (*p = fwd_alloc_ptr(struct fwd_portrange)) != NULL ) - { - (*p)->min = min; - (*p)->max = max; - return 0; - } - } - } - - fwd_free_ptr(*p); - return -1; -} - -static int -fwd_read_proto(struct uci_context *uci, const char *s, const char *o, struct fwd_proto **p) -{ - const char *val = ucix_get_option(uci, "firewall", s, o); - int proto; - - if( val == NULL ) - { - return 0; - } - else - { - if( (*p = fwd_alloc_ptr(struct fwd_proto)) != NULL ) - { - proto = atoi(val); - - if( !strcasecmp(val, "all") ) - { - (*p)->type = FWD_PR_ALL; - (*p)->proto = 0; - } - else if( !strcasecmp(val, "icmp") ) - { - (*p)->type = FWD_PR_ICMP; - (*p)->proto = 0; - } - else if( !strcasecmp(val, "udp") ) - { - (*p)->type = FWD_PR_UDP; - (*p)->proto = 0; - } - else if( !strcasecmp(val, "tcp") ) - { - (*p)->type = FWD_PR_TCP; - (*p)->proto = 0; - } - else if( !strcasecmp(val, "tcpudp") ) - { - (*p)->type = FWD_PR_TCPUDP; - (*p)->proto = 0; - } - else if( proto > 0 ) - { - (*p)->type = FWD_PR_CUSTOM; - (*p)->proto = proto; - } - else - { - goto inval; - } - - return 0; - } - } - - inval: - fwd_free_ptr(*p); - return -1; -} - -static int -fwd_read_icmptype(struct uci_context *uci, const char *s, const char *o, struct fwd_icmptype **i) -{ - const char *val = ucix_get_option(uci, "firewall", s, o); - unsigned int type, code; - - if( val == NULL ) - { - return 0; - } - else - { - if( (*i = fwd_alloc_ptr(struct fwd_icmptype)) != NULL ) - { - if( sscanf(val, "%u/%u", &type, &code) == 2 ) - { - if( (type > 255) || (code > 255) ) - goto inval; - - (*i)->type = type; - (*i)->code = code; - - return 0; - } - - else if( sscanf(val, "%u", &type) == 1 ) - { - if( type > 255 ) - goto inval; - - (*i)->type = type; - (*i)->code = -1; - - return 0; - } - - /* XXX: no validity check here but I do not want to - duplicate libipt_icmp.c ... */ - else if( sscanf(val, "%31s", (*i)->name) == 1 ) - { - return 0; - } - } - } - - inval: - fwd_free_ptr(*i); - return -1; -} - -static const char * -fwd_read_string(struct uci_context *uci, const char *s, const char *o) -{ - return ucix_get_option(uci, "firewall", s, o); -} - - -static void -fwd_append_config(struct fwd_data *h, struct fwd_data *a) -{ - while( h->next ) - h = h->next; - - h->next = a; -} - - -/* - * config defaults - */ -static void fwd_read_defaults_cb( - struct uci_context *uci, - const char *s, struct fwd_defaults *d -) { - d->input = fwd_read_policy(uci, s, "input"); - d->forward = fwd_read_policy(uci, s, "forward"); - d->output = fwd_read_policy(uci, s, "output"); - d->syn_flood = fwd_read_bool(uci, s, "syn_flood", 1); - d->syn_rate = fwd_read_uint(uci, s, "syn_rate", 25); - d->syn_burst = fwd_read_uint(uci, s, "syn_burst", 50); - d->drop_invalid = fwd_read_bool(uci, s, "drop_invalid", 1); -} - -static struct fwd_data * -fwd_read_defaults(struct uci_context *uci) -{ - struct fwd_data *dt; - struct fwd_defaults d; - - if( (dt = fwd_alloc_ptr(struct fwd_data)) != NULL ) - { - memset(&d, 0, sizeof(d)); - - ucix_for_each_section_type(uci, "firewall", "defaults", - (void *)fwd_read_defaults_cb, &d); - - memcpy(&dt->section.defaults, &d, sizeof(d)); - - dt->type = FWD_S_DEFAULTS; - dt->next = NULL; - - return dt; - } - - return NULL; -} - - -/* - * config zone - */ -static void fwd_read_zone_networks_cb( - const char *net, struct fwd_network **np -) { - struct fwd_network *nn; - - if( (nn = fwd_alloc_ptr(struct fwd_network)) != NULL ) - { - nn->name = strdup(net); - nn->next = *np; - *np = nn; - } -} - -static void fwd_read_zones_cb( - struct uci_context *uci, - const char *s, struct fwd_data_conveyor *cv -) { - struct fwd_data *dtn; - struct fwd_network *net = NULL; - const char *name; - - if( !(name = fwd_read_string(uci, s, "name")) ) - fwd_read_error("section '%s' is missing 'name' option!", s); - - if( (dtn = fwd_alloc_ptr(struct fwd_data)) != NULL ) - { - dtn->section.zone.name = strdup(name); - dtn->section.zone.masq = fwd_read_bool(uci, s, "masq", 0); - dtn->section.zone.mtu_fix = fwd_read_bool(uci, s, "mtu_fix", 0); - dtn->section.zone.conntrack = fwd_read_bool(uci, s, "conntrack", 0); - - dtn->section.zone.input = fwd_read_policy(uci, s, "input") - ?: cv->head->section.defaults.input ?: FWD_P_DROP; - - dtn->section.zone.forward = fwd_read_policy(uci, s, "forward") - ?: cv->head->section.defaults.forward ?: FWD_P_DROP; - - dtn->section.zone.output = fwd_read_policy(uci, s, "output") - ?: cv->head->section.defaults.output ?: FWD_P_DROP; - - /* try to parse option/list network ... */ - if( ucix_for_each_list(uci, "firewall", s, "network", - (void *)&fwd_read_zone_networks_cb, &net) < 0 ) - { - /* ... didn't work, fallback to option name */ - fwd_read_zone_networks_cb(name, &net); - } - - dtn->section.zone.networks = net; - dtn->type = FWD_S_ZONE; - dtn->next = cv->cursor; - cv->cursor = dtn; - } -} - -static struct fwd_data * -fwd_read_zones(struct uci_context *uci, struct fwd_data *def) -{ - struct fwd_data_conveyor cv; - - cv.cursor = NULL; - cv.head = def; - - ucix_for_each_section_type(uci, "firewall", "zone", - (void *)fwd_read_zones_cb, &cv); - - return cv.cursor; -} - - -/* - * config forwarding - */ -static void fwd_read_forwards_cb( - struct uci_context *uci, - const char *s, struct fwd_data_conveyor *cv -) { - const char *src, *dest; - struct fwd_data *dtn; - struct fwd_zone *zsrc = NULL; - struct fwd_zone *zdest = NULL; - - if( !(src = fwd_read_string(uci, s, "src")) ) - fwd_read_error("section '%s' is missing 'src' option!", s); - else if( !(zsrc = fwd_lookup_zone(cv->head, src)) ) - fwd_read_error("section '%s' references unknown src zone '%s'!", s, src); - else if( !(dest = fwd_read_string(uci, s, "dest")) ) - fwd_read_error("section '%s' is missing 'dest' option!", s); - else if( !(zdest = fwd_lookup_zone(cv->head, dest)) ) - fwd_read_error("section '%s' references unknown dest zone '%s'!", s, dest); - - if( (dtn = fwd_alloc_ptr(struct fwd_data)) != NULL ) - { - dtn->section.forwarding.src = zsrc; - dtn->section.forwarding.dest = zdest; - dtn->section.forwarding.mtu_fix = fwd_read_bool(uci, s, "mtu_fix", 0); - dtn->section.forwarding.masq = fwd_read_bool(uci, s, "masq", 0); - - dtn->type = FWD_S_FORWARD; - - if( zsrc ) - { - dtn->next = zsrc->forwardings; - zsrc->forwardings = dtn; - } - else - { - dtn->next = cv->cursor; - cv->cursor = dtn; - } - } - else - { - fwd_read_error("out of memory while parsing config!"); - } -} - -static struct fwd_data * -fwd_read_forwards(struct uci_context *uci, struct fwd_data *zones) -{ - struct fwd_data_conveyor cv; - - cv.cursor = NULL; - cv.head = zones; - - ucix_for_each_section_type(uci, "firewall", "forwarding", - (void *)fwd_read_forwards_cb, &cv); - - return cv.cursor; -} - - -/* - * config redirect - */ -static void fwd_read_redirects_cb( - struct uci_context *uci, - const char *s, struct fwd_data_conveyor *cv -) { - const char *src; - struct fwd_data *dtn = NULL; - struct fwd_data *dtn2 = NULL; - struct fwd_zone *zsrc = NULL; - - /* check zone */ - if( !(src = fwd_read_string(uci, s, "src")) ) - fwd_read_error( - "section '%s' is missing 'src' option!", - s - ); - - else if( !(zsrc = fwd_lookup_zone(cv->head, src)) ) - fwd_read_error( - "section '%s' references unknown src zone '%s'!", - s, src - ); - - /* uci context, section, name, type */ - fwd_check_option(uci, s, src_ip, cidr); - fwd_check_option(uci, s, src_mac, mac); - fwd_check_option(uci, s, src_port, portrange); - fwd_check_option(uci, s, src_dport, portrange); - fwd_check_option(uci, s, dest_ip, cidr); - fwd_check_option(uci, s, dest_port, portrange); - fwd_check_option(uci, s, proto, proto); - - if( (dtn = fwd_alloc_ptr(struct fwd_data)) != NULL ) - { - dtn->section.redirect.proto = proto; - dtn->section.redirect.src = zsrc; - dtn->section.redirect.src_ip = src_ip; - dtn->section.redirect.src_mac = src_mac; - dtn->section.redirect.src_port = src_port; - dtn->section.redirect.src_dport = src_dport; - dtn->section.redirect.dest_ip = dest_ip; - dtn->section.redirect.dest_port = dest_port; - - dtn->type = FWD_S_REDIRECT; - dtn->next = zsrc->redirects; - zsrc->redirects = dtn; - - if( (proto != NULL) && (proto->type == FWD_PR_TCPUDP) ) - { - if( !(dtn2 = fwd_alloc_ptr(struct fwd_data)) || - !(dtn2->section.redirect.proto = fwd_alloc_ptr(struct fwd_proto)) - ) { - fwd_free_ptr(dtn2); - fwd_read_error("out of memory while parsing config!"); - } - - dtn->section.redirect.proto->type = FWD_PR_UDP; - dtn2->section.redirect.proto->type = FWD_PR_TCP; - - dtn2->section.redirect.src = zsrc; - dtn2->section.redirect.src_ip = src_ip; - dtn2->section.redirect.src_mac = src_mac; - dtn2->section.redirect.src_port = src_port; - dtn2->section.redirect.src_dport = src_dport; - dtn2->section.redirect.dest_ip = dest_ip; - dtn2->section.redirect.dest_port = dest_port; - dtn2->section.redirect.clone = 1; - - dtn2->type = FWD_S_REDIRECT; - dtn2->next = zsrc->redirects; - zsrc->redirects = dtn2; - } - } - else - { - fwd_read_error("out of memory while parsing config!"); - } -} - -static struct fwd_data * -fwd_read_redirects(struct uci_context *uci, struct fwd_data *zones) -{ - struct fwd_data_conveyor cv; - - cv.cursor = NULL; - cv.head = zones; - - ucix_for_each_section_type(uci, "firewall", "redirect", - (void *)fwd_read_redirects_cb, &cv); - - return cv.cursor; -} - - -/* - * config rule - */ -static void fwd_read_rules_cb( - struct uci_context *uci, - const char *s, struct fwd_data_conveyor *cv -) { - const char *src, *dest; - struct fwd_data *dtn = NULL; - struct fwd_data *dtn2 = NULL; - struct fwd_zone *zsrc = NULL; - struct fwd_zone *zdest = NULL; - - /* check zones */ - if( !(src = fwd_read_string(uci, s, "src")) ) - fwd_read_error( - "section '%s' is missing 'src' option!", - s - ); - - else if( !(zsrc = fwd_lookup_zone(cv->head, src)) ) - fwd_read_error( - "section '%s' references unknown src zone '%s'!", - s, src - ); - - if( (dest = fwd_read_string(uci, s, "dest")) != NULL ) - if( !(zdest = fwd_lookup_zone(cv->head, dest)) ) - fwd_read_error( - "section '%s' references unknown dest zone '%s'!", - s, dest - ); - - /* uci context, section, name, type */ - fwd_check_option(uci, s, src_ip, cidr); - fwd_check_option(uci, s, src_mac, mac); - fwd_check_option(uci, s, src_port, portrange); - fwd_check_option(uci, s, dest_ip, cidr); - fwd_check_option(uci, s, dest_port, portrange); - fwd_check_option(uci, s, proto, proto); - fwd_check_option(uci, s, icmptype, icmptype); - - if( (dtn = fwd_alloc_ptr(struct fwd_data)) != NULL ) - { - dtn->section.rule.proto = proto; - dtn->section.rule.icmp_type = icmptype; - dtn->section.rule.src = zsrc; - dtn->section.rule.src_ip = src_ip; - dtn->section.rule.src_mac = src_mac; - dtn->section.rule.src_port = src_port; - dtn->section.rule.dest = zdest; - dtn->section.rule.dest_ip = dest_ip; - dtn->section.rule.dest_port = dest_port; - dtn->section.rule.target = fwd_read_policy(uci, s, "target"); - - dtn->type = FWD_S_RULE; - dtn->next = zsrc->rules; - zsrc->rules = dtn; - - if( (proto != NULL) && (proto->type == FWD_PR_TCPUDP) ) - { - if( !(dtn2 = fwd_alloc_ptr(struct fwd_data)) || - !(dtn2->section.rule.proto = fwd_alloc_ptr(struct fwd_proto)) - ) { - fwd_free_ptr(dtn2); - fwd_read_error("out of memory while parsing config!"); - } - - dtn->section.rule.proto->type = FWD_PR_UDP; - dtn2->section.rule.proto->type = FWD_PR_TCP; - - dtn2->section.rule.src = zsrc; - dtn2->section.rule.src_ip = src_ip; - dtn2->section.rule.src_mac = src_mac; - dtn2->section.rule.src_port = src_port; - dtn2->section.rule.dest = zdest; - dtn2->section.rule.dest_ip = dest_ip; - dtn2->section.rule.dest_port = dest_port; - dtn2->section.rule.target = dtn->section.rule.target; - dtn2->section.rule.clone = 1; - - dtn2->type = FWD_S_RULE; - dtn2->next = zsrc->rules; - zsrc->rules = dtn2; - } - } - else - { - fwd_read_error("out of memory while parsing config!"); - } -} - -static struct fwd_data * -fwd_read_rules(struct uci_context *uci, struct fwd_data *zones) -{ - struct fwd_data_conveyor cv; - - cv.cursor = NULL; - cv.head = zones; - - ucix_for_each_section_type(uci, "firewall", "rule", - (void *)fwd_read_rules_cb, &cv); - - return cv.cursor; -} - - -/* - * config include - */ -static void fwd_read_includes_cb( - struct uci_context *uci, - const char *s, struct fwd_data_conveyor *cv -) { - const char *path = fwd_read_string(uci, s, "path"); - struct fwd_data *dtn = NULL; - - if( path != NULL ) - { - if( (dtn = fwd_alloc_ptr(struct fwd_data)) != NULL ) - { - dtn->section.include.path = strdup(path); - - dtn->type = FWD_S_INCLUDE; - dtn->next = cv->cursor; - cv->cursor = dtn; - } - else - { - fwd_read_error("out of memory while parsing config!"); - } - } -} - -static struct fwd_data * -fwd_read_includes(struct uci_context *uci) -{ - struct fwd_data_conveyor cv; - - cv.cursor = NULL; - cv.head = NULL; - - ucix_for_each_section_type(uci, "firewall", "include", - (void *)fwd_read_includes_cb, &cv); - - return cv.cursor; -} - - -/* - * config interface - */ -static void fwd_read_network_data( - struct uci_context *uci, struct fwd_network *net -) { - struct fwd_network *e; - const char *type, *ifname; - - for( e = net; e; e = e->next ) - { - if( (type = ucix_get_option(uci, "network", e->name, NULL)) != NULL ) - { - if( !(ifname = ucix_get_option(uci, "network", e->name, "ifname")) ) - fwd_read_error( - "section '%s' is missing 'ifname' option!", - e->name - ); - - e->isalias = (strcmp(type, "alias") ? 0 : 1); - e->ifname = strdup(ifname); - } - } -} - -static void fwd_read_networks( - struct uci_context *uci, struct fwd_data *zones -) { - struct fwd_data *e; - - for( e = zones; e; e = e->next ) - if( e->type == FWD_S_ZONE ) - fwd_read_network_data(uci, e->section.zone.networks); -} - -static void fwd_free_networks(struct fwd_network *h) -{ - struct fwd_network *e = h; - - while( h != NULL ) - { - e = h->next; - - fwd_free_ptr(h->name); - fwd_free_ptr(h->ifname); - fwd_free_ptr(h->addr); - - free(h); - h = e; - } - - e = h = NULL; -} - -static struct fwd_cidr * fwd_alloc_cidr(struct fwd_cidr *addr) -{ - struct fwd_cidr *cidr; - - if( (cidr = fwd_alloc_ptr(struct fwd_cidr)) != NULL ) - { - if( addr != NULL ) - { - cidr->addr.s_addr = addr->addr.s_addr; - cidr->prefix = addr->prefix; - } - - return cidr; - } - - return NULL; -} - - - -struct fwd_data * fwd_read_config(struct fwd_handle *h) -{ - struct uci_context *ctx; - struct fwd_data *defaults, *zones, *e; - struct fwd_addr *addrs; - struct fwd_network *net; - struct fwd_zone *zone; - - if( (ctx = ucix_init("firewall")) != NULL ) - { - if( !(defaults = fwd_read_defaults(ctx)) ) - goto error; - - if( !(zones = fwd_read_zones(ctx, defaults)) ) - goto error; - - fwd_append_config(defaults, zones); - fwd_append_config(defaults, fwd_read_forwards(ctx, zones)); - fwd_append_config(defaults, fwd_read_redirects(ctx, zones)); - fwd_append_config(defaults, fwd_read_rules(ctx, zones)); - fwd_append_config(defaults, fwd_read_includes(ctx)); - - ucix_cleanup(ctx); - - if( (ctx = ucix_init("network")) != NULL ) - { - fwd_read_networks(ctx, zones); - ucix_cleanup(ctx); - - if( !(addrs = fwd_get_addrs(h->rtnl_socket, AF_INET)) ) - goto error; - - for( e = zones; e && (zone = &e->section.zone); e = e->next ) - { - if( e->type != FWD_S_ZONE ) - break; - - for( net = zone->networks; net; net = net->next ) - { - net->addr = fwd_alloc_cidr( - fwd_lookup_addr(addrs, net->ifname) - ); - } - } - - fwd_free_addrs(addrs); - return defaults; - } - } - - error: - if( ctx ) ucix_cleanup(ctx); - fwd_free_config(defaults); - fwd_free_config(zones); - return NULL; -} - - -void fwd_free_config(struct fwd_data *h) -{ - struct fwd_data *e = h; - - while( h != NULL ) - { - e = h->next; - - switch(h->type) - { - case FWD_S_INCLUDE: - fwd_free_ptr(h->section.include.path); - break; - - case FWD_S_ZONE: - fwd_free_ptr(h->section.zone.name); - fwd_free_networks(h->section.zone.networks); - fwd_free_config(h->section.zone.rules); - fwd_free_config(h->section.zone.redirects); - fwd_free_config(h->section.zone.forwardings); - break; - - case FWD_S_REDIRECT: - /* Clone rules share all pointers except proto. - Prevent a double-free here */ - if( ! h->section.redirect.clone ) - { - fwd_free_ptr(h->section.redirect.src_ip); - fwd_free_ptr(h->section.redirect.src_mac); - fwd_free_ptr(h->section.redirect.src_port); - fwd_free_ptr(h->section.redirect.src_dport); - fwd_free_ptr(h->section.redirect.dest_ip); - fwd_free_ptr(h->section.redirect.dest_port); - } - fwd_free_ptr(h->section.redirect.proto); - break; - - case FWD_S_RULE: - /* Clone rules share all pointers except proto. - Prevent a double-free here */ - if( ! h->section.rule.clone ) - { - fwd_free_ptr(h->section.rule.src_ip); - fwd_free_ptr(h->section.rule.src_mac); - fwd_free_ptr(h->section.rule.src_port); - fwd_free_ptr(h->section.rule.dest_ip); - fwd_free_ptr(h->section.rule.dest_port); - fwd_free_ptr(h->section.rule.icmp_type); - } - fwd_free_ptr(h->section.rule.proto); - break; - - case FWD_S_DEFAULTS: - case FWD_S_FORWARD: - /* Make gcc happy */ - break; - } - - fwd_free_ptr(h); - h = e; - } - - e = h = NULL; -} - - -struct fwd_zone * -fwd_lookup_zone(struct fwd_data *h, const char *n) -{ - struct fwd_data *e; - - if( n != NULL ) - { - for( e = h; e; e = e->next ) - { - if( (e->type = FWD_S_ZONE) && !strcmp(e->section.zone.name, n) ) - return &e->section.zone; - } - } - - return NULL; -} - diff --git a/contrib/fwd/src/fwd_config.h b/contrib/fwd/src/fwd_config.h deleted file mode 100644 index 058cff473..000000000 --- a/contrib/fwd/src/fwd_config.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef __FWD_CONFIG_H__ -#define __FWD_CONFIG_H__ - -#include "fwd.h" -#include "ucix.h" - -/* fwd_check_option(uci_ctx, section, name, type) */ -#define fwd_check_option(uci, sct, name, type) \ - struct fwd_##type *name = NULL; \ - if( fwd_read_##type(uci, sct, #name, &name) ) \ - { \ - printf("ERROR: section '%s' contains invalid %s in '%s'!\n", \ - sct, #type, #name); \ - return; \ - } - -/* structure to access fwd_data* in uci iter callbacks */ -struct fwd_data_conveyor { - struct fwd_data *head; - struct fwd_data *cursor; -}; - -/* api */ -struct fwd_data * fwd_read_config(struct fwd_handle *); -struct fwd_zone * fwd_lookup_zone(struct fwd_data *, const char *); - -void fwd_free_config(struct fwd_data *); - -#endif diff --git a/contrib/fwd/src/fwd_ipc.c b/contrib/fwd/src/fwd_ipc.c deleted file mode 100644 index 83eb7d886..000000000 --- a/contrib/fwd/src/fwd_ipc.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * fwd - OpenWrt firewall daemon - unix domain socket parts - * - * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org> - * - * The fwd program is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * The fwd program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with the fwd program. If not, see http://www.gnu.org/licenses/. - */ - - -#include "fwd.h" -#include "fwd_ipc.h" - - -int fwd_ipc_listen(void) -{ - int fd; - struct sockaddr_un addr; - - if( (fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0 ) - fwd_fatal("Cannot create AF_UNIX socket: %m"); - - memset(&addr, 0, sizeof(struct sockaddr_un)); - strcpy(addr.sun_path, FWD_SOCKET_PATH); - addr.sun_family = AF_UNIX; - - unlink(FWD_SOCKET_PATH); - - if( bind(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0 ) - fwd_fatal("Cannot bind AF_UNIX socket: %m"); - - if( listen(fd, 1) < 0 ) - fwd_fatal("Cannot listen on AF_UNIX socket: %m"); - - //fcntl(fd, F_SETFL, O_NONBLOCK); - - return fd; -} - -int fwd_ipc_accept(int fd) -{ - return accept(fd, NULL, NULL); -} - -int fwd_ipc_connect(void) -{ - int fd; - struct sockaddr_un addr; - - if( (fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0 ) - fwd_fatal("Cannot create AF_UNIX socket: %m"); - - memset(&addr, 0, sizeof(struct sockaddr_un)); - strcpy(addr.sun_path, FWD_SOCKET_PATH); - addr.sun_family = AF_UNIX; - - if( connect(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0 ) - fwd_fatal("Cannot connect AF_UNIX socket: %m"); - - fcntl(fd, F_SETFL, O_NONBLOCK); - - return fd; -} - -int fwd_ipc_recvmsg(int fd, void *buf, int len) -{ - return recv(fd, buf, len, 0); -} - -int fwd_ipc_sendmsg(int fd, void *buf, int len) -{ - return send(fd, buf, len, 0); -} - -void fwd_ipc_shutdown(int fd) -{ - shutdown(fd, SHUT_RDWR); - close(fd); -} - -int fwd_ipc_sendtype(int fd, enum fwd_ipc_msgtype type) -{ - struct fwd_ipc_msg msg; - - memset(&msg, 0, sizeof(struct fwd_ipc_msg)); - msg.type = type; - - return fwd_ipc_sendmsg(fd, &msg, sizeof(struct fwd_ipc_msg)); -} diff --git a/contrib/fwd/src/fwd_ipc.h b/contrib/fwd/src/fwd_ipc.h deleted file mode 100644 index 4a4c9ecc7..000000000 --- a/contrib/fwd/src/fwd_ipc.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * fwd - OpenWrt firewall daemon - unix domain socket headers - * - * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org> - * - * The fwd program is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * The fwd program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with the fwd program. If not, see http://www.gnu.org/licenses/. - */ - -#ifndef __FWD_IPC_H__ -#define __FWD_IPC_H__ - -#include <unistd.h> -#include <fcntl.h> -#include <errno.h> - -#include <sys/socket.h> -#include <sys/un.h> - -#define FWD_SOCKET_PATH "/var/run/fwd.sock" - - -enum fwd_ipc_msgtype { - FWD_IPC_OK = 0, - FWD_IPC_ERROR = 1, - FWD_IPC_FLUSH = 2, - FWD_IPC_BUILD = 3, - FWD_IPC_RELOAD = 4, - FWD_IPC_ADDIF = 5, - FWD_IPC_DELIF = 6 -}; - -struct fwd_ipc_msg { - enum fwd_ipc_msgtype type; - union { - char network[256]; - } data; -}; - -int fwd_ipc_listen(void); -int fwd_ipc_accept(int); - -int fwd_ipc_connect(void); - -int fwd_ipc_recvmsg(int, void *, int); -int fwd_ipc_sendmsg(int, void *, int); - -void fwd_ipc_shutdown(int); - -int fwd_ipc_sendtype(int, enum fwd_ipc_msgtype); - -#endif diff --git a/contrib/fwd/src/fwd_rules.c b/contrib/fwd/src/fwd_rules.c deleted file mode 100644 index b960e62fd..000000000 --- a/contrib/fwd/src/fwd_rules.c +++ /dev/null @@ -1,886 +0,0 @@ -/* - * fwd - OpenWrt firewall daemon - iptables rule set - * - * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org> - * - * The fwd program is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * The fwd program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with the fwd program. If not, see http://www.gnu.org/licenses/. - */ - - -#include "fwd.h" -#include "fwd_addr.h" -#include "fwd_rules.h" -#include "fwd_xtables.h" -#include "fwd_utils.h" - - -/* -P <chain> <policy> */ -static void fwd_r_set_policy( - struct iptc_handle *h, const char *chain, const char *policy -) { - iptc_set_policy(chain, policy, NULL, h); -} - -/* -N <chain> */ -static void fwd_r_new_chain(struct iptc_handle *h, const char *chain) -{ - iptc_create_chain(chain, h); -} - -/* -A <chain1> -j <chain2> */ -static void fwd_r_jump_chain( - struct iptc_handle *h, const char *chain1, const char *chain2 -) { - struct fwd_xt_rule *r; - - if( (r = fwd_xt_init_rule(h)) != NULL ) - { - fwd_xt_get_target(r, chain2); - fwd_xt_append_rule(r, chain1); - } -} - -/* -A <chain> -m state --state INVALID -j DROP */ -static void fwd_r_drop_invalid(struct iptc_handle *h, const char *chain) -{ - struct fwd_xt_rule *r; - struct xtables_match *m; - - if( (r = fwd_xt_init_rule(h)) != NULL ) - { - if( (m = fwd_xt_get_match(r, "state")) != NULL ) - { - fwd_xt_parse_match(r, m, "--state", "INVALID"); - fwd_xt_get_target(r, "DROP"); - fwd_xt_append_rule(r, chain); - } - } -} - -/* -A <chain> -m state --state RELATED,ESTABLISHED -j ACCEPT */ -static void fwd_r_accept_related(struct iptc_handle *h, const char *chain) -{ - struct fwd_xt_rule *r; - struct xtables_match *m; - - if( (r = fwd_xt_init_rule(h)) != NULL ) - { - if( (m = fwd_xt_get_match(r, "state")) != NULL ) - { - fwd_xt_parse_match(r, m, "--state", "RELATED,ESTABLISHED"); - fwd_xt_get_target(r, "ACCEPT"); - fwd_xt_append_rule(r, chain); - } - } -} - -/* -A INPUT -i lo -j ACCEPT; -A OUTPUT -o lo -j ACCEPT */ -static void fwd_r_accept_lo(struct iptc_handle *h) -{ - struct fwd_network n; - struct fwd_xt_rule *r; - - n.ifname = "lo"; - - if( (r = fwd_xt_init_rule(h)) != NULL ) - { - fwd_xt_parse_in(r, &n, 0); - fwd_xt_get_target(r, "ACCEPT"); - fwd_xt_append_rule(r, "INPUT"); - } - - if( (r = fwd_xt_init_rule(h)) != NULL ) - { - fwd_xt_parse_out(r, &n, 0); - fwd_xt_get_target(r, "ACCEPT"); - fwd_xt_append_rule(r, "OUTPUT"); - } -} - -/* build syn_flood chain and jump rule */ -static void fwd_r_add_synflood(struct iptc_handle *h, struct fwd_defaults *def) -{ - struct fwd_proto p; - struct fwd_xt_rule *r; - struct xtables_match *m; - char buf[32]; - - /* -N syn_flood */ - fwd_r_new_chain(h, "syn_flood"); - - /* return rule */ - if( (r = fwd_xt_init_rule(h)) != NULL ) - { - /* -p tcp */ - p.type = FWD_PR_TCP; - fwd_xt_parse_proto(r, &p, 0); - - /* -m tcp --syn */ - if( (m = fwd_xt_get_match(r, "tcp")) != NULL ) - { - fwd_xt_parse_match(r, m, "--syn"); - } - - /* -m limit --limit x/second --limit-burst y */ - if( (m = fwd_xt_get_match(r, "limit")) != NULL ) - { - sprintf(buf, "%i/second", def->syn_rate); - fwd_xt_parse_match(r, m, "--limit", buf); - - sprintf(buf, "%i", def->syn_burst); - fwd_xt_parse_match(r, m, "--limit-burst", buf); - } - - /* -j RETURN; -A syn_flood */ - fwd_xt_get_target(r, "RETURN"); - fwd_xt_append_rule(r, "syn_flood"); - } - - /* drop rule */ - if( (r = fwd_xt_init_rule(h)) != NULL ) - { - /* -j DROP; -A syn_flood */ - fwd_xt_get_target(r, "DROP"); - fwd_xt_append_rule(r, "syn_flood"); - } - - /* jump to syn_flood rule */ - if( (r = fwd_xt_init_rule(h)) != NULL ) - { - /* -p tcp */ - p.type = FWD_PR_TCP; - fwd_xt_parse_proto(r, &p, 0); - - /* -m tcp --syn */ - if( (m = fwd_xt_get_match(r, "tcp")) != NULL ) - { - fwd_xt_parse_match(r, m, "--syn"); - } - - /* -j syn_flood; -A INPUT */ - fwd_xt_get_target(r, "syn_flood"); - fwd_xt_append_rule(r, "INPUT"); - } -} - -/* build reject target chain */ -static void fwd_r_handle_reject(struct iptc_handle *h) -{ - struct fwd_proto p; - struct fwd_xt_rule *r; - struct xtables_target *t; - - /* -N handle_reject */ - fwd_r_new_chain(h, "handle_reject"); - - /* tcp reject rule */ - if( (r = fwd_xt_init_rule(h)) != NULL ) - { - /* -p tcp */ - p.type = FWD_PR_TCP; - fwd_xt_parse_proto(r, &p, 0); - - /* -j REJECT --reject-with tcp-reset */ - if( (t = fwd_xt_get_target(r, "REJECT")) != NULL ) - { - fwd_xt_parse_target(r, t, "--reject-with", "tcp-reset"); - } - - /* -A handle_reject */ - fwd_xt_append_rule(r, "handle_reject"); - } - - /* common reject rule */ - if( (r = fwd_xt_init_rule(h)) != NULL ) - { - /* -j REJECT --reject-with icmp-port-unreachable */ - if( (t = fwd_xt_get_target(r, "REJECT")) != NULL ) - { - fwd_xt_parse_target(r, t, "--reject-with", - "icmp-port-unreachable"); - } - - /* -A handle_reject */ - fwd_xt_append_rule(r, "handle_reject"); - } -} - -/* build drop target chain */ -static void fwd_r_handle_drop(struct iptc_handle *h) -{ - struct fwd_xt_rule *r; - - /* -N handle_drop */ - fwd_r_new_chain(h, "handle_drop"); - - /* common drop rule */ - if( (r = fwd_xt_init_rule(h)) != NULL ) - { - /* -j DROP; -A handle_drop */ - fwd_xt_get_target(r, "DROP"); - fwd_xt_append_rule(r, "handle_drop"); - } -} - -/* build accept target chain */ -static void fwd_r_handle_accept(struct iptc_handle *h) -{ - struct fwd_xt_rule *r; - - /* -N handle_accept */ - fwd_r_new_chain(h, "handle_accept"); - - /* common accept rule */ - if( (r = fwd_xt_init_rule(h)) != NULL ) - { - /* -j ACCEPT; -A handle_accept */ - fwd_xt_get_target(r, "ACCEPT"); - fwd_xt_append_rule(r, "handle_accept"); - } -} - -/* add comment match */ -static void fwd_r_add_comment( - struct fwd_xt_rule *r, const char *t, struct fwd_zone *z, - struct fwd_network *n -) { - struct xtables_match *m; - char buf[256]; - - if( (m = fwd_xt_get_match(r, "comment")) != NULL ) - { - snprintf(buf, sizeof(buf), "%s:net=%s zone=%s", t, n->name, z->name); - fwd_xt_parse_match(r, m, "--comment", buf); - } -} - -/* add --sport (if applicable) */ -static void fwd_r_add_sport( - struct fwd_xt_rule *r, struct fwd_portrange *p -) { - int proto = r->entry->ip.proto; - char buf[12]; - struct xtables_match *m; - - /* have portrange and proto is tcp or udp ... */ - if( (p != NULL) && ((proto == 6) || (proto == 17)) ) - { - /* get match ... */ - if( (m = fwd_xt_get_match(r, (proto == 6) ? "tcp" : "udp")) != NULL ) - { - snprintf(buf, sizeof(buf), "%u:%u", p->min, p->max); - fwd_xt_parse_match(r, m, "--sport", buf); - } - } -} - -/* add --dport (if applicable) */ -static void fwd_r_add_dport( - struct fwd_xt_rule *r, struct fwd_portrange *p -) { - int proto = r->entry->ip.proto; - char buf[12]; - struct xtables_match *m; - - /* have portrange and proto is tcp or udp ... */ - if( (p != NULL) && ((proto == 6) || (proto == 17)) ) - { - /* get match ... */ - if( (m = fwd_xt_get_match(r, (proto == 6) ? "tcp" : "udp")) != NULL ) - { - snprintf(buf, sizeof(buf), "%u:%u", p->min, p->max); - fwd_xt_parse_match(r, m, "--dport", buf); - } - } -} - -/* add --icmp-type (of applicable) */ -static void fwd_r_add_icmptype( - struct fwd_xt_rule *r, struct fwd_icmptype *i -) { - int proto = r->entry->ip.proto; - struct xtables_match *m; - char buf[32]; - - /* have icmp-type and proto is icmp ... */ - if( (i != NULL) && (proto == 1) ) - { - /* get match ... */ - if( (m = fwd_xt_get_match(r, "icmp")) != NULL ) - { - if( i->name[0] ) - snprintf(buf, sizeof(buf), "%s", i->name); - else - snprintf(buf, sizeof(buf), "%u/%u", i->type, i->code); - - fwd_xt_parse_match(r, m, "--icmp-type", buf); - } - } -} - -/* add -m mac --mac-source ... */ -static void fwd_r_add_srcmac( - struct fwd_xt_rule *r, struct fwd_mac *mac -) { - struct xtables_match *m; - char buf[18]; - - if( mac != NULL ) - { - if( (m = fwd_xt_get_match(r, "mac")) != NULL ) - { - snprintf(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x", - mac->mac[0], mac->mac[1], mac->mac[2], - mac->mac[3], mac->mac[4], mac->mac[5]); - - fwd_xt_parse_match(r, m, "--mac-source", buf); - } - } -} - -/* add policy target */ -static void fwd_r_add_policytarget( - struct fwd_xt_rule *r, enum fwd_policy pol -) { - switch(pol) - { - case FWD_P_ACCEPT: - fwd_xt_get_target(r, "handle_accept"); - break; - - case FWD_P_REJECT: - fwd_xt_get_target(r, "handle_reject"); - break; - - case FWD_P_DROP: - case FWD_P_UNSPEC: - fwd_xt_get_target(r, "handle_drop"); - break; - } -} - -/* add dnat target */ -static void fwd_r_add_dnattarget( - struct fwd_xt_rule *r, struct fwd_cidr *c, struct fwd_portrange *p -) { - struct xtables_target *t; - char buf[32]; - - if( c != NULL ) - { - if( (t = fwd_xt_get_target(r, "DNAT")) != NULL ) - { - if( p != NULL ) - snprintf(buf, sizeof(buf), "%s:%u-%u", - inet_ntoa(c->addr), p->min, p->max); - else - snprintf(buf, sizeof(buf), "%s", inet_ntoa(c->addr)); - - fwd_xt_parse_target(r, t, "--to-destination", buf); - } - } -} - -/* parse comment string and look for match */ -static int fwd_r_cmp(const char *what, const char *cmt, const char *cmp) -{ - char *match; - - if( (match = strstr(cmt, what)) == NULL ) - return 0; - - match += strlen(what); - - if( strncmp(match, cmp, strlen(cmp)) != 0 ) - return 0; - - if( (match[strlen(cmp)] != ' ') && (match[strlen(cmp)] != '\0') ) - return 0; - - return 1; -} - - -static void fwd_ipt_defaults_create(struct fwd_data *d) -{ - struct fwd_defaults *def = &d->section.defaults; - struct iptc_handle *h_filter, *h_nat; - - if( !(h_filter = iptc_init("filter")) || !(h_nat = iptc_init("nat")) ) - fwd_fatal("Unable to obtain libiptc handle"); - - /* policies */ - fwd_r_set_policy(h_filter, "INPUT", - def->input == FWD_P_ACCEPT ? "ACCEPT" : "DROP"); - fwd_r_set_policy(h_filter, "OUTPUT", - def->output == FWD_P_ACCEPT ? "ACCEPT" : "DROP"); - fwd_r_set_policy(h_filter, "FORWARD", - def->forward == FWD_P_ACCEPT ? "ACCEPT" : "DROP"); - - /* invalid state drop */ - if( def->drop_invalid ) - { - fwd_r_drop_invalid(h_filter, "INPUT"); - fwd_r_drop_invalid(h_filter, "OUTPUT"); - fwd_r_drop_invalid(h_filter, "FORWARD"); - } - - /* default accept related */ - fwd_r_accept_related(h_filter, "INPUT"); - fwd_r_accept_related(h_filter, "OUTPUT"); - fwd_r_accept_related(h_filter, "FORWARD"); - - /* default accept on lo */ - fwd_r_accept_lo(h_filter); - - /* syn flood protection */ - if( def->syn_flood ) - { - fwd_r_add_synflood(h_filter, def); - } - - /* rule container chains */ - fwd_r_new_chain(h_filter, "mssfix"); - fwd_r_new_chain(h_filter, "zones"); - fwd_r_new_chain(h_filter, "rules"); - fwd_r_new_chain(h_filter, "redirects"); - fwd_r_new_chain(h_filter, "forwardings"); - fwd_r_jump_chain(h_filter, "INPUT", "rules"); - fwd_r_jump_chain(h_filter, "FORWARD", "mssfix"); - fwd_r_jump_chain(h_filter, "FORWARD", "zones"); - fwd_r_jump_chain(h_filter, "FORWARD", "rules"); - fwd_r_jump_chain(h_filter, "FORWARD", "redirects"); - fwd_r_jump_chain(h_filter, "FORWARD", "forwardings"); - fwd_r_new_chain(h_nat, "zonemasq"); - fwd_r_new_chain(h_nat, "redirects"); - fwd_r_new_chain(h_nat, "loopback"); - fwd_r_jump_chain(h_nat, "POSTROUTING", "zonemasq"); - fwd_r_jump_chain(h_nat, "PREROUTING", "redirects"); - fwd_r_jump_chain(h_nat, "POSTROUTING", "loopback"); - - /* standard drop, accept, reject chain */ - fwd_r_handle_drop(h_filter); - fwd_r_handle_accept(h_filter); - fwd_r_handle_reject(h_filter); - - - if( !iptc_commit(h_nat) ) - fwd_fatal("Cannot commit nat table: %s", iptc_strerror(errno)); - - if( !iptc_commit(h_filter) ) - fwd_fatal("Cannot commit filter table: %s", iptc_strerror(errno)); - - iptc_free(h_nat); - iptc_free(h_filter); -} - - -void fwd_ipt_build_ruleset(struct fwd_handle *h) -{ - struct fwd_data *e; - - fwd_xt_init(); - - for( e = h->conf; e; e = e->next ) - { - switch(e->type) - { - case FWD_S_DEFAULTS: - fwd_log_info("Loading defaults"); - fwd_ipt_defaults_create(e); - break; - - case FWD_S_INCLUDE: - fwd_log_info("Loading include: %s", - e->section.include.path); - break; - - case FWD_S_ZONE: - case FWD_S_FORWARD: - case FWD_S_REDIRECT: - case FWD_S_RULE: - /* Make gcc happy */ - break; - } - } -} - - -static struct fwd_zone * -fwd_lookup_zone(struct fwd_handle *h, const char *net) -{ - struct fwd_data *e; - struct fwd_network *n; - - for( e = h->conf; e; e = e->next ) - if( e->type == FWD_S_ZONE ) - for( n = e->section.zone.networks; n; n = n->next ) - if( !strcmp(n->name, net) ) - return &e->section.zone; - - return NULL; -} - -static struct fwd_network * -fwd_lookup_network(struct fwd_zone *z, const char *net) -{ - struct fwd_network *n; - - for( n = z->networks; n; n = n->next ) - if( !strcmp(n->name, net) ) - return n; - - return NULL; -} - -void fwd_ipt_addif(struct fwd_handle *h, const char *net) -{ - struct fwd_data *e; - struct fwd_zone *z; - struct fwd_rule *c; - struct fwd_redirect *r; - struct fwd_forwarding *f; - struct fwd_cidr *a, *a2; - struct fwd_network *n, *n2; - struct fwd_proto p; - - struct fwd_xt_rule *x; - struct xtables_match *m; - struct xtables_target *t; - - struct iptc_handle *h_filter, *h_nat; - - if( !(h_filter = iptc_init("filter")) || !(h_nat = iptc_init("nat")) ) - fwd_fatal("Unable to obtain libiptc handle"); - - - if( !(z = fwd_lookup_zone(h, net)) ) - return; - - if( !(n = fwd_lookup_network(z, net)) ) - return; - - if( !(a = n->addr) || fwd_empty_cidr(a) ) - return; - - - fwd_log_info("Adding network %s (interface %s)", - n->name, n->ifname); - - /* Build masquerading rule */ - if( z->masq ) - { - if( (x = fwd_xt_init_rule(h_nat)) != NULL ) - { - fwd_xt_parse_out(x, n, 0); /* -o ... */ - fwd_xt_get_target(x, "MASQUERADE"); /* -j MASQUERADE */ - fwd_r_add_comment(x, "masq", z, n); /* -m comment ... */ - fwd_xt_append_rule(x, "zonemasq"); /* -A zonemasq */ - } - } - - /* Build MSS fix rule */ - if( z->mtu_fix ) - { - if( (x = fwd_xt_init_rule(h_filter)) != NULL ) - { - p.type = FWD_PR_TCP; - fwd_xt_parse_out(x, n, 0); /* -o ... */ - fwd_xt_parse_proto(x, &p, 0); /* -p tcp */ - - /* -m tcp --tcp-flags SYN,RST SYN */ - if( (m = fwd_xt_get_match(x, "tcp")) != NULL ) - fwd_xt_parse_match(x, m, "--tcp-flags", "SYN,RST", "SYN"); - - /* -j TCPMSS --clamp-mss-to-pmtu */ - if( (t = fwd_xt_get_target(x, "TCPMSS")) != NULL ) - fwd_xt_parse_target(x, t, "--clamp-mss-to-pmtu"); - - /* -m comment ... */ - fwd_r_add_comment(x, "mssfix", z, n); - - /* -A mssfix */ - fwd_xt_append_rule(x, "mssfix"); - } - } - - /* Build intra-zone forwarding rules */ - for( n2 = z->networks; n2; n2 = n2->next ) - { - if( (a2 = n2->addr) != NULL ) - { - if( (x = fwd_xt_init_rule(h_filter)) != NULL ) - { - fwd_xt_parse_in(x, n, 0); /* -i ... */ - fwd_xt_parse_out(x, n2, 0); /* -o ... */ - fwd_r_add_policytarget(x, z->forward); /* -j handle_... */ - fwd_r_add_comment(x, "zone", z, n); /* -m comment ... */ - fwd_xt_append_rule(x, "zones"); /* -A zones */ - } - } - } - - /* Build inter-zone forwarding rules */ - for( e = z->forwardings; e && (f = &e->section.forwarding); e = e->next ) - { - for( n2 = f->dest->networks; n2; n2 = n2->next ) - { - /* Build forwarding rule */ - if( (x = fwd_xt_init_rule(h_filter)) != NULL ) - { - fwd_xt_parse_in(x, n, 0); /* -i ... */ - fwd_xt_parse_out(x, n2, 0); /* -o ... */ - fwd_r_add_policytarget(x, FWD_P_ACCEPT); /* -j handle_... */ - fwd_r_add_comment(x, "forward", z, n); /* -m comment ... */ - fwd_xt_append_rule(x, "forwardings"); /* -A forwardings */ - } - } - } - - /* Build DNAT rules */ - for( e = z->redirects; e && (r = &e->section.redirect); e = e->next ) - { - /* DNAT */ - if( (x = fwd_xt_init_rule(h_nat)) != NULL ) - { - fwd_xt_parse_in(x, n, 0); /* -i ... */ - fwd_xt_parse_src(x, r->src_ip, 0); /* -s ... */ - fwd_xt_parse_dest(x, a, 0); /* -d ... */ - fwd_xt_parse_proto(x, r->proto, 0); /* -p ... */ - fwd_r_add_sport(x, r->src_port); /* --sport ... */ - fwd_r_add_dport(x, r->src_dport); /* --dport ... */ - fwd_r_add_srcmac(x, r->src_mac); /* -m mac --mac-source ... */ - fwd_r_add_dnattarget(x, r->dest_ip, r->dest_port); /* -j DNAT ... */ - fwd_r_add_comment(x, "redir", z, n); /* -m comment ... */ - fwd_xt_append_rule(x, "redirects"); /* -A redirects */ - } - - /* Forward */ - if( (x = fwd_xt_init_rule(h_filter)) != NULL ) - { - fwd_xt_parse_in(x, n, 0); /* -i ... */ - fwd_xt_parse_src(x, r->src_ip, 0); /* -s ... */ - fwd_xt_parse_dest(x, r->dest_ip, 0); /* -d ... */ - fwd_xt_parse_proto(x, r->proto, 0); /* -p ... */ - fwd_r_add_srcmac(x, r->src_mac); /* -m mac --mac-source ... */ - fwd_r_add_sport(x, r->src_port); /* --sport ... */ - fwd_r_add_dport(x, r->dest_port); /* --dport ... */ - fwd_r_add_policytarget(x, FWD_P_ACCEPT); /* -j handle_accept */ - fwd_r_add_comment(x, "redir", z, n); /* -m comment ... */ - fwd_xt_append_rule(x, "redirects"); /* -A redirects */ - } - - /* Add loopback rule if neither src_ip nor src_mac are defined */ - if( !r->src_ip && !r->src_mac ) - { - if( (x = fwd_xt_init_rule(h_nat)) != NULL ) - { - fwd_xt_parse_in(x, n, 1); /* -i ! ... */ - fwd_xt_parse_dest(x, r->dest_ip, 0); /* -d ... */ - fwd_xt_parse_proto(x, r->proto, 0); /* -p ... */ - fwd_r_add_sport(x, r->src_port); /* --sport ... */ - fwd_r_add_dport(x, r->src_dport); /* --dport ... */ - fwd_xt_get_target(x, "MASQUERADE"); /* -j MASQUERADE */ - fwd_r_add_comment(x, "redir", z, n); /* -m comment ... */ - fwd_xt_append_rule(x, "loopback"); /* -A loopback */ - } - } - } - - /* Build rules */ - for( e = z->rules; e && (c = &e->section.rule); e = e->next ) - { - /* Has destination, add forward rule for each network in target zone */ - if( c->dest ) - { - for( n2 = c->dest->networks; n2; n2 = n2->next ) - { - if( (x = fwd_xt_init_rule(h_filter)) != NULL ) - { - fwd_xt_parse_in(x, n, 0); /* -i ... */ - fwd_xt_parse_out(x, n2, 0); /* -o ... */ - fwd_xt_parse_src(x, c->src_ip, 0); /* -s ... */ - fwd_xt_parse_dest(x, c->dest_ip, 0); /* -d ... */ - fwd_xt_parse_proto(x, c->proto, 0); /* -p ... */ - fwd_r_add_icmptype(x, c->icmp_type); /* --icmp-type ... */ - fwd_r_add_srcmac(x, c->src_mac); /* --mac-source ... */ - fwd_r_add_sport(x, c->src_port); /* --sport ... */ - fwd_r_add_dport(x, c->dest_port); /* --dport ... */ - fwd_r_add_policytarget(x, c->target); /* -j handle_... */ - fwd_r_add_comment(x, "rule", z, n); /* -m comment ... */ - fwd_xt_append_rule(x, "rules"); /* -A rules */ - } - } - } - - /* No destination specified, treat it as input rule */ - else - { - if( (x = fwd_xt_init_rule(h_filter)) != NULL ) - { - fwd_xt_parse_in(x, n, 0); /* -i ... */ - fwd_xt_parse_src(x, c->src_ip, 0); /* -s ... */ - fwd_xt_parse_dest(x, c->dest_ip, 0); /* -d ... */ - fwd_xt_parse_proto(x, c->proto, 0); /* -p ... */ - fwd_r_add_icmptype(x, c->icmp_type); /* --icmp-type ... */ - fwd_r_add_srcmac(x, c->src_mac); /* --mac-source ... */ - fwd_r_add_sport(x, c->src_port); /* --sport ... */ - fwd_r_add_dport(x, c->dest_port); /* --dport ... */ - fwd_r_add_policytarget(x, c->target); /* -j handle_... */ - fwd_r_add_comment(x, "rule", z, n); /* -m comment ... */ - fwd_xt_append_rule(x, "rules"); /* -A rules */ - } - } - } - - if( !iptc_commit(h_nat) ) - fwd_fatal("Cannot commit nat table: %s", iptc_strerror(errno)); - - if( !iptc_commit(h_filter) ) - fwd_fatal("Cannot commit filter table: %s", iptc_strerror(errno)); - - iptc_free(h_nat); - iptc_free(h_filter); -} - - -static void fwd_ipt_delif_table(struct iptc_handle *h, const char *net) -{ - const struct xt_entry_match *m; - const struct ipt_entry *e; - const char *chain, *comment; - size_t off = 0, num = 0; - - /* iterate chains */ - for( chain = iptc_first_chain(h); chain; - chain = iptc_next_chain(h) - ) { - /* iterate rules */ - for( e = iptc_first_rule(chain, h), num = 0; e; - e = iptc_next_rule(e, h), num++ - ) { - repeat_rule: - - /* skip entries w/o matches */ - if( ! e->target_offset ) - continue; - - /* iterate matches */ - for( off = sizeof(struct ipt_entry); - off < e->target_offset; - off += m->u.match_size - ) { - m = (void *)e + off; - - /* yay */ - if( ! strcmp(m->u.user.name, "comment") ) - { - /* better use struct_xt_comment_info but well... */ - comment = (void *)m + sizeof(struct xt_entry_match); - - if( fwd_r_cmp("net=", comment, net) ) - { - e = iptc_next_rule(e, h); - iptc_delete_num_entry(chain, num, h); - - if( e != NULL ) - goto repeat_rule; - else - break; - } - } - } - } - } -} - -void fwd_ipt_delif(struct fwd_handle *h, const char *net) -{ - struct iptc_handle *h_filter, *h_nat; - - if( !(h_filter = iptc_init("filter")) || !(h_nat = iptc_init("nat")) ) - fwd_fatal("Unable to obtain libiptc handle"); - - - fwd_log_info("Removing network %s", net); - - /* delete network related rules */ - fwd_ipt_delif_table(h_nat, net); - fwd_ipt_delif_table(h_filter, net); - - - if( !iptc_commit(h_nat) ) - fwd_fatal("Cannot commit nat table: %s", iptc_strerror(errno)); - - if( !iptc_commit(h_filter) ) - fwd_fatal("Cannot commit filter table: %s", iptc_strerror(errno)); - - iptc_free(h_nat); - iptc_free(h_filter); -} - -void fwd_ipt_chgif(struct fwd_handle *h, const char *net) -{ - /* XXX: should alter rules in-place, tbd */ - fwd_ipt_delif(h, net); - fwd_ipt_addif(h, net); -} - - -static void fwd_ipt_clear_ruleset_table(struct iptc_handle *h) -{ - const char *chain; - - /* pass 1: flush all chains */ - for( chain = iptc_first_chain(h); chain; - chain = iptc_next_chain(h) - ) { - iptc_flush_entries(chain, h); - } - - /* pass 2: remove user defined chains */ - for( chain = iptc_first_chain(h); chain; - chain = iptc_next_chain(h) - ) { - if( ! iptc_builtin(chain, h) ) - iptc_delete_chain(chain, h); - } -} - -void fwd_ipt_clear_ruleset(struct fwd_handle *h) -{ - struct iptc_handle *h_filter, *h_nat; - - if( !(h_filter = iptc_init("filter")) || !(h_nat = iptc_init("nat")) ) - fwd_fatal("Unable to obtain libiptc handle"); - - /* flush tables */ - fwd_ipt_clear_ruleset_table(h_nat); - fwd_ipt_clear_ruleset_table(h_filter); - - /* revert policies */ - fwd_r_set_policy(h_filter, "INPUT", "ACCEPT"); - fwd_r_set_policy(h_filter, "OUTPUT", "ACCEPT"); - fwd_r_set_policy(h_filter, "FORWARD", "ACCEPT"); - - - if( !iptc_commit(h_nat) ) - fwd_fatal("Cannot commit nat table: %s", iptc_strerror(errno)); - - if( !iptc_commit(h_filter) ) - fwd_fatal("Cannot commit filter table: %s", iptc_strerror(errno)); - - iptc_free(h_nat); - iptc_free(h_filter); -} - diff --git a/contrib/fwd/src/fwd_rules.h b/contrib/fwd/src/fwd_rules.h deleted file mode 100644 index b9eabd870..000000000 --- a/contrib/fwd/src/fwd_rules.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * fwd - OpenWrt firewall daemon - header for iptables rule set - * - * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org> - * - * The fwd program is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * The fwd program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with the fwd program. If not, see http://www.gnu.org/licenses/. - */ - -#ifndef __FWD_RULES_H__ -#define __FWD_RULES_H__ - -#include "fwd.h" - -void fwd_ipt_build_ruleset(struct fwd_handle *h); -void fwd_ipt_clear_ruleset(struct fwd_handle *h); - -void fwd_ipt_addif(struct fwd_handle *h, const char *net); -void fwd_ipt_delif(struct fwd_handle *h, const char *net); -void fwd_ipt_chgif(struct fwd_handle *h, const char *net); - -#endif - diff --git a/contrib/fwd/src/fwd_utils.c b/contrib/fwd/src/fwd_utils.c deleted file mode 100644 index 170ecf468..000000000 --- a/contrib/fwd/src/fwd_utils.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * fwd - OpenWrt firewall daemon - commmon utility functions - * - * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org> - * - * The fwd program is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * The fwd program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with the fwd program. If not, see http://www.gnu.org/licenses/. - */ - - -#include "fwd_utils.h" - - -void fwd_log_init(void) -{ - openlog("Firewall", 0, LOG_DAEMON | LOG_PERROR); -} - -void __fwd_log(int prio, const char *msg, ...) -{ - va_list ap; - va_start(ap, msg); - vsyslog(prio, msg, ap); - va_end(ap); -} - - - -int fwd_empty_cidr(struct fwd_cidr *c) -{ - if( (c == NULL) || ((c->addr.s_addr == 0) && (c->prefix == 0)) ) - return 1; - - return 0; -} - -int fwd_equal_cidr(struct fwd_cidr *a, struct fwd_cidr *b) -{ - if( fwd_empty_cidr(a) && fwd_empty_cidr(b) ) - return 1; - else if( (a->addr.s_addr == b->addr.s_addr) && (a->prefix == b->prefix) ) - return 1; - - return 0; -} - -void fwd_update_cidr(struct fwd_cidr *a, struct fwd_cidr *b) -{ - if( a != NULL ) - { - a->addr.s_addr = b ? b->addr.s_addr : 0; - a->prefix = b ? b->prefix : 0; - } -} - - -/* fwd_zmalloc(size_t) - * Allocates a zeroed buffer of the given size. */ -void * fwd_zmalloc(size_t s) -{ - void *b = malloc(s); - - if( b != NULL ) - memset(b, 0, s); - - return b; -} - - diff --git a/contrib/fwd/src/fwd_utils.h b/contrib/fwd/src/fwd_utils.h deleted file mode 100644 index 618a53784..000000000 --- a/contrib/fwd/src/fwd_utils.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * fwd - OpenWrt firewall daemon - commmon utility header - * - * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org> - * - * The fwd program is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * The fwd program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with the fwd program. If not, see http://www.gnu.org/licenses/. - */ - -#ifndef __FWD_UTILS_H__ -#define __FWD_UTILS_H__ - -#include <syslog.h> - -#include "fwd.h" - -void fwd_log_init(void); -void __fwd_log(int, const char *, ...); -#define fwd_log_info(...) __fwd_log(LOG_INFO, __VA_ARGS__) -#define fwd_log_err(...) __fwd_log(LOG_ERR, __VA_ARGS__) - -int fwd_empty_cidr(struct fwd_cidr *); -int fwd_equal_cidr(struct fwd_cidr *, struct fwd_cidr *); -void fwd_update_cidr(struct fwd_cidr *, struct fwd_cidr *); - -/* fwd_zmalloc(size_t) - * Allocates a zeroed buffer of the given size. */ -void * fwd_zmalloc(size_t); - -/* fwd_alloc_ptr(type) - * Allocates a buffer with the size of the given datatype - * and returns a pointer to it. */ -#define fwd_alloc_ptr(t) (t *) fwd_zmalloc(sizeof(t)) - -/* fwd_free_ptr(void *) - * Frees the given pointer and sets it to NULL. - * Safe for NULL values. */ -#define fwd_free_ptr(x) do { if(x != NULL) free(x); x = NULL; } while(0) - -#endif - diff --git a/contrib/fwd/src/fwd_xtables.c b/contrib/fwd/src/fwd_xtables.c deleted file mode 100644 index 895715d92..000000000 --- a/contrib/fwd/src/fwd_xtables.c +++ /dev/null @@ -1,412 +0,0 @@ -/* - * fwd - OpenWrt firewall daemon - libiptc/libxtables interface - * - * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org> - * - * The fwd program is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * The fwd program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with the fwd program. If not, see http://www.gnu.org/licenses/. - */ - - -#include "fwd.h" -#include "fwd_xtables.h" -#include "fwd_utils.h" - - -/* Required by certain extensions like SNAT and DNAT */ -int kernel_version; - -extern void -get_kernel_version(void) { - static struct utsname uts; - int x = 0, y = 0, z = 0; - - if (uname(&uts) == -1) { - fprintf(stderr, "Unable to retrieve kernel version.\n"); - xtables_free_opts(1); - exit(1); - } - - sscanf(uts.release, "%d.%d.%d", &x, &y, &z); - kernel_version = LINUX_VERSION(x, y, z); -} - - -static void xt_exit_error(enum xtables_exittype status, const char *msg, ...) -{ - va_list ap; - va_start(ap, msg); - vprintf(msg, ap); - va_end(ap); - exit(1); -} - -void fwd_xt_init(void) -{ - struct xtables_globals xt_globals = { - .option_offset = 0, - .program_version = IPTABLES_VERSION, - .opts = 0, - .orig_opts = 0, - .exit_err = (void *)&xt_exit_error, - }; - - xtables_init(); - xtables_set_nfproto(NFPROTO_IPV4); - xtables_set_params(&xt_globals); -} - - -struct fwd_xt_rule * fwd_xt_init_rule(struct iptc_handle *h) -{ - struct fwd_xt_rule *r; - - if( (r = fwd_alloc_ptr(struct fwd_xt_rule)) != NULL ) - { - if( (r->entry = fwd_alloc_ptr(struct ipt_entry)) != NULL ) - { - r->iptc = h; - return r; - } - } - - fwd_free_ptr(r); - return NULL; -} - -void fwd_xt_parse_frag( - struct fwd_xt_rule *r, int frag, int inv -) { - if( frag ) - { - r->entry->ip.flags |= IPT_F_FRAG; - - if( inv ) - r->entry->ip.invflags |= IPT_INV_FRAG; - } -} - -void fwd_xt_parse_proto( - struct fwd_xt_rule *r, struct fwd_proto *p, int inv -) { - if( p != NULL ) - { - switch(p->type) - { - case FWD_PR_TCP: - r->entry->ip.proto = 6; - break; - - case FWD_PR_UDP: - r->entry->ip.proto = 17; - break; - - case FWD_PR_ICMP: - r->entry->ip.proto = 1; - break; - - case FWD_PR_CUSTOM: - r->entry->ip.proto = p->proto; - break; - - case FWD_PR_ALL: - case FWD_PR_TCPUDP: - r->entry->ip.proto = 0; - break; - } - - if( inv ) - r->entry->ip.invflags |= IPT_INV_PROTO; - } -} - -void fwd_xt_parse_in( - struct fwd_xt_rule *r, struct fwd_network *n, int inv -) { - if( n != NULL ) - { - strncpy(r->entry->ip.iniface, n->ifname, IFNAMSIZ); - - if( inv ) - r->entry->ip.invflags |= IPT_INV_VIA_IN; - } -} - -void fwd_xt_parse_out( - struct fwd_xt_rule *r, struct fwd_network *n, int inv -) { - if( n != NULL ) - { - strncpy(r->entry->ip.outiface, n->ifname, IFNAMSIZ); - - if( inv ) - r->entry->ip.invflags |= IPT_INV_VIA_OUT; - } -} - -void fwd_xt_parse_src( - struct fwd_xt_rule *r, struct fwd_cidr *c, int inv -) { - if( c != NULL ) - { - r->entry->ip.src.s_addr = c->addr.s_addr; - r->entry->ip.smsk.s_addr = htonl(~((1 << (32 - c->prefix)) - 1)); - - if( inv ) - r->entry->ip.invflags |= IPT_INV_SRCIP; - } -} - -void fwd_xt_parse_dest( - struct fwd_xt_rule *r, struct fwd_cidr *c, int inv -) { - if( c != NULL ) - { - r->entry->ip.dst.s_addr = c->addr.s_addr; - r->entry->ip.dmsk.s_addr = htonl(~((1 << (32 - c->prefix)) - 1)); - - if( inv ) - r->entry->ip.invflags |= IPT_INV_DSTIP; - } -} - - -struct xtables_match * fwd_xt_get_match( - struct fwd_xt_rule *r, const char *name -) { - struct xtables_match *m = xtables_find_match(name, XTF_TRY_LOAD, &r->matches); - size_t s; - - if( m != NULL ) - { - s = IPT_ALIGN(sizeof(struct ipt_entry_match)) + m->size; - - if( (m->m = malloc(s)) != NULL ) - { - memset(m->m, 0, s); - strcpy(m->m->u.user.name, m->name); - m->m->u.match_size = s; - - if( m->init ) - m->init(m->m); - - return m; - } - } - - return NULL; -} - -void __fwd_xt_parse_match( - struct fwd_xt_rule *r, struct xtables_match *m, ... -) { - char optc; - char *s, **opts; - size_t len = 1; - int inv = 0; - - va_list ap; - va_start(ap, m); - - opts = malloc(len * sizeof(*opts)); - opts[0] = "x"; - - while( (s = (char *)va_arg(ap, char *)) != NULL ) - { - opts = realloc(opts, ++len * sizeof(*opts)); - opts[len-1] = s; - } - - va_end(ap); - - if( len > 1 ) - { - optind = 0; - - while( (optc = getopt_long(len, opts, "", m->extra_opts, NULL)) > -1 ) - { - if( (optc == '?') && (optarg[0] == '!') && (optarg[1] == '\0') ) - { - inv = 1; - continue; - } - - m->parse(optc, opts, inv, &m->mflags, r->entry, &m->m); - inv = 0; - } - } - - free(opts); -} - - -struct xtables_target * fwd_xt_get_target( - struct fwd_xt_rule *r, const char *name -) { - struct xtables_target *t = xtables_find_target(name, XTF_TRY_LOAD); - size_t s; - - if( !t ) - t = xtables_find_target(IPT_STANDARD_TARGET, XTF_LOAD_MUST_SUCCEED); - - if( t != NULL ) - { - s = IPT_ALIGN(sizeof(struct ipt_entry_target)) + t->size; - - if( (t->t = malloc(s)) != NULL ) - { - memset(t->t, 0, s); - strcpy(t->t->u.user.name, name); - t->t->u.target_size = s; - xtables_set_revision(t->t->u.user.name, t->revision); - - if( t->init ) - t->init(t->t); - - r->target = t; - - return t; - } - } - - return NULL; -} - -void __fwd_xt_parse_target( - struct fwd_xt_rule *r, struct xtables_target *t, ... -) { - char optc; - char *s, **opts; - size_t len = 1; - int inv = 0; - - va_list ap; - va_start(ap, t); - - opts = malloc(len * sizeof(*opts)); - opts[0] = "x"; - - while( (s = (char *)va_arg(ap, char *)) != NULL ) - { - opts = realloc(opts, ++len * sizeof(*opts)); - opts[len-1] = s; - } - - va_end(ap); - - if( len > 1 ) - { - optind = 0; - - while( (optc = getopt_long(len, opts, "", t->extra_opts, NULL)) > -1 ) - { - if( (optc == '?') && (optarg[0] == '!') && (optarg[1] == '\0') ) - { - inv = 1; - continue; - } - - t->parse(optc, opts, inv, &t->tflags, r->entry, &t->t); - inv = 0; - } - } - - free(opts); -} - - -static int fwd_xt_exec_rule(struct fwd_xt_rule *r, const char *chain, int pos) -{ - size_t s; - struct xtables_rule_match *m, *next; - struct xtables_match *em; - struct xtables_target *et; - struct ipt_entry *e; - int rv = 0; - - s = IPT_ALIGN(sizeof(struct ipt_entry)); - - for( m = r->matches; m; m = m->next ) - s += m->match->m->u.match_size; - - if( (e = malloc(s + r->target->t->u.target_size)) != NULL ) - { - memset(e, 0, s + r->target->t->u.target_size); - memcpy(e, r->entry, sizeof(struct ipt_entry)); - - e->target_offset = s; - e->next_offset = s + r->target->t->u.target_size; - - s = 0; - - for( m = r->matches; m; m = m->next ) - { - memcpy(e->elems + s, m->match->m, m->match->m->u.match_size); - s += m->match->m->u.match_size; - } - - memcpy(e->elems + s, r->target->t, r->target->t->u.target_size); - - rv = (pos > -1) - ? iptc_insert_entry(chain, e, (unsigned int) pos, r->iptc) - : iptc_append_entry(chain, e, r->iptc) - ; - } - else - { - errno = ENOMEM; - } - - - fwd_free_ptr(e); - fwd_free_ptr(r->entry); - fwd_free_ptr(r->target->t); - - for( m = r->matches; m; ) - { - next = m->next; - fwd_free_ptr(m->match->m); - - if( m->match == m->match->next ) - fwd_free_ptr(m->match); - - fwd_free_ptr(m); - m = next; - } - - fwd_free_ptr(r); - - /* reset all targets and matches */ - for (em = xtables_matches; em; em = em->next) - em->mflags = 0; - - for (et = xtables_targets; et; et = et->next) - { - et->tflags = 0; - et->used = 0; - } - - return rv; -} - -int fwd_xt_insert_rule( - struct fwd_xt_rule *r, const char *chain, unsigned int pos -) { - return fwd_xt_exec_rule(r, chain, pos); -} - -int fwd_xt_append_rule( - struct fwd_xt_rule *r, const char *chain -) { - return fwd_xt_exec_rule(r, chain, -1); -} - diff --git a/contrib/fwd/src/fwd_xtables.h b/contrib/fwd/src/fwd_xtables.h deleted file mode 100644 index 1ac57bb0e..000000000 --- a/contrib/fwd/src/fwd_xtables.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * fwd - OpenWrt firewall daemon - libiptc/libxtables interface headers - * - * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org> - * - * The fwd program is free software: you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * The fwd program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with the fwd program. If not, see http://www.gnu.org/licenses/. - */ - - -#ifndef __FWD_XTABLES_H__ -#define __FWD_XTABLES_H__ - -#include <iptables.h> -#include <xtables.h> -#include <libiptc/libxtc.h> - -#include <dlfcn.h> -#include <errno.h> - -#include <sys/stat.h> -#include <sys/utsname.h> - - - -struct fwd_xt_rule { - struct iptc_handle *iptc; - struct ipt_entry *entry; - struct xtables_rule_match *matches; - struct xtables_target *target; -}; - - -/* Required by certain extensions like SNAT and DNAT */ -extern int kernel_version; -extern void get_kernel_version(void); - - -void fwd_xt_init(void); - -struct fwd_xt_rule * fwd_xt_init_rule(struct iptc_handle *h); - -void fwd_xt_parse_proto(struct fwd_xt_rule *r, struct fwd_proto *p, int inv); -void fwd_xt_parse_in(struct fwd_xt_rule *r, struct fwd_network *n, int inv); -void fwd_xt_parse_out(struct fwd_xt_rule *r, struct fwd_network *n, int inv); -void fwd_xt_parse_src(struct fwd_xt_rule *r, struct fwd_cidr *c, int inv); -void fwd_xt_parse_dest(struct fwd_xt_rule *r, struct fwd_cidr *c, int inv); -void fwd_xt_parse_frag(struct fwd_xt_rule *r, int frag, int inv); - -struct xtables_match * fwd_xt_get_match(struct fwd_xt_rule *r, const char *name); -void __fwd_xt_parse_match(struct fwd_xt_rule *r, struct xtables_match *m, ...); -#define fwd_xt_parse_match(r, m, ...) __fwd_xt_parse_match(r, m, __VA_ARGS__, NULL) - -struct xtables_target * fwd_xt_get_target(struct fwd_xt_rule *r, const char *name); -void __fwd_xt_parse_target(struct fwd_xt_rule *r, struct xtables_target *t, ...); -#define fwd_xt_parse_target(r, t, ...) __fwd_xt_parse_target(r, t, __VA_ARGS__, NULL) - -int fwd_xt_append_rule(struct fwd_xt_rule *r, const char *chain); -int fwd_xt_insert_rule(struct fwd_xt_rule *r, const char *chain, unsigned int pos); - -#endif diff --git a/contrib/fwd/src/ucix.c b/contrib/fwd/src/ucix.c deleted file mode 100644 index 1d2d87f6d..000000000 --- a/contrib/fwd/src/ucix.c +++ /dev/null @@ -1,236 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - * - * Copyright (C) 2008 John Crispin <blogic@openwrt.org> - */ - -#include <string.h> -#include <stdlib.h> -#include <ctype.h> - -#include <uci_config.h> -#include <uci.h> -#include "ucix.h" - -static struct uci_ptr ptr; - -static inline int ucix_get_ptr(struct uci_context *ctx, const char *p, const char *s, const char *o, const char *t) -{ - memset(&ptr, 0, sizeof(ptr)); - ptr.package = p; - ptr.section = s; - ptr.option = o; - ptr.value = t; - return uci_lookup_ptr(ctx, &ptr, NULL, true); -} - -struct uci_context* ucix_init(const char *config_file) -{ - struct uci_context *ctx = uci_alloc_context(); - uci_add_history_path(ctx, "/var/state"); - if(uci_load(ctx, config_file, NULL) != UCI_OK) - { - printf("%s/%s is missing or corrupt\n", ctx->savedir, config_file); - return NULL; - } - return ctx; -} - -struct uci_context* ucix_init_path(const char *path, const char *config_file) -{ - struct uci_context *ctx = uci_alloc_context(); - if(path) - uci_set_confdir(ctx, path); - if(uci_load(ctx, config_file, NULL) != UCI_OK) - { - printf("%s/%s is missing or corrupt\n", ctx->savedir, config_file); - return NULL; - } - return ctx; -} - -int ucix_load(struct uci_context *ctx, const char *config_file) -{ - if(uci_load(ctx, config_file, NULL) != UCI_OK) - { - printf("%s/%s is missing or corrupt\n", ctx->savedir, config_file); - return 0; - } - return 1; -} - -void ucix_cleanup(struct uci_context *ctx) -{ - uci_free_context(ctx); -} - -void ucix_save(struct uci_context *ctx) -{ - uci_set_savedir(ctx, "/tmp/.uci/"); - uci_save(ctx, NULL); -} - -void ucix_save_state(struct uci_context *ctx) -{ - uci_set_savedir(ctx, "/var/state/"); - uci_save(ctx, NULL); -} - -const char* ucix_get_option(struct uci_context *ctx, const char *p, const char *s, const char *o) -{ - struct uci_element *e = NULL; - const char *value = NULL; - if(ucix_get_ptr(ctx, p, s, o, NULL)) - return NULL; - if (!(ptr.flags & UCI_LOOKUP_COMPLETE)) - return NULL; - e = ptr.last; - switch (e->type) - { - case UCI_TYPE_SECTION: - value = uci_to_section(e)->type; - break; - - case UCI_TYPE_OPTION: - switch(ptr.o->type) { - case UCI_TYPE_STRING: - value = ptr.o->v.string; - break; - default: - value = NULL; - break; - } - break; - - default: - return 0; - } - - return value; -} - -int ucix_for_each_list( - struct uci_context *ctx, const char *p, const char *s, const char *o, - void (*cb)(const char*, void*), void *priv) -{ - struct uci_element *e = NULL; - char *value = NULL; - int count = 0; - if(ucix_get_ptr(ctx, p, s, o, NULL)) - return -1; - if (!(ptr.flags & UCI_LOOKUP_COMPLETE)) - return -1; - e = ptr.last; - if(e->type == UCI_TYPE_OPTION) - { - switch(ptr.o->type) - { - case UCI_TYPE_LIST: - uci_foreach_element(&ptr.o->v.list, e) { - cb(e->name, priv); - count++; - } - break; - - case UCI_TYPE_STRING: - if( (value = strdup(ptr.o->v.string)) != NULL ) - { - char *ts, *tt, *tp; - for( ts = value; 1; ts = NULL ) - { - if( (tt = strtok_r(ts, " \t", &tp)) != NULL ) - { - cb(tt, priv); - count++; - } - else - { - break; - } - } - free(value); - } - break; - } - - return count; - } - - return -1; -} - -int ucix_get_option_int(struct uci_context *ctx, const char *p, const char *s, const char *o, int def) -{ - const char *tmp = ucix_get_option(ctx, p, s, o); - int ret = def; - - if (tmp) - ret = atoi(tmp); - return ret; -} - -void ucix_add_section(struct uci_context *ctx, const char *p, const char *s, const char *t) -{ - if(ucix_get_ptr(ctx, p, s, NULL, t)) - return; - uci_set(ctx, &ptr); -} - -void ucix_add_option(struct uci_context *ctx, const char *p, const char *s, const char *o, const char *t) -{ - if(ucix_get_ptr(ctx, p, s, o, (t)?(t):(""))) - return; - uci_set(ctx, &ptr); -} - -void ucix_add_option_int(struct uci_context *ctx, const char *p, const char *s, const char *o, int t) -{ - char tmp[64]; - snprintf(tmp, 64, "%d", t); - ucix_add_option(ctx, p, s, o, tmp); -} - -void ucix_del(struct uci_context *ctx, const char *p, const char *s, const char *o) -{ - if(!ucix_get_ptr(ctx, p, s, o, NULL)) - uci_delete(ctx, &ptr); -} - -void ucix_revert(struct uci_context *ctx, const char *p, const char *s, const char *o) -{ - if(!ucix_get_ptr(ctx, p, s, o, NULL)) - uci_revert(ctx, &ptr); -} - -void ucix_for_each_section_type(struct uci_context *ctx, - const char *p, const char *t, - void (*cb)(struct uci_context *, const char*, void*), void *priv) -{ - struct uci_element *e; - if(ucix_get_ptr(ctx, p, NULL, NULL, NULL)) - return; - uci_foreach_element(&ptr.p->sections, e) - if (!strcmp(t, uci_to_section(e)->type)) - cb(ctx, e->name, priv); -} - -int ucix_commit(struct uci_context *ctx, const char *p) -{ - if(ucix_get_ptr(ctx, p, NULL, NULL, NULL)) - return 1; - return uci_commit(ctx, &ptr.p, false); -} - - diff --git a/contrib/fwd/src/ucix.h b/contrib/fwd/src/ucix.h deleted file mode 100644 index d77ac8530..000000000 --- a/contrib/fwd/src/ucix.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - * - * Copyright (C) 2008 John Crispin <blogic@openwrt.org> - */ - -#ifndef __UCIX_H__ -#define __UCIX_H_ - -struct uci_context* ucix_init(const char *config_file); -struct uci_context* ucix_init_path(const char *path, const char *config_file); -int ucix_load(struct uci_context *ctx, const char *config_file); -void ucix_cleanup(struct uci_context *ctx); -void ucix_save(struct uci_context *ctx); -void ucix_save_state(struct uci_context *ctx); -const char* ucix_get_option(struct uci_context *ctx, - const char *p, const char *s, const char *o); -int ucix_for_each_list(struct uci_context *ctx, - const char *p, const char *s, const char *o, - void (*cb)(const char*, void*), void *priv); -int ucix_get_option_int(struct uci_context *ctx, - const char *p, const char *s, const char *o, int def); -void ucix_add_section(struct uci_context *ctx, - const char *p, const char *s, const char *t); -void ucix_add_option(struct uci_context *ctx, - const char *p, const char *s, const char *o, const char *t); -void ucix_add_option_int(struct uci_context *ctx, - const char *p, const char *s, const char *o, int t); -void ucix_for_each_section_type(struct uci_context *ctx, - const char *p, const char *t, - void (*cb)(struct uci_context *, const char*, void*), void *priv); -int ucix_commit(struct uci_context *ctx, const char *p); -void ucix_revert(struct uci_context *ctx, - const char *p, const char *s, const char *o); -void ucix_del(struct uci_context *ctx, const char *p, - const char *s, const char *o); -#endif - diff --git a/contrib/lar/Makefile b/contrib/lar/Makefile deleted file mode 100644 index 5199546e7..000000000 --- a/contrib/lar/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -GCC := gcc -CFLAGS := -Wall -LDFLAGS := - -OBJ = cli.o lar.o md5.o -BIN = lar - -compile: -cli: $(OBJ) - $(GCC) $(CFLAGS) -o $(BIN) $(OBJ) $(LDFLAGS) - -clean: - rm -f $(OBJ) $(BIN) diff --git a/contrib/lar/cli.c b/contrib/lar/cli.c deleted file mode 100644 index 36216d46e..000000000 --- a/contrib/lar/cli.c +++ /dev/null @@ -1,131 +0,0 @@ -#include "lar.h" - -int do_print_member( lar_archive *ar, const char *name ) -{ - lar_member *member; - - if( (member = lar_open_member(ar, name)) != NULL ) - { - write(fileno(stdout), member->data, member->length); - lar_close_member(member); - } - else - LAR_DIE("Unable to locate archive member"); - - return 0; -} - -int do_print_index( lar_archive *ar ) -{ - lar_index *index = ar->index; - - if( ar->has_filenames ) - { - while(index) - { - if( index->type == LAR_TYPE_REGULAR ) - { - printf("%s\n", index->filename); - } - - index = index->next; - } - - return 0; - } - - LAR_DIE("The archive contains no file list"); - return 1; -} - -int do_require( const char *package, const char *path ) -{ - int stat = 1; - lar_archive *ar; - lar_member *mb; - - if( (ar = lar_find_archive(package, path, 1)) != NULL ) - { - if( (mb = lar_find_member(ar, package)) != NULL ) - { - write(fileno(stdout), mb->data, mb->length); - lar_close_member(mb); - stat = 0; - } - - lar_close(ar); - } - - return stat; -} - -int do_findfile( const char *filename, const char *path ) -{ - int stat = 1; - lar_archive *ar; - lar_member *mb; - - if( (ar = lar_find_archive(filename, path, 0)) != NULL ) - { - if( (mb = lar_open_member(ar, filename)) != NULL ) - { - write(fileno(stdout), mb->data, mb->length); - lar_close_member(mb); - stat = 0; - } - - lar_close(ar); - } - - return stat; -} - -int main( int argc, const char* argv[] ) -{ - lar_archive *ar; - int stat = 0; - - if( argv[1] != NULL && argv[2] != NULL ) - { - switch(argv[1][0]) - { - case 's': - if( (ar = lar_open(argv[2])) != NULL ) - { - if( argv[3] != NULL ) - stat = do_print_member(ar, argv[3]); - else - stat = do_print_index(ar); - - lar_close(ar); - } - else - { - LAR_DIE("Failed to open archive"); - } - - break; - - case 'r': - stat = do_require(argv[2], argv[3]); - break; - - case 'f': - stat = do_findfile(argv[2], argv[3]); - break; - } - - return stat; - } - else - { - printf("Usage:\n"); - printf("\tlar show <archive> [<member>]\n"); - printf("\tlar require <package> [<path>]\n"); - printf("\tlar find <filename> [<path>]\n"); - - return 1; - } - - return 0; -} diff --git a/contrib/lar/lar.c b/contrib/lar/lar.c deleted file mode 100644 index 2a0fa7da6..000000000 --- a/contrib/lar/lar.c +++ /dev/null @@ -1,328 +0,0 @@ -/* - * lar - Lua Archive Library - * - * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -#include "lar.h" - -static int lar_read32( int fd, uint32_t *val ) -{ - uint8_t buffer[5]; - - if( read(fd, buffer, 4) < 4 ) - LAR_DIE("Unexpected EOF while reading data"); - - buffer[4] = 0; - *val = ntohl(*((uint32_t *) buffer)); - - return 0; -} - -static int lar_read16( int fd, uint16_t *val ) -{ - uint8_t buffer[3]; - - if( read(fd, buffer, 2) < 2 ) - LAR_DIE("Unexpected EOF while reading data"); - - buffer[2] = 0; - *val = ntohs(*((uint16_t *) buffer)); - - return 0; -} - -static void lar_md5( char *md5, const char *data, int len ) -{ - md5_state_t state; - - md5_init(&state); - md5_append(&state, (const md5_byte_t *)data, len); - md5_finish(&state, (md5_byte_t *)md5); -} - -static int lar_read_filenames( lar_archive *ar ) -{ - int i; - int j; - char *filelist; - size_t pgof; - size_t pgsz = getpagesize(); - lar_index *idx_ptr; - lar_index *idx_filelist = ar->index; - - while(idx_filelist) - { - if( idx_filelist->type == LAR_TYPE_FILELIST ) - break; - - idx_filelist = idx_filelist->next; - } - - if( idx_filelist != NULL ) - { - pgof = ( idx_filelist->offset % pgsz ); - - filelist = mmap( - 0, idx_filelist->length + pgof, PROT_READ, MAP_PRIVATE, - ar->fd, idx_filelist->offset - pgof - ); - - if( filelist == MAP_FAILED ) - LAR_DIE("Failed to mmap() file list"); - - - idx_ptr = ar->index; - i = pgof; - - while(idx_ptr) - { - if( idx_ptr->type == LAR_TYPE_REGULAR ) - { - j = strlen(&filelist[i]) + 1; - - if( (j >= LAR_FNAME_BUFFER) || - ((i+j) > (idx_filelist->length+pgof)) ) - LAR_DIE("Filename exceeds maximum allowed length"); - - idx_ptr->filename = (char *)malloc(j); - memcpy(idx_ptr->filename, &filelist[i], j); - - i += j; - } - - idx_ptr = idx_ptr->next; - } - - munmap(filelist, idx_filelist->length + pgof); - - return 1; - } - - return 0; -} - -lar_index * lar_get_index( lar_archive *ar ) -{ - uint32_t i; - uint32_t idx_offset; - uint32_t idx_length; - lar_index *idx_map; - lar_index *idx_ptr; - - if( lseek(ar->fd, -(sizeof(idx_offset)), SEEK_END) == -1 ) - LAR_DIE("Unable to seek to end of archive"); - - lar_read32(ar->fd, &idx_offset); - idx_length = ( ar->length - idx_offset - sizeof(idx_offset) ); - - if( lseek(ar->fd, idx_offset, SEEK_SET) == -1 ) - LAR_DIE("Unable to seek to archive index"); - - - idx_map = NULL; - - for( i = 0; i < idx_length; i += (sizeof(lar_index) - 2 * sizeof(char *)) ) - { - idx_ptr = (lar_index *)malloc(sizeof(lar_index)); - idx_ptr->filename = NULL; - - lar_read32(ar->fd, &idx_ptr->offset); - lar_read32(ar->fd, &idx_ptr->length); - lar_read16(ar->fd, &idx_ptr->type); - lar_read16(ar->fd, &idx_ptr->flags); - - if(read(ar->fd,&idx_ptr->id,sizeof(idx_ptr->id)) < sizeof(idx_ptr->id)) - LAR_DIE("Unexpected EOF while reading member id"); - - idx_ptr->next = idx_map; - idx_map = idx_ptr; - } - - return idx_map; -} - -lar_member * lar_mmap_member( lar_archive *ar, lar_index *idx_ptr ) -{ - lar_member *member; - size_t pgsz = getpagesize(); - size_t pgof = ( idx_ptr->offset % pgsz ); - - char *memberdata = mmap( - 0, idx_ptr->length + pgof, PROT_READ, MAP_PRIVATE, - ar->fd, idx_ptr->offset - pgof - ); - - if( memberdata == MAP_FAILED ) - LAR_DIE("Failed to mmap() member data"); - - member = (lar_member *)malloc(sizeof(lar_member)); - member->type = idx_ptr->type; - member->flags = idx_ptr->flags; - member->length = idx_ptr->length; - member->data = &memberdata[pgof]; - - member->mmap = memberdata; - member->mlen = idx_ptr->length + pgof; - - return member; -} - -lar_member * lar_open_member( lar_archive *ar, const char *name ) -{ - lar_index *idx_ptr = ar->index; - char mbid[sizeof(idx_ptr->id)]; - - lar_md5(mbid, name, strlen(name)); - - while(idx_ptr) - { - if( !strncmp(mbid, idx_ptr->id, sizeof(mbid)) ) - return lar_mmap_member(ar, idx_ptr); - - idx_ptr = idx_ptr->next; - } - - return NULL; -} - -int lar_close_member( lar_member *member ) -{ - int stat = munmap(member->mmap, member->mlen); - free(member); - member = NULL; - - return stat; -} - -lar_archive * lar_open( const char *filename ) -{ - int fd; - struct stat as; - lar_archive *ar; - - if( stat(filename, &as) == -1 ) - return NULL; - - if( !(as.st_mode & S_IFREG) ) - return NULL; - - if( (fd = open(filename, O_RDONLY)) != -1 ) - { - ar = (lar_archive *)malloc(sizeof(lar_archive)); - ar->fd = fd; - ar->length = as.st_size; - ar->index = lar_get_index(ar); - strncpy(ar->filename, filename, sizeof(ar->filename)); - - ar->has_filenames = lar_read_filenames(ar); - - return ar; - } - - return NULL; -} - -int lar_close( lar_archive *ar ) -{ - lar_index *idx_head; - lar_index *idx_next; - - close(ar->fd); - - idx_head = ar->index; - do { - idx_next = idx_head->next; - free(idx_head->filename); - free(idx_head); - } while( (idx_head = idx_next) != NULL ); - - free(ar); - ar = NULL; - - return 0; -} - -lar_archive * lar_find_archive( const char *package, const char *path, int pkg ) -{ - uint32_t i; - uint32_t j; - uint32_t seg = 1; - uint32_t len = 0; - uint32_t pln = 0; - char sep = ( pkg ? '.' : '/' ); - struct stat s; - LAR_FNAME(buffer); - - if( path ) - { - for( pln = 0; path[pln] != '\0'; pln++ ) - if( pln >= (sizeof(buffer) - 5) ) - LAR_DIE("Library path exceeds maximum allowed length"); - - memcpy(buffer, path, pln); - } - - if( buffer[pln-1] != '/' ) - buffer[pln++] = '/'; - - for( len = 0; package[len] != '\0'; len++ ) - { - if( len >= (sizeof(buffer) - 5 - pln) ) - LAR_DIE("Package name exceeds maximum allowed length"); - - if( package[len] == sep ) seg++; - } - - while( seg > 0 ) - { - for( i = 0, j = 1; (i < len) && (j <= seg); i++ ) - { - if( package[i] == sep ) { - if( j < seg ) j++; else break; - } - - buffer[pln+i] = ( package[i] == sep ) ? LAR_DIRSEP : package[i]; - } - - strcpy(&buffer[pln+i], ".lar"); - - if( (stat(buffer, &s) > -1) && (s.st_mode & S_IFREG) ) - return lar_open(buffer); - - seg--; - } - - return NULL; -} - -lar_member * lar_find_member( lar_archive *ar, const char *package ) -{ - int len; - LAR_FNAME(buffer); - - for( len = 0; package[len] != '\0'; len++ ) - { - if( len >= (sizeof(buffer) - 5) ) - LAR_DIE("Package name exceeds maximum allowed length"); - - buffer[len] = ( package[len] == '.' ) ? '/' : package[len]; - } - - strcpy(&buffer[len], ".lua"); - - return lar_open_member(ar, buffer); -} diff --git a/contrib/lar/lar.h b/contrib/lar/lar.h deleted file mode 100644 index 5888f7e65..000000000 --- a/contrib/lar/lar.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * lar - Lua Archive Library - * - * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -#ifndef __LAR_H -#define __LAR_H - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <stdint.h> -#include <fcntl.h> -#include <string.h> -#include <errno.h> -#include <arpa/inet.h> -#include <sys/types.h> -#include <sys/mman.h> -#include <sys/stat.h> - -#include "md5.h" - -#define LAR_DIE(s) \ - do { \ - fprintf(stderr, "%s(%i): %s(): %s\n", \ - __FILE__, __LINE__, __FUNCTION__, s); \ - if( errno ) fprintf(stderr, "%s(%i): %s\n", \ - __FILE__, __LINE__, strerror(errno) ); \ - exit(1); \ - } while(0) - - -#define LAR_FNAME_BUFFER 1024 -#define LAR_FNAME(s) char s[LAR_FNAME_BUFFER] - -#define LAR_TYPE_REGULAR 0x0000 -#define LAR_TYPE_FILELIST 0xFFFF - -#ifdef __WIN32__ -#define LAR_DIRSEP '\\' -#else -#define LAR_DIRSEP '/' -#endif - - -struct lar_index_item { - uint32_t offset; - uint32_t length; - uint16_t type; - uint16_t flags; - char id[16]; - char *filename; - struct lar_index_item *next; -}; - -struct lar_member_item { - uint16_t type; - uint16_t flags; - uint32_t length; - char *data; - char *mmap; - size_t mlen; -}; - -struct lar_archive_handle { - int fd; - int has_filenames; - off_t length; - char filename[LAR_FNAME_BUFFER]; - struct lar_index_item *index; -}; - -typedef struct lar_index_item lar_index; -typedef struct lar_member_item lar_member; -typedef struct lar_archive_handle lar_archive; - - -lar_index * lar_get_index( lar_archive *ar ); - -lar_member * lar_mmap_member( lar_archive *ar, lar_index *idx_ptr ); - -lar_member * lar_open_member( lar_archive *ar, const char *name ); - -int lar_close_member( lar_member *member ); - -lar_archive * lar_open( const char *filename ); - -int lar_close( lar_archive *ar ); - -lar_archive * lar_find_archive( const char *package, const char *path, int pkg); - -lar_member * lar_find_member( lar_archive *ar, const char *package ); - -#endif diff --git a/contrib/lar/lar.pl b/contrib/lar/lar.pl deleted file mode 100755 index 2f9f3dd65..000000000 --- a/contrib/lar/lar.pl +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/perl - -use strict; - -@ARGV || die "Usage: $0 <file1> <file2> ... <fileN>\n"; - -my @index; -my $offset = 0; - -foreach my $file ( @ARGV ) -{ - if( -f $file && open F, "< $file" ) - { - warn sprintf "Member at 0x%08X\n", $offset; - push @index, [ ]; - - my $size = length $file; - - print $file; - print "\0" x ( $size % 4 ); - - $index[-1][0] = $offset; - $index[-1][1] = $size; - $index[-1][2] = $offset + $size + ( $size % 4 ); - - - $size = 0; - while( read F, my $buffer, 4096 ) { - $size += length $buffer; - print $buffer; - } - print "\0" x ( $size % 4 ); - - $index[-1][3] = $size; - $offset = $index[-1][2] + $size + ( $size % 4 ); - - close F; - } -} - -my $count = 1; -foreach my $file ( @index ) -{ - warn sprintf "Index[%4d]: 0x%08X 0x%08X 0x%08X 0x%08X\n", $count++, $file->[0], $file->[1], $file->[2], $file->[3]; - print pack "NNNNnn", $file->[0], $file->[1], $file->[2], $file->[3], 0x0000, 0x0000; -} - -warn sprintf "Index at 0x%08X, length 0x%08X\n", $offset, @index * 20; -print pack "N", $offset; - diff --git a/contrib/lar/larlib.c b/contrib/lar/larlib.c deleted file mode 100644 index aa9280a09..000000000 --- a/contrib/lar/larlib.c +++ /dev/null @@ -1,540 +0,0 @@ -/* - * lar - Lua Archive Library - * - * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -#include "lua.h" -#include "lualib.h" -#include "lauxlib.h" -#include "lar.h" - -typedef struct { - int fd; - char *data; - size_t length; -} mmap_handle; - -static int larlib_perror( lua_State *L, const char *message ) -{ - lua_pushnil(L); - lua_pushstring(L, message); - - return 2; -} - -int larlib_open( lua_State *L ) -{ - lar_archive *ar, **udata; - const char *filename = luaL_checkstring( L, 1 ); - - if( filename != NULL && (ar = lar_open(filename)) != NULL ) - { - if( (udata = lua_newuserdata(L, sizeof(lar_archive *))) != NULL ) - { - *udata = ar; - luaL_getmetatable(L, "lar.archive"); - lua_setmetatable(L, -2); - } - else - { - return luaL_error(L, "Out of memory"); - } - } - else - { - return larlib_perror(L, "Archive not found"); - } - - return 1; -} - -int larlib_find( lua_State *L ) -{ - const char *filename = luaL_checkstring( L, 1 ); - const char *basepath = luaL_optstring( L, 2, "./" ); - int is_pkg = strstr(filename, "/") ? 0 : 1; - lar_archive *ar, **udata; - - if( ((ar = lar_find_archive(filename, basepath, is_pkg)) != NULL) || - ((ar = lar_find_archive(filename, LUA_LDIR, is_pkg)) != NULL) || - ((ar = lar_find_archive(filename, LUA_CDIR, is_pkg)) != NULL) ) - { - if( (udata = lua_newuserdata(L, sizeof(lar_archive *))) != NULL ) - { - *udata = ar; - luaL_getmetatable(L, "lar.archive"); - lua_setmetatable(L, -2); - } - else - { - return luaL_error(L, "Out of memory"); - } - } - else - { - return larlib_perror(L, "Archive not found"); - } - - return 1; -} - -int larlib_md5( lua_State *L ) -{ - int i; - char md5[16], md5_hex[33]; - const char *data = luaL_checkstring( L, 1 ); - md5_state_t state; - - md5_init(&state); - md5_append(&state, (const md5_byte_t *)data, strlen(data)); - md5_finish(&state, (md5_byte_t *)md5); - - for( i = 0; i < 16; i++ ) - sprintf(&md5_hex[i*2], "%02x", (unsigned char)md5[i]); - - lua_pushstring(L, md5_hex); - return 1; -} - -int larlib_md5_file( lua_State *L ) -{ - int i, fd, len; - char md5[16], md5_hex[33], buffer[1024]; - const char *filename = luaL_checkstring( L, 1 ); - md5_state_t state; - - if( (fd = open(filename, O_RDONLY)) != -1 ) - { - md5_init(&state); - - while( (len = read(fd, buffer, 1024)) > 0 ) - md5_append(&state, (const md5_byte_t *)buffer, len); - - md5_finish(&state, (md5_byte_t *)md5); - - for( i = 0; i < 16; i++ ) - sprintf(&md5_hex[i*2], "%02x", (unsigned char)md5[i]); - - close(fd); - lua_pushstring(L, md5_hex); - } - else - { - return larlib_perror(L, strerror(errno)); - } - - return 1; -} - -static int larlib_mkpath( const char *name, const char *path, char *buffer ) -{ - int nlen = strlen(name); - int plen = strlen(path); - - if( (nlen + plen + 1) <= LAR_FNAME_BUFFER ) - { - strcpy(buffer, path); - - if( buffer[plen-1] != '/' ) - buffer[plen++] = '/'; - - strcpy(&buffer[plen], name); - buffer[plen + nlen] = '\0'; - - return 0; - } - - return 1; -} - -static int larlib__gc( lua_State *L ) -{ - lar_archive **archive = luaL_checkudata( L, 1, "lar.archive" ); - - if( *archive ) - lar_close(*archive); - - *archive = NULL; - return 0; -} - - -static int larlib_member__open( lua_State *L, lar_member *mb ) -{ - lar_archive **archive = NULL; - const char *filename = NULL; - lar_member **udata; - - if( mb == NULL ) - { - *archive = luaL_checkudata( L, 1, "lar.archive" ); - filename = luaL_checkstring( L, 2 ); - } - - if( mb != NULL || (mb = lar_open_member(*archive, filename)) != NULL ) - { - if( (udata = lua_newuserdata(L, sizeof(lar_member *))) != NULL ) - { - *udata = mb; - luaL_getmetatable(L, "lar.member"); - lua_setmetatable(L, -2); - } - else - { - return luaL_error(L, "Out of memory"); - } - } - else - { - return larlib_perror(L, "Member not found in archive"); - } - - return 1; -} - -int larlib_member_open( lua_State *L ) -{ - return larlib_member__open( L, NULL ); -} - -int larlib_member_find( lua_State *L ) -{ - lar_archive **archive = luaL_checkudata( L, 1, "lar.archive" ); - const char *package = luaL_checkstring( L, 2 ); - lar_member *mb, **udata; - - if( (mb = lar_find_member(*archive, package)) != NULL ) - { - if( (udata = lua_newuserdata(L, sizeof(lar_member *))) != NULL ) - { - *udata = mb; - luaL_getmetatable(L, "lar.member"); - lua_setmetatable(L, -2); - } - else - { - return luaL_error(L, "Out of memory"); - } - } - else - { - return larlib_perror(L, "Member not found in archive"); - } - - return 1; -} - -int larlib_member_size( lua_State *L ) -{ - lar_member **member = luaL_checkudata( L, 1, "lar.member" ); - lua_pushnumber(L, (*member)->length); - return 1; -} - -int larlib_member_type( lua_State *L ) -{ - lar_member **member = luaL_checkudata( L, 1, "lar.member" ); - lua_pushnumber(L, (*member)->type); - return 1; -} - -int larlib_member_flags( lua_State *L ) -{ - lar_member **member = luaL_checkudata( L, 1, "lar.member" ); - lua_pushnumber(L, (*member)->flags); - return 1; -} - -int larlib_member_read( lua_State *L ) -{ - lar_member **member = luaL_checkudata( L, 1, "lar.member" ); - int start = luaL_checknumber( L, 2 ); - int length = luaL_optnumber( L, 3, (*member)->length ); - char *stringcopy; - - if( (start >= 0) && (start < (*member)->length) && (length > 0) ) - { - if( (start + length) >= (*member)->length ) - length = (*member)->length - start; - - if( (stringcopy = (char *)malloc(length + 1)) != NULL ) - { - memcpy(stringcopy, &(*member)->data[start], length); - stringcopy[length] = '\0'; - lua_pushstring(L, stringcopy); - free(stringcopy); - } - else - { - return luaL_error(L, "Out of memory"); - } - } - else - { - return larlib_perror(L, "Invalid argument"); - } - - return 1; -} - -int larlib_member_data( lua_State *L ) -{ - lar_member **member = luaL_checkudata( L, 1, "lar.member" ); - lua_pushstring(L, (*member)->data); - return 1; -} - -int larlib_member_load( lua_State *L ) -{ - lar_member **member = luaL_checkudata( L, 1, "lar.member" ); - int status = luaL_loadbuffer( L, (*member)->data, (*member)->length, - "=(lar member)" ); - - if( status ) - { - lua_pushnil(L); - lua_insert(L, -2); - return 2; - } - - return 1; -} - -static int larlib_member__gc( lua_State *L ) -{ - lar_member **member = luaL_checkudata( L, 1, "lar.member" ); - - if( *member ) - lar_close_member(*member); - - *member = NULL; - return 0; -} - - -static int larlib_mmfile__open( lua_State *L, const char *filename ) -{ - struct stat s; - mmap_handle *fh, **udata; - - if( filename == NULL ) - filename = (const char *)luaL_checkstring( L, 1 ); - - if( (fh = (mmap_handle *)malloc(sizeof(mmap_handle))) == NULL ) - return larlib_perror(L, "Out of memory"); - - if( stat(filename, &s) > -1 && (fh->fd = open(filename, O_RDONLY)) > -1 ) - { - fh->length = s.st_size; - fh->data = mmap( 0, s.st_size, PROT_READ, MAP_PRIVATE, fh->fd, 0 ); - - if( fh->data == MAP_FAILED ) - return larlib_perror(L, "Failed to mmap() file"); - - if( (udata = lua_newuserdata(L, sizeof(char *))) != NULL ) - { - *udata = fh; - luaL_getmetatable(L, "lar.mmfile"); - lua_setmetatable(L, -2); - } - else - { - return larlib_perror(L, "Out of memory"); - } - } - else - { - return larlib_perror(L, strerror(errno)); - } - - return 1; -} - -int larlib_mmfile_open( lua_State *L ) -{ - return larlib_mmfile__open(L, NULL); -} - -int larlib_mmfile_size( lua_State *L ) -{ - mmap_handle **fh = luaL_checkudata( L, 1, "lar.mmfile" ); - lua_pushnumber(L, (*fh)->length); - return 1; -} - -int larlib_mmfile_read( lua_State *L ) -{ - mmap_handle **fh = luaL_checkudata( L, 1, "lar.mmfile" ); - int start = luaL_checknumber( L, 2 ); - int length = luaL_optnumber( L, 3, (*fh)->length ); - char *stringcopy; - - if( (start >= 0) && (start < (*fh)->length) && (length > 0) ) - { - if( (start + length) >= (*fh)->length ) - length = (*fh)->length - start; - - if( (stringcopy = (char *)malloc(length + 1)) != NULL ) - { - memcpy(stringcopy, &(*fh)->data[start], length); - stringcopy[length] = '\0'; - lua_pushstring(L, stringcopy); - free(stringcopy); - } - else - { - return luaL_error(L, "Out of memory"); - } - } - else - { - return larlib_perror(L, "Invalid argument"); - } - - return 1; -} - -int larlib_mmfile_data( lua_State *L ) -{ - mmap_handle **fh = luaL_checkudata( L, 1, "lar.mmfile" ); - lua_pushstring(L, (*fh)->data); - return 1; -} - -int larlib_mmfile_load( lua_State *L ) -{ - mmap_handle **fh = luaL_checkudata( L, 1, "lar.mmfile" ); - int status = luaL_loadbuffer(L, (*fh)->data, (*fh)->length, "=(mmap file)"); - - if( status ) - { - lua_pushnil(L); - lua_insert(L, -2); - return 2; - } - - return 1; -} - -static int larlib_mmfile__gc( lua_State *L ) -{ - mmap_handle **fh = luaL_checkudata( L, 1, "lar.mmfile" ); - - if( *fh ) - { - close((*fh)->fd); - munmap((*fh)->data, (*fh)->length); - free(*fh); - *fh = NULL; - } - - return 0; -} - - -int larlib_findfile( lua_State *L ) -{ - int i; - const char *filename = luaL_checkstring( L, 1 ); - const char *basepath = luaL_optstring( L, 2, "./" ); - struct stat s; - lar_archive *ar; - lar_member *mb; - LAR_FNAME(filepath); - - const char *searchpath[3] = { basepath, LUA_LDIR, LUA_CDIR }; - - for( i = 0; i < 3; i++ ) - if( !larlib_mkpath(filename, searchpath[i], filepath) ) - if( stat(filepath, &s) > -1 && (s.st_mode & S_IFREG) ) - return larlib_mmfile__open( L, filepath ); - - for( i = 0; i < 3; i++ ) - if( (ar = lar_find_archive(filename, searchpath[i], 0)) != NULL ) - if( (mb = lar_open_member(ar, filename)) != NULL ) - return larlib_member__open( L, mb ); - - return larlib_perror(L, "File not found"); -} - - -static const luaL_reg LAR_REG[] = { - { "open", larlib_open }, - { "find", larlib_find }, - { "md5", larlib_md5 }, - { "md5_file", larlib_md5_file }, - { "mmap", larlib_mmfile_open }, - { "findfile", larlib_findfile }, - { NULL, NULL } -}; - -static const luaL_reg LAR_ARCHIVE_REG[] = { - { "member", larlib_member_open }, - { "find", larlib_member_find }, - { "__gc", larlib__gc }, - { NULL, NULL } -}; - -static const luaL_reg LAR_MEMBER_REG[] = { - { "size", larlib_member_size }, - { "type", larlib_member_type }, - { "flags", larlib_member_flags }, - { "read", larlib_member_read }, - { "data", larlib_member_data }, - { "load", larlib_member_load }, - { "__gc", larlib_member__gc }, - { NULL, NULL } -}; - -static const luaL_reg LAR_MMFILE_REG[] = { - { "size", larlib_mmfile_size }, - { "read", larlib_mmfile_read }, - { "data", larlib_mmfile_data }, - { "load", larlib_mmfile_load }, - { "__gc", larlib_mmfile__gc }, - { NULL, NULL } -}; - - -LUALIB_API int luaopen_larlib( lua_State *L ) -{ - luaL_newmetatable(L, "lar"); - luaL_register(L, NULL, LAR_REG); - lua_pushvalue(L, -1); - lua_setfield(L, -2, "__index"); - lua_setglobal(L, "lar"); - - luaL_newmetatable(L, "lar.archive"); - luaL_register(L, NULL, LAR_ARCHIVE_REG); - lua_pushvalue(L, -1); - lua_setfield(L, -2, "__index"); - lua_setglobal(L, "lar.archive"); - - luaL_newmetatable(L, "lar.member"); - luaL_register(L, NULL, LAR_MEMBER_REG); - lua_pushvalue(L, -1); - lua_setfield(L, -2, "__index"); - lua_setglobal(L, "lar.member"); - - luaL_newmetatable(L, "lar.mmfile"); - luaL_register(L, NULL, LAR_MMFILE_REG); - lua_pushvalue(L, -1); - lua_setfield(L, -2, "__index"); - lua_setglobal(L, "lar.mmfile"); - - return 1; -} diff --git a/contrib/lar/md5.c b/contrib/lar/md5.c deleted file mode 100644 index c35d96c5e..000000000 --- a/contrib/lar/md5.c +++ /dev/null @@ -1,381 +0,0 @@ -/* - Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - L. Peter Deutsch - ghost@aladdin.com - - */ -/* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */ -/* - Independent implementation of MD5 (RFC 1321). - - This code implements the MD5 Algorithm defined in RFC 1321, whose - text is available at - http://www.ietf.org/rfc/rfc1321.txt - The code is derived from the text of the RFC, including the test suite - (section A.5) but excluding the rest of Appendix A. It does not include - any code or documentation that is identified in the RFC as being - copyrighted. - - The original and principal author of md5.c is L. Peter Deutsch - <ghost@aladdin.com>. Other authors are noted in the change history - that follows (in reverse chronological order): - - 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order - either statically or dynamically; added missing #include <string.h> - in library. - 2002-03-11 lpd Corrected argument list for main(), and added int return - type, in test program and T value program. - 2002-02-21 lpd Added missing #include <stdio.h> in test program. - 2000-07-03 lpd Patched to eliminate warnings about "constant is - unsigned in ANSI C, signed in traditional"; made test program - self-checking. - 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. - 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). - 1999-05-03 lpd Original version. - */ - -#include "md5.h" -#include <string.h> - -#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */ -#ifdef ARCH_IS_BIG_ENDIAN -# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1) -#else -# define BYTE_ORDER 0 -#endif - -#define T_MASK ((md5_word_t)~0) -#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87) -#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9) -#define T3 0x242070db -#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111) -#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050) -#define T6 0x4787c62a -#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec) -#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe) -#define T9 0x698098d8 -#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850) -#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e) -#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841) -#define T13 0x6b901122 -#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c) -#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71) -#define T16 0x49b40821 -#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d) -#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf) -#define T19 0x265e5a51 -#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855) -#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2) -#define T22 0x02441453 -#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e) -#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437) -#define T25 0x21e1cde6 -#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829) -#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278) -#define T28 0x455a14ed -#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa) -#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07) -#define T31 0x676f02d9 -#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375) -#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd) -#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e) -#define T35 0x6d9d6122 -#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3) -#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb) -#define T38 0x4bdecfa9 -#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f) -#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f) -#define T41 0x289b7ec6 -#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805) -#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a) -#define T44 0x04881d05 -#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6) -#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a) -#define T47 0x1fa27cf8 -#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a) -#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb) -#define T50 0x432aff97 -#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58) -#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6) -#define T53 0x655b59c3 -#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d) -#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82) -#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e) -#define T57 0x6fa87e4f -#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f) -#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb) -#define T60 0x4e0811a1 -#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d) -#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca) -#define T63 0x2ad7d2bb -#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e) - - -static void -md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) -{ - md5_word_t - a = pms->abcd[0], b = pms->abcd[1], - c = pms->abcd[2], d = pms->abcd[3]; - md5_word_t t; -#if BYTE_ORDER > 0 - /* Define storage only for big-endian CPUs. */ - md5_word_t X[16]; -#else - /* Define storage for little-endian or both types of CPUs. */ - md5_word_t xbuf[16]; - const md5_word_t *X; -#endif - - { -#if BYTE_ORDER == 0 - /* - * Determine dynamically whether this is a big-endian or - * little-endian machine, since we can use a more efficient - * algorithm on the latter. - */ - static const int w = 1; - - if (*((const md5_byte_t *)&w)) /* dynamic little-endian */ -#endif -#if BYTE_ORDER <= 0 /* little-endian */ - { - /* - * On little-endian machines, we can process properly aligned - * data without copying it. - */ - if (!((data - (const md5_byte_t *)0) & 3)) { - /* data are properly aligned */ - X = (const md5_word_t *)data; - } else { - /* not aligned */ - memcpy(xbuf, data, 64); - X = xbuf; - } - } -#endif -#if BYTE_ORDER == 0 - else /* dynamic big-endian */ -#endif -#if BYTE_ORDER >= 0 /* big-endian */ - { - /* - * On big-endian machines, we must arrange the bytes in the - * right order. - */ - const md5_byte_t *xp = data; - int i; - -# if BYTE_ORDER == 0 - X = xbuf; /* (dynamic only) */ -# else -# define xbuf X /* (static only) */ -# endif - for (i = 0; i < 16; ++i, xp += 4) - xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); - } -#endif - } - -#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) - - /* Round 1. */ - /* Let [abcd k s i] denote the operation - a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ -#define F(x, y, z) (((x) & (y)) | (~(x) & (z))) -#define SET(a, b, c, d, k, s, Ti)\ - t = a + F(b,c,d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 0, 7, T1); - SET(d, a, b, c, 1, 12, T2); - SET(c, d, a, b, 2, 17, T3); - SET(b, c, d, a, 3, 22, T4); - SET(a, b, c, d, 4, 7, T5); - SET(d, a, b, c, 5, 12, T6); - SET(c, d, a, b, 6, 17, T7); - SET(b, c, d, a, 7, 22, T8); - SET(a, b, c, d, 8, 7, T9); - SET(d, a, b, c, 9, 12, T10); - SET(c, d, a, b, 10, 17, T11); - SET(b, c, d, a, 11, 22, T12); - SET(a, b, c, d, 12, 7, T13); - SET(d, a, b, c, 13, 12, T14); - SET(c, d, a, b, 14, 17, T15); - SET(b, c, d, a, 15, 22, T16); -#undef SET - - /* Round 2. */ - /* Let [abcd k s i] denote the operation - a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ -#define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) -#define SET(a, b, c, d, k, s, Ti)\ - t = a + G(b,c,d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 1, 5, T17); - SET(d, a, b, c, 6, 9, T18); - SET(c, d, a, b, 11, 14, T19); - SET(b, c, d, a, 0, 20, T20); - SET(a, b, c, d, 5, 5, T21); - SET(d, a, b, c, 10, 9, T22); - SET(c, d, a, b, 15, 14, T23); - SET(b, c, d, a, 4, 20, T24); - SET(a, b, c, d, 9, 5, T25); - SET(d, a, b, c, 14, 9, T26); - SET(c, d, a, b, 3, 14, T27); - SET(b, c, d, a, 8, 20, T28); - SET(a, b, c, d, 13, 5, T29); - SET(d, a, b, c, 2, 9, T30); - SET(c, d, a, b, 7, 14, T31); - SET(b, c, d, a, 12, 20, T32); -#undef SET - - /* Round 3. */ - /* Let [abcd k s t] denote the operation - a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ -#define H(x, y, z) ((x) ^ (y) ^ (z)) -#define SET(a, b, c, d, k, s, Ti)\ - t = a + H(b,c,d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 5, 4, T33); - SET(d, a, b, c, 8, 11, T34); - SET(c, d, a, b, 11, 16, T35); - SET(b, c, d, a, 14, 23, T36); - SET(a, b, c, d, 1, 4, T37); - SET(d, a, b, c, 4, 11, T38); - SET(c, d, a, b, 7, 16, T39); - SET(b, c, d, a, 10, 23, T40); - SET(a, b, c, d, 13, 4, T41); - SET(d, a, b, c, 0, 11, T42); - SET(c, d, a, b, 3, 16, T43); - SET(b, c, d, a, 6, 23, T44); - SET(a, b, c, d, 9, 4, T45); - SET(d, a, b, c, 12, 11, T46); - SET(c, d, a, b, 15, 16, T47); - SET(b, c, d, a, 2, 23, T48); -#undef SET - - /* Round 4. */ - /* Let [abcd k s t] denote the operation - a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ -#define I(x, y, z) ((y) ^ ((x) | ~(z))) -#define SET(a, b, c, d, k, s, Ti)\ - t = a + I(b,c,d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 0, 6, T49); - SET(d, a, b, c, 7, 10, T50); - SET(c, d, a, b, 14, 15, T51); - SET(b, c, d, a, 5, 21, T52); - SET(a, b, c, d, 12, 6, T53); - SET(d, a, b, c, 3, 10, T54); - SET(c, d, a, b, 10, 15, T55); - SET(b, c, d, a, 1, 21, T56); - SET(a, b, c, d, 8, 6, T57); - SET(d, a, b, c, 15, 10, T58); - SET(c, d, a, b, 6, 15, T59); - SET(b, c, d, a, 13, 21, T60); - SET(a, b, c, d, 4, 6, T61); - SET(d, a, b, c, 11, 10, T62); - SET(c, d, a, b, 2, 15, T63); - SET(b, c, d, a, 9, 21, T64); -#undef SET - - /* Then perform the following additions. (That is increment each - of the four registers by the value it had before this block - was started.) */ - pms->abcd[0] += a; - pms->abcd[1] += b; - pms->abcd[2] += c; - pms->abcd[3] += d; -} - -void -md5_init(md5_state_t *pms) -{ - pms->count[0] = pms->count[1] = 0; - pms->abcd[0] = 0x67452301; - pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476; - pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301; - pms->abcd[3] = 0x10325476; -} - -void -md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes) -{ - const md5_byte_t *p = data; - int left = nbytes; - int offset = (pms->count[0] >> 3) & 63; - md5_word_t nbits = (md5_word_t)(nbytes << 3); - - if (nbytes <= 0) - return; - - /* Update the message length. */ - pms->count[1] += nbytes >> 29; - pms->count[0] += nbits; - if (pms->count[0] < nbits) - pms->count[1]++; - - /* Process an initial partial block. */ - if (offset) { - int copy = (offset + nbytes > 64 ? 64 - offset : nbytes); - - memcpy(pms->buf + offset, p, copy); - if (offset + copy < 64) - return; - p += copy; - left -= copy; - md5_process(pms, pms->buf); - } - - /* Process full blocks. */ - for (; left >= 64; p += 64, left -= 64) - md5_process(pms, p); - - /* Process a final partial block. */ - if (left) - memcpy(pms->buf, p, left); -} - -void -md5_finish(md5_state_t *pms, md5_byte_t digest[16]) -{ - static const md5_byte_t pad[64] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - md5_byte_t data[8]; - int i; - - /* Save the length before padding. */ - for (i = 0; i < 8; ++i) - data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); - /* Pad to 56 bytes mod 64. */ - md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); - /* Append the length. */ - md5_append(pms, data, 8); - for (i = 0; i < 16; ++i) - digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); -} diff --git a/contrib/lar/md5.h b/contrib/lar/md5.h deleted file mode 100644 index 698c995d8..000000000 --- a/contrib/lar/md5.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - L. Peter Deutsch - ghost@aladdin.com - - */ -/* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */ -/* - Independent implementation of MD5 (RFC 1321). - - This code implements the MD5 Algorithm defined in RFC 1321, whose - text is available at - http://www.ietf.org/rfc/rfc1321.txt - The code is derived from the text of the RFC, including the test suite - (section A.5) but excluding the rest of Appendix A. It does not include - any code or documentation that is identified in the RFC as being - copyrighted. - - The original and principal author of md5.h is L. Peter Deutsch - <ghost@aladdin.com>. Other authors are noted in the change history - that follows (in reverse chronological order): - - 2002-04-13 lpd Removed support for non-ANSI compilers; removed - references to Ghostscript; clarified derivation from RFC 1321; - now handles byte order either statically or dynamically. - 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. - 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5); - added conditionalization for C++ compilation from Martin - Purschke <purschke@bnl.gov>. - 1999-05-03 lpd Original version. - */ - -#ifndef md5_INCLUDED -# define md5_INCLUDED - -/* - * This package supports both compile-time and run-time determination of CPU - * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be - * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is - * defined as non-zero, the code will be compiled to run only on big-endian - * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to - * run on either big- or little-endian CPUs, but will run slightly less - * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined. - */ - -typedef unsigned char md5_byte_t; /* 8-bit byte */ -typedef unsigned int md5_word_t; /* 32-bit word */ - -/* Define the state of the MD5 Algorithm. */ -typedef struct md5_state_s { - md5_word_t count[2]; /* message length in bits, lsw first */ - md5_word_t abcd[4]; /* digest buffer */ - md5_byte_t buf[64]; /* accumulate block */ -} md5_state_t; - -#ifdef __cplusplus -extern "C" -{ -#endif - -/* Initialize the algorithm. */ -void md5_init(md5_state_t *pms); - -/* Append a string to the message. */ -void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes); - -/* Finish the message and return the digest. */ -void md5_finish(md5_state_t *pms, md5_byte_t digest[16]); - -#ifdef __cplusplus -} /* end extern "C" */ -#endif - -#endif /* md5_INCLUDED */ diff --git a/contrib/lar/openwrt/050-lar-source-loader.patch b/contrib/lar/openwrt/050-lar-source-loader.patch deleted file mode 100644 index c2e1c5966..000000000 --- a/contrib/lar/openwrt/050-lar-source-loader.patch +++ /dev/null @@ -1,1561 +0,0 @@ -diff -Nbur lua-5.1.4.orig/src/Makefile lua-5.1.4/src/Makefile ---- lua-5.1.4.orig/src/Makefile 2009-04-06 21:36:52.000000000 +0200 -+++ lua-5.1.4/src/Makefile 2009-04-11 01:02:45.000000000 +0200 -@@ -28,7 +28,7 @@ - lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o \ - lundump.o lvm.o lzio.o lnum.o - LIB_O= lauxlib.o lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o \ -- lstrlib.o loadlib.o linit.o -+ lstrlib.o loadlib.o linit.o lar.o md5.o larlib.o - - LUA_T= lua - LUA_O= lua.o -diff -Nbur lua-5.1.4.orig/src/lar.c lua-5.1.4/src/lar.c ---- lua-5.1.4.orig/src/lar.c 1970-01-01 01:00:00.000000000 +0100 -+++ lua-5.1.4/src/lar.c 2009-04-13 16:51:07.000000000 +0200 -@@ -0,0 +1,328 @@ -+/* -+ * lar - Lua Archive Library -+ * -+ * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org> -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+ -+#include "lar.h" -+ -+static int lar_read32( int fd, uint32_t *val ) -+{ -+ uint8_t buffer[5]; -+ -+ if( read(fd, buffer, 4) < 4 ) -+ LAR_DIE("Unexpected EOF while reading data"); -+ -+ buffer[4] = 0; -+ *val = ntohl(*((uint32_t *) buffer)); -+ -+ return 0; -+} -+ -+static int lar_read16( int fd, uint16_t *val ) -+{ -+ uint8_t buffer[3]; -+ -+ if( read(fd, buffer, 2) < 2 ) -+ LAR_DIE("Unexpected EOF while reading data"); -+ -+ buffer[2] = 0; -+ *val = ntohs(*((uint16_t *) buffer)); -+ -+ return 0; -+} -+ -+static void lar_md5( char *md5, const char *data, int len ) -+{ -+ md5_state_t state; -+ -+ md5_init(&state); -+ md5_append(&state, (const md5_byte_t *)data, len); -+ md5_finish(&state, (md5_byte_t *)md5); -+} -+ -+static int lar_read_filenames( lar_archive *ar ) -+{ -+ int i; -+ int j; -+ char *filelist; -+ size_t pgof; -+ size_t pgsz = getpagesize(); -+ lar_index *idx_ptr; -+ lar_index *idx_filelist = ar->index; -+ -+ while(idx_filelist) -+ { -+ if( idx_filelist->type == LAR_TYPE_FILELIST ) -+ break; -+ -+ idx_filelist = idx_filelist->next; -+ } -+ -+ if( idx_filelist != NULL ) -+ { -+ pgof = ( idx_filelist->offset % pgsz ); -+ -+ filelist = mmap( -+ 0, idx_filelist->length + pgof, PROT_READ, MAP_PRIVATE, -+ ar->fd, idx_filelist->offset - pgof -+ ); -+ -+ if( filelist == MAP_FAILED ) -+ LAR_DIE("Failed to mmap() file list"); -+ -+ -+ idx_ptr = ar->index; -+ i = pgof; -+ -+ while(idx_ptr) -+ { -+ if( idx_ptr->type == LAR_TYPE_REGULAR ) -+ { -+ j = strlen(&filelist[i]) + 1; -+ -+ if( (j >= LAR_FNAME_BUFFER) || -+ ((i+j) > (idx_filelist->length+pgof)) ) -+ LAR_DIE("Filename exceeds maximum allowed length"); -+ -+ idx_ptr->filename = (char *)malloc(j); -+ memcpy(idx_ptr->filename, &filelist[i], j); -+ -+ i += j; -+ } -+ -+ idx_ptr = idx_ptr->next; -+ } -+ -+ munmap(filelist, idx_filelist->length + pgof); -+ -+ return 1; -+ } -+ -+ return 0; -+} -+ -+lar_index * lar_get_index( lar_archive *ar ) -+{ -+ uint32_t i; -+ uint32_t idx_offset; -+ uint32_t idx_length; -+ lar_index *idx_map; -+ lar_index *idx_ptr; -+ -+ if( lseek(ar->fd, -(sizeof(idx_offset)), SEEK_END) == -1 ) -+ LAR_DIE("Unable to seek to end of archive"); -+ -+ lar_read32(ar->fd, &idx_offset); -+ idx_length = ( ar->length - idx_offset - sizeof(idx_offset) ); -+ -+ if( lseek(ar->fd, idx_offset, SEEK_SET) == -1 ) -+ LAR_DIE("Unable to seek to archive index"); -+ -+ -+ idx_map = NULL; -+ -+ for( i = 0; i < idx_length; i += (sizeof(lar_index) - 2 * sizeof(char *)) ) -+ { -+ idx_ptr = (lar_index *)malloc(sizeof(lar_index)); -+ idx_ptr->filename = NULL; -+ -+ lar_read32(ar->fd, &idx_ptr->offset); -+ lar_read32(ar->fd, &idx_ptr->length); -+ lar_read16(ar->fd, &idx_ptr->type); -+ lar_read16(ar->fd, &idx_ptr->flags); -+ -+ if(read(ar->fd,&idx_ptr->id,sizeof(idx_ptr->id)) < sizeof(idx_ptr->id)) -+ LAR_DIE("Unexpected EOF while reading member id"); -+ -+ idx_ptr->next = idx_map; -+ idx_map = idx_ptr; -+ } -+ -+ return idx_map; -+} -+ -+lar_member * lar_mmap_member( lar_archive *ar, lar_index *idx_ptr ) -+{ -+ lar_member *member; -+ size_t pgsz = getpagesize(); -+ size_t pgof = ( idx_ptr->offset % pgsz ); -+ -+ char *memberdata = mmap( -+ 0, idx_ptr->length + pgof, PROT_READ, MAP_PRIVATE, -+ ar->fd, idx_ptr->offset - pgof -+ ); -+ -+ if( memberdata == MAP_FAILED ) -+ LAR_DIE("Failed to mmap() member data"); -+ -+ member = (lar_member *)malloc(sizeof(lar_member)); -+ member->type = idx_ptr->type; -+ member->flags = idx_ptr->flags; -+ member->length = idx_ptr->length; -+ member->data = &memberdata[pgof]; -+ -+ member->mmap = memberdata; -+ member->mlen = idx_ptr->length + pgof; -+ -+ return member; -+} -+ -+lar_member * lar_open_member( lar_archive *ar, const char *name ) -+{ -+ lar_index *idx_ptr = ar->index; -+ char mbid[sizeof(idx_ptr->id)]; -+ -+ lar_md5(mbid, name, strlen(name)); -+ -+ while(idx_ptr) -+ { -+ if( !strncmp(mbid, idx_ptr->id, sizeof(mbid)) ) -+ return lar_mmap_member(ar, idx_ptr); -+ -+ idx_ptr = idx_ptr->next; -+ } -+ -+ return NULL; -+} -+ -+int lar_close_member( lar_member *member ) -+{ -+ int stat = munmap(member->mmap, member->mlen); -+ free(member); -+ member = NULL; -+ -+ return stat; -+} -+ -+lar_archive * lar_open( const char *filename ) -+{ -+ int fd; -+ struct stat as; -+ lar_archive *ar; -+ -+ if( stat(filename, &as) == -1 ) -+ return NULL; -+ -+ if( !(as.st_mode & S_IFREG) ) -+ return NULL; -+ -+ if( (fd = open(filename, O_RDONLY)) != -1 ) -+ { -+ ar = (lar_archive *)malloc(sizeof(lar_archive)); -+ ar->fd = fd; -+ ar->length = as.st_size; -+ ar->index = lar_get_index(ar); -+ strncpy(ar->filename, filename, sizeof(ar->filename)); -+ -+ ar->has_filenames = lar_read_filenames(ar); -+ -+ return ar; -+ } -+ -+ return NULL; -+} -+ -+int lar_close( lar_archive *ar ) -+{ -+ lar_index *idx_head; -+ lar_index *idx_next; -+ -+ close(ar->fd); -+ -+ idx_head = ar->index; -+ do { -+ idx_next = idx_head->next; -+ free(idx_head->filename); -+ free(idx_head); -+ } while( (idx_head = idx_next) != NULL ); -+ -+ free(ar); -+ ar = NULL; -+ -+ return 0; -+} -+ -+lar_archive * lar_find_archive( const char *package, const char *path, int pkg ) -+{ -+ uint32_t i; -+ uint32_t j; -+ uint32_t seg = 1; -+ uint32_t len = 0; -+ uint32_t pln = 0; -+ char sep = ( pkg ? '.' : '/' ); -+ struct stat s; -+ LAR_FNAME(buffer); -+ -+ if( path ) -+ { -+ for( pln = 0; path[pln] != '\0'; pln++ ) -+ if( pln >= (sizeof(buffer) - 5) ) -+ LAR_DIE("Library path exceeds maximum allowed length"); -+ -+ memcpy(buffer, path, pln); -+ } -+ -+ if( buffer[pln-1] != '/' ) -+ buffer[pln++] = '/'; -+ -+ for( len = 0; package[len] != '\0'; len++ ) -+ { -+ if( len >= (sizeof(buffer) - 5 - pln) ) -+ LAR_DIE("Package name exceeds maximum allowed length"); -+ -+ if( package[len] == sep ) seg++; -+ } -+ -+ while( seg > 0 ) -+ { -+ for( i = 0, j = 1; (i < len) && (j <= seg); i++ ) -+ { -+ if( package[i] == sep ) { -+ if( j < seg ) j++; else break; -+ } -+ -+ buffer[pln+i] = ( package[i] == sep ) ? LAR_DIRSEP : package[i]; -+ } -+ -+ strcpy(&buffer[pln+i], ".lar"); -+ -+ if( (stat(buffer, &s) > -1) && (s.st_mode & S_IFREG) ) -+ return lar_open(buffer); -+ -+ seg--; -+ } -+ -+ return NULL; -+} -+ -+lar_member * lar_find_member( lar_archive *ar, const char *package ) -+{ -+ int len; -+ LAR_FNAME(buffer); -+ -+ for( len = 0; package[len] != '\0'; len++ ) -+ { -+ if( len >= (sizeof(buffer) - 5) ) -+ LAR_DIE("Package name exceeds maximum allowed length"); -+ -+ buffer[len] = ( package[len] == '.' ) ? '/' : package[len]; -+ } -+ -+ strcpy(&buffer[len], ".lua"); -+ -+ return lar_open_member(ar, buffer); -+} -diff -Nbur lua-5.1.4.orig/src/lar.h lua-5.1.4/src/lar.h ---- lua-5.1.4.orig/src/lar.h 1970-01-01 01:00:00.000000000 +0100 -+++ lua-5.1.4/src/lar.h 2009-04-13 17:13:47.000000000 +0200 -@@ -0,0 +1,108 @@ -+/* -+ * lar - Lua Archive Library -+ * -+ * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org> -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+ -+#ifndef __LAR_H -+#define __LAR_H -+ -+#include <stdio.h> -+#include <stdlib.h> -+#include <unistd.h> -+#include <stdint.h> -+#include <fcntl.h> -+#include <string.h> -+#include <errno.h> -+#include <arpa/inet.h> -+#include <sys/types.h> -+#include <sys/mman.h> -+#include <sys/stat.h> -+ -+#include "md5.h" -+ -+#define LAR_DIE(s) \ -+ do { \ -+ fprintf(stderr, "%s(%i): %s(): %s\n", \ -+ __FILE__, __LINE__, __FUNCTION__, s); \ -+ if( errno ) fprintf(stderr, "%s(%i): %s\n", \ -+ __FILE__, __LINE__, strerror(errno) ); \ -+ exit(1); \ -+ } while(0) -+ -+ -+#define LAR_FNAME_BUFFER 1024 -+#define LAR_FNAME(s) char s[LAR_FNAME_BUFFER] -+ -+#define LAR_TYPE_REGULAR 0x0000 -+#define LAR_TYPE_FILELIST 0xFFFF -+ -+#ifdef __WIN32__ -+#define LAR_DIRSEP '\\' -+#else -+#define LAR_DIRSEP '/' -+#endif -+ -+ -+struct lar_index_item { -+ uint32_t offset; -+ uint32_t length; -+ uint16_t type; -+ uint16_t flags; -+ char id[16]; -+ char *filename; -+ struct lar_index_item *next; -+}; -+ -+struct lar_member_item { -+ uint16_t type; -+ uint16_t flags; -+ uint32_t length; -+ char *data; -+ char *mmap; -+ size_t mlen; -+}; -+ -+struct lar_archive_handle { -+ int fd; -+ int has_filenames; -+ off_t length; -+ char filename[LAR_FNAME_BUFFER]; -+ struct lar_index_item *index; -+}; -+ -+typedef struct lar_index_item lar_index; -+typedef struct lar_member_item lar_member; -+typedef struct lar_archive_handle lar_archive; -+ -+ -+lar_index * lar_get_index( lar_archive *ar ); -+ -+lar_member * lar_mmap_member( lar_archive *ar, lar_index *idx_ptr ); -+ -+lar_member * lar_open_member( lar_archive *ar, const char *name ); -+ -+int lar_close_member( lar_member *member ); -+ -+lar_archive * lar_open( const char *filename ); -+ -+int lar_close( lar_archive *ar ); -+ -+lar_archive * lar_find_archive( const char *package, const char *path, int pkg); -+ -+lar_member * lar_find_member( lar_archive *ar, const char *package ); -+ -+#endif -diff -Nbur lua-5.1.4.orig/src/larlib.c lua-5.1.4/src/larlib.c ---- lua-5.1.4.orig/src/larlib.c 1970-01-01 01:00:00.000000000 +0100 -+++ lua-5.1.4/src/larlib.c 2009-04-13 17:24:57.000000000 +0200 -@@ -0,0 +1,540 @@ -+/* -+ * lar - Lua Archive Library -+ * -+ * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org> -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+ -+#include "lua.h" -+#include "lualib.h" -+#include "lauxlib.h" -+#include "lar.h" -+ -+typedef struct { -+ int fd; -+ char *data; -+ size_t length; -+} mmap_handle; -+ -+static int larlib_perror( lua_State *L, const char *message ) -+{ -+ lua_pushnil(L); -+ lua_pushstring(L, message); -+ -+ return 2; -+} -+ -+int larlib_open( lua_State *L ) -+{ -+ lar_archive *ar, **udata; -+ const char *filename = luaL_checkstring( L, 1 ); -+ -+ if( filename != NULL && (ar = lar_open(filename)) != NULL ) -+ { -+ if( (udata = lua_newuserdata(L, sizeof(lar_archive *))) != NULL ) -+ { -+ *udata = ar; -+ luaL_getmetatable(L, "lar.archive"); -+ lua_setmetatable(L, -2); -+ } -+ else -+ { -+ return luaL_error(L, "Out of memory"); -+ } -+ } -+ else -+ { -+ return larlib_perror(L, "Archive not found"); -+ } -+ -+ return 1; -+} -+ -+int larlib_find( lua_State *L ) -+{ -+ const char *filename = luaL_checkstring( L, 1 ); -+ const char *basepath = luaL_optstring( L, 2, "./" ); -+ int is_pkg = strstr(filename, "/") ? 0 : 1; -+ lar_archive *ar, **udata; -+ -+ if( ((ar = lar_find_archive(filename, basepath, is_pkg)) != NULL) || -+ ((ar = lar_find_archive(filename, LUA_LDIR, is_pkg)) != NULL) || -+ ((ar = lar_find_archive(filename, LUA_CDIR, is_pkg)) != NULL) ) -+ { -+ if( (udata = lua_newuserdata(L, sizeof(lar_archive *))) != NULL ) -+ { -+ *udata = ar; -+ luaL_getmetatable(L, "lar.archive"); -+ lua_setmetatable(L, -2); -+ } -+ else -+ { -+ return luaL_error(L, "Out of memory"); -+ } -+ } -+ else -+ { -+ return larlib_perror(L, "Archive not found"); -+ } -+ -+ return 1; -+} -+ -+int larlib_md5( lua_State *L ) -+{ -+ int i; -+ char md5[16], md5_hex[33]; -+ const char *data = luaL_checkstring( L, 1 ); -+ md5_state_t state; -+ -+ md5_init(&state); -+ md5_append(&state, (const md5_byte_t *)data, strlen(data)); -+ md5_finish(&state, (md5_byte_t *)md5); -+ -+ for( i = 0; i < 16; i++ ) -+ sprintf(&md5_hex[i*2], "%02x", (unsigned char)md5[i]); -+ -+ lua_pushstring(L, md5_hex); -+ return 1; -+} -+ -+int larlib_md5_file( lua_State *L ) -+{ -+ int i, fd, len; -+ char md5[16], md5_hex[33], buffer[1024]; -+ const char *filename = luaL_checkstring( L, 1 ); -+ md5_state_t state; -+ -+ if( (fd = open(filename, O_RDONLY)) != -1 ) -+ { -+ md5_init(&state); -+ -+ while( (len = read(fd, buffer, 1024)) > 0 ) -+ md5_append(&state, (const md5_byte_t *)buffer, len); -+ -+ md5_finish(&state, (md5_byte_t *)md5); -+ -+ for( i = 0; i < 16; i++ ) -+ sprintf(&md5_hex[i*2], "%02x", (unsigned char)md5[i]); -+ -+ close(fd); -+ lua_pushstring(L, md5_hex); -+ } -+ else -+ { -+ return larlib_perror(L, strerror(errno)); -+ } -+ -+ return 1; -+} -+ -+static int larlib_mkpath( const char *name, const char *path, char *buffer ) -+{ -+ int nlen = strlen(name); -+ int plen = strlen(path); -+ -+ if( (nlen + plen + 1) <= LAR_FNAME_BUFFER ) -+ { -+ strcpy(buffer, path); -+ -+ if( buffer[plen-1] != '/' ) -+ buffer[plen++] = '/'; -+ -+ strcpy(&buffer[plen], name); -+ buffer[plen + nlen] = '\0'; -+ -+ return 0; -+ } -+ -+ return 1; -+} -+ -+static int larlib__gc( lua_State *L ) -+{ -+ lar_archive **archive = luaL_checkudata( L, 1, "lar.archive" ); -+ -+ if( *archive ) -+ lar_close(*archive); -+ -+ *archive = NULL; -+ return 0; -+} -+ -+ -+static int larlib_member__open( lua_State *L, lar_member *mb ) -+{ -+ lar_archive **archive = NULL; -+ const char *filename = NULL; -+ lar_member **udata; -+ -+ if( mb == NULL ) -+ { -+ *archive = luaL_checkudata( L, 1, "lar.archive" ); -+ filename = luaL_checkstring( L, 2 ); -+ } -+ -+ if( mb != NULL || (mb = lar_open_member(*archive, filename)) != NULL ) -+ { -+ if( (udata = lua_newuserdata(L, sizeof(lar_member *))) != NULL ) -+ { -+ *udata = mb; -+ luaL_getmetatable(L, "lar.member"); -+ lua_setmetatable(L, -2); -+ } -+ else -+ { -+ return luaL_error(L, "Out of memory"); -+ } -+ } -+ else -+ { -+ return larlib_perror(L, "Member not found in archive"); -+ } -+ -+ return 1; -+} -+ -+int larlib_member_open( lua_State *L ) -+{ -+ return larlib_member__open( L, NULL ); -+} -+ -+int larlib_member_find( lua_State *L ) -+{ -+ lar_archive **archive = luaL_checkudata( L, 1, "lar.archive" ); -+ const char *package = luaL_checkstring( L, 2 ); -+ lar_member *mb, **udata; -+ -+ if( (mb = lar_find_member(*archive, package)) != NULL ) -+ { -+ if( (udata = lua_newuserdata(L, sizeof(lar_member *))) != NULL ) -+ { -+ *udata = mb; -+ luaL_getmetatable(L, "lar.member"); -+ lua_setmetatable(L, -2); -+ } -+ else -+ { -+ return luaL_error(L, "Out of memory"); -+ } -+ } -+ else -+ { -+ return larlib_perror(L, "Member not found in archive"); -+ } -+ -+ return 1; -+} -+ -+int larlib_member_size( lua_State *L ) -+{ -+ lar_member **member = luaL_checkudata( L, 1, "lar.member" ); -+ lua_pushnumber(L, (*member)->length); -+ return 1; -+} -+ -+int larlib_member_type( lua_State *L ) -+{ -+ lar_member **member = luaL_checkudata( L, 1, "lar.member" ); -+ lua_pushnumber(L, (*member)->type); -+ return 1; -+} -+ -+int larlib_member_flags( lua_State *L ) -+{ -+ lar_member **member = luaL_checkudata( L, 1, "lar.member" ); -+ lua_pushnumber(L, (*member)->flags); -+ return 1; -+} -+ -+int larlib_member_read( lua_State *L ) -+{ -+ lar_member **member = luaL_checkudata( L, 1, "lar.member" ); -+ int start = luaL_checknumber( L, 2 ); -+ int length = luaL_optnumber( L, 3, (*member)->length ); -+ char *stringcopy; -+ -+ if( (start >= 0) && (start < (*member)->length) && (length > 0) ) -+ { -+ if( (start + length) >= (*member)->length ) -+ length = (*member)->length - start; -+ -+ if( (stringcopy = (char *)malloc(length + 1)) != NULL ) -+ { -+ memcpy(stringcopy, &(*member)->data[start], length); -+ stringcopy[length] = '\0'; -+ lua_pushstring(L, stringcopy); -+ free(stringcopy); -+ } -+ else -+ { -+ return luaL_error(L, "Out of memory"); -+ } -+ } -+ else -+ { -+ return larlib_perror(L, "Invalid argument"); -+ } -+ -+ return 1; -+} -+ -+int larlib_member_data( lua_State *L ) -+{ -+ lar_member **member = luaL_checkudata( L, 1, "lar.member" ); -+ lua_pushstring(L, (*member)->data); -+ return 1; -+} -+ -+int larlib_member_load( lua_State *L ) -+{ -+ lar_member **member = luaL_checkudata( L, 1, "lar.member" ); -+ int status = luaL_loadbuffer( L, (*member)->data, (*member)->length, -+ "=(lar member)" ); -+ -+ if( status ) -+ { -+ lua_pushnil(L); -+ lua_insert(L, -2); -+ return 2; -+ } -+ -+ return 1; -+} -+ -+static int larlib_member__gc( lua_State *L ) -+{ -+ lar_member **member = luaL_checkudata( L, 1, "lar.member" ); -+ -+ if( *member ) -+ lar_close_member(*member); -+ -+ *member = NULL; -+ return 0; -+} -+ -+ -+static int larlib_mmfile__open( lua_State *L, const char *filename ) -+{ -+ struct stat s; -+ mmap_handle *fh, **udata; -+ -+ if( filename == NULL ) -+ filename = (const char *)luaL_checkstring( L, 1 ); -+ -+ if( (fh = (mmap_handle *)malloc(sizeof(mmap_handle))) == NULL ) -+ return larlib_perror(L, "Out of memory"); -+ -+ if( stat(filename, &s) > -1 && (fh->fd = open(filename, O_RDONLY)) > -1 ) -+ { -+ fh->length = s.st_size; -+ fh->data = mmap( 0, s.st_size, PROT_READ, MAP_PRIVATE, fh->fd, 0 ); -+ -+ if( fh->data == MAP_FAILED ) -+ return larlib_perror(L, "Failed to mmap() file"); -+ -+ if( (udata = lua_newuserdata(L, sizeof(char *))) != NULL ) -+ { -+ *udata = fh; -+ luaL_getmetatable(L, "lar.mmfile"); -+ lua_setmetatable(L, -2); -+ } -+ else -+ { -+ return larlib_perror(L, "Out of memory"); -+ } -+ } -+ else -+ { -+ return larlib_perror(L, strerror(errno)); -+ } -+ -+ return 1; -+} -+ -+int larlib_mmfile_open( lua_State *L ) -+{ -+ return larlib_mmfile__open(L, NULL); -+} -+ -+int larlib_mmfile_size( lua_State *L ) -+{ -+ mmap_handle **fh = luaL_checkudata( L, 1, "lar.mmfile" ); -+ lua_pushnumber(L, (*fh)->length); -+ return 1; -+} -+ -+int larlib_mmfile_read( lua_State *L ) -+{ -+ mmap_handle **fh = luaL_checkudata( L, 1, "lar.mmfile" ); -+ int start = luaL_checknumber( L, 2 ); -+ int length = luaL_optnumber( L, 3, (*fh)->length ); -+ char *stringcopy; -+ -+ if( (start >= 0) && (start < (*fh)->length) && (length > 0) ) -+ { -+ if( (start + length) >= (*fh)->length ) -+ length = (*fh)->length - start; -+ -+ if( (stringcopy = (char *)malloc(length + 1)) != NULL ) -+ { -+ memcpy(stringcopy, &(*fh)->data[start], length); -+ stringcopy[length] = '\0'; -+ lua_pushstring(L, stringcopy); -+ free(stringcopy); -+ } -+ else -+ { -+ return luaL_error(L, "Out of memory"); -+ } -+ } -+ else -+ { -+ return larlib_perror(L, "Invalid argument"); -+ } -+ -+ return 1; -+} -+ -+int larlib_mmfile_data( lua_State *L ) -+{ -+ mmap_handle **fh = luaL_checkudata( L, 1, "lar.mmfile" ); -+ lua_pushstring(L, (*fh)->data); -+ return 1; -+} -+ -+int larlib_mmfile_load( lua_State *L ) -+{ -+ mmap_handle **fh = luaL_checkudata( L, 1, "lar.mmfile" ); -+ int status = luaL_loadbuffer(L, (*fh)->data, (*fh)->length, "=(mmap file)"); -+ -+ if( status ) -+ { -+ lua_pushnil(L); -+ lua_insert(L, -2); -+ return 2; -+ } -+ -+ return 1; -+} -+ -+static int larlib_mmfile__gc( lua_State *L ) -+{ -+ mmap_handle **fh = luaL_checkudata( L, 1, "lar.mmfile" ); -+ -+ if( *fh ) -+ { -+ close((*fh)->fd); -+ munmap((*fh)->data, (*fh)->length); -+ free(*fh); -+ *fh = NULL; -+ } -+ -+ return 0; -+} -+ -+ -+int larlib_findfile( lua_State *L ) -+{ -+ int i; -+ const char *filename = luaL_checkstring( L, 1 ); -+ const char *basepath = luaL_optstring( L, 2, "./" ); -+ struct stat s; -+ lar_archive *ar; -+ lar_member *mb; -+ LAR_FNAME(filepath); -+ -+ const char *searchpath[3] = { basepath, LUA_LDIR, LUA_CDIR }; -+ -+ for( i = 0; i < 3; i++ ) -+ if( !larlib_mkpath(filename, searchpath[i], filepath) ) -+ if( stat(filepath, &s) > -1 && (s.st_mode & S_IFREG) ) -+ return larlib_mmfile__open( L, filepath ); -+ -+ for( i = 0; i < 3; i++ ) -+ if( (ar = lar_find_archive(filename, searchpath[i], 0)) != NULL ) -+ if( (mb = lar_open_member(ar, filename)) != NULL ) -+ return larlib_member__open( L, mb ); -+ -+ return larlib_perror(L, "File not found"); -+} -+ -+ -+static const luaL_reg LAR_REG[] = { -+ { "open", larlib_open }, -+ { "find", larlib_find }, -+ { "md5", larlib_md5 }, -+ { "md5_file", larlib_md5_file }, -+ { "mmap", larlib_mmfile_open }, -+ { "findfile", larlib_findfile }, -+ { NULL, NULL } -+}; -+ -+static const luaL_reg LAR_ARCHIVE_REG[] = { -+ { "member", larlib_member_open }, -+ { "find", larlib_member_find }, -+ { "__gc", larlib__gc }, -+ { NULL, NULL } -+}; -+ -+static const luaL_reg LAR_MEMBER_REG[] = { -+ { "size", larlib_member_size }, -+ { "type", larlib_member_type }, -+ { "flags", larlib_member_flags }, -+ { "read", larlib_member_read }, -+ { "data", larlib_member_data }, -+ { "load", larlib_member_load }, -+ { "__gc", larlib_member__gc }, -+ { NULL, NULL } -+}; -+ -+static const luaL_reg LAR_MMFILE_REG[] = { -+ { "size", larlib_mmfile_size }, -+ { "read", larlib_mmfile_read }, -+ { "data", larlib_mmfile_data }, -+ { "load", larlib_mmfile_load }, -+ { "__gc", larlib_mmfile__gc }, -+ { NULL, NULL } -+}; -+ -+ -+LUALIB_API int luaopen_larlib( lua_State *L ) -+{ -+ luaL_newmetatable(L, "lar"); -+ luaL_register(L, NULL, LAR_REG); -+ lua_pushvalue(L, -1); -+ lua_setfield(L, -2, "__index"); -+ lua_setglobal(L, "lar"); -+ -+ luaL_newmetatable(L, "lar.archive"); -+ luaL_register(L, NULL, LAR_ARCHIVE_REG); -+ lua_pushvalue(L, -1); -+ lua_setfield(L, -2, "__index"); -+ lua_setglobal(L, "lar.archive"); -+ -+ luaL_newmetatable(L, "lar.member"); -+ luaL_register(L, NULL, LAR_MEMBER_REG); -+ lua_pushvalue(L, -1); -+ lua_setfield(L, -2, "__index"); -+ lua_setglobal(L, "lar.member"); -+ -+ luaL_newmetatable(L, "lar.mmfile"); -+ luaL_register(L, NULL, LAR_MMFILE_REG); -+ lua_pushvalue(L, -1); -+ lua_setfield(L, -2, "__index"); -+ lua_setglobal(L, "lar.mmfile"); -+ -+ return 1; -+} -diff -Nbur lua-5.1.4.orig/src/linit.c lua-5.1.4/src/linit.c ---- lua-5.1.4.orig/src/linit.c 2009-04-06 21:36:52.000000000 +0200 -+++ lua-5.1.4/src/linit.c 2009-04-11 01:27:00.000000000 +0200 -@@ -23,6 +23,7 @@ - {LUA_STRLIBNAME, luaopen_string}, - {LUA_MATHLIBNAME, luaopen_math}, - {LUA_DBLIBNAME, luaopen_debug}, -+ {LUA_LARLIBNAME, luaopen_larlib}, - {NULL, NULL} - }; - -diff -Nbur lua-5.1.4.orig/src/loadlib.c lua-5.1.4/src/loadlib.c ---- lua-5.1.4.orig/src/loadlib.c 2009-04-06 21:36:52.000000000 +0200 -+++ lua-5.1.4/src/loadlib.c 2009-04-11 01:04:47.000000000 +0200 -@@ -21,6 +21,7 @@ - #include "lauxlib.h" - #include "lualib.h" - -+#include "lar.h" - - /* prefix for open functions in C libraries */ - #define LUA_POF "luaopen_" -@@ -388,6 +389,36 @@ - } - - -+static int loader_Lar (lua_State *L) { -+ lar_archive *ar; -+ lar_member *mb; -+ const char *name = luaL_checkstring(L, 1); -+ -+ if( (ar = lar_find_archive(name, "./", 1)) || -+ (ar = lar_find_archive(name, LUA_LDIR, 1)) || -+ (ar = lar_find_archive(name, LUA_CDIR, 1)) -+ ) { -+ if( (mb = lar_find_member(ar, name)) != NULL ) { -+ if( luaL_loadbuffer(L, mb->data, mb->length, ar->filename) != 0 ) { -+ luaL_error(L, "error while loading lar member '%s':\n\t%s", -+ name, lua_tostring(L, -1)); -+ } -+ lar_close_member(mb); -+ } -+ else { -+ lua_pushfstring(L, "\n\tno matching lar member " LUA_QS " in " LUA_QS, -+ name, ar->filename); -+ } -+ lar_close(ar); -+ } -+ else { -+ lua_pushfstring(L, "\n\tno matching lar archive for " LUA_QS, name); -+ } -+ -+ return 1; -+} -+ -+ - static const char *mkfuncname (lua_State *L, const char *modname) { - const char *funcname; - const char *mark = strchr(modname, *LUA_IGMARK); -@@ -621,7 +652,7 @@ - - - static const lua_CFunction loaders[] = -- {loader_preload, loader_Lua, loader_C, loader_Croot, NULL}; -+ {loader_preload, loader_Lua, loader_Lar, loader_C, loader_Croot, NULL}; - - - LUALIB_API int luaopen_package (lua_State *L) { -diff -Nbur lua-5.1.4.orig/src/lualib.h lua-5.1.4/src/lualib.h ---- lua-5.1.4.orig/src/lualib.h 2009-04-06 21:36:52.000000000 +0200 -+++ lua-5.1.4/src/lualib.h 2009-04-11 01:28:24.000000000 +0200 -@@ -39,6 +39,9 @@ - #define LUA_LOADLIBNAME "package" - LUALIB_API int (luaopen_package) (lua_State *L); - -+#define LUA_LARLIBNAME "lar" -+LUALIB_API int (luaopen_larlib) (lua_State *L); -+ - - /* open all previous libraries */ - LUALIB_API void (luaL_openlibs) (lua_State *L); -diff -Nbur lua-5.1.4.orig/src/md5.c lua-5.1.4/src/md5.c ---- lua-5.1.4.orig/src/md5.c 1970-01-01 01:00:00.000000000 +0100 -+++ lua-5.1.4/src/md5.c 2009-04-10 23:07:56.000000000 +0200 -@@ -0,0 +1,381 @@ -+/* -+ Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved. -+ -+ This software is provided 'as-is', without any express or implied -+ warranty. In no event will the authors be held liable for any damages -+ arising from the use of this software. -+ -+ Permission is granted to anyone to use this software for any purpose, -+ including commercial applications, and to alter it and redistribute it -+ freely, subject to the following restrictions: -+ -+ 1. The origin of this software must not be misrepresented; you must not -+ claim that you wrote the original software. If you use this software -+ in a product, an acknowledgment in the product documentation would be -+ appreciated but is not required. -+ 2. Altered source versions must be plainly marked as such, and must not be -+ misrepresented as being the original software. -+ 3. This notice may not be removed or altered from any source distribution. -+ -+ L. Peter Deutsch -+ ghost@aladdin.com -+ -+ */ -+/* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */ -+/* -+ Independent implementation of MD5 (RFC 1321). -+ -+ This code implements the MD5 Algorithm defined in RFC 1321, whose -+ text is available at -+ http://www.ietf.org/rfc/rfc1321.txt -+ The code is derived from the text of the RFC, including the test suite -+ (section A.5) but excluding the rest of Appendix A. It does not include -+ any code or documentation that is identified in the RFC as being -+ copyrighted. -+ -+ The original and principal author of md5.c is L. Peter Deutsch -+ <ghost@aladdin.com>. Other authors are noted in the change history -+ that follows (in reverse chronological order): -+ -+ 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order -+ either statically or dynamically; added missing #include <string.h> -+ in library. -+ 2002-03-11 lpd Corrected argument list for main(), and added int return -+ type, in test program and T value program. -+ 2002-02-21 lpd Added missing #include <stdio.h> in test program. -+ 2000-07-03 lpd Patched to eliminate warnings about "constant is -+ unsigned in ANSI C, signed in traditional"; made test program -+ self-checking. -+ 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. -+ 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). -+ 1999-05-03 lpd Original version. -+ */ -+ -+#include "md5.h" -+#include <string.h> -+ -+#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */ -+#ifdef ARCH_IS_BIG_ENDIAN -+# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1) -+#else -+# define BYTE_ORDER 0 -+#endif -+ -+#define T_MASK ((md5_word_t)~0) -+#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87) -+#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9) -+#define T3 0x242070db -+#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111) -+#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050) -+#define T6 0x4787c62a -+#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec) -+#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe) -+#define T9 0x698098d8 -+#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850) -+#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e) -+#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841) -+#define T13 0x6b901122 -+#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c) -+#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71) -+#define T16 0x49b40821 -+#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d) -+#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf) -+#define T19 0x265e5a51 -+#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855) -+#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2) -+#define T22 0x02441453 -+#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e) -+#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437) -+#define T25 0x21e1cde6 -+#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829) -+#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278) -+#define T28 0x455a14ed -+#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa) -+#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07) -+#define T31 0x676f02d9 -+#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375) -+#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd) -+#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e) -+#define T35 0x6d9d6122 -+#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3) -+#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb) -+#define T38 0x4bdecfa9 -+#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f) -+#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f) -+#define T41 0x289b7ec6 -+#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805) -+#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a) -+#define T44 0x04881d05 -+#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6) -+#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a) -+#define T47 0x1fa27cf8 -+#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a) -+#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb) -+#define T50 0x432aff97 -+#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58) -+#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6) -+#define T53 0x655b59c3 -+#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d) -+#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82) -+#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e) -+#define T57 0x6fa87e4f -+#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f) -+#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb) -+#define T60 0x4e0811a1 -+#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d) -+#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca) -+#define T63 0x2ad7d2bb -+#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e) -+ -+ -+static void -+md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) -+{ -+ md5_word_t -+ a = pms->abcd[0], b = pms->abcd[1], -+ c = pms->abcd[2], d = pms->abcd[3]; -+ md5_word_t t; -+#if BYTE_ORDER > 0 -+ /* Define storage only for big-endian CPUs. */ -+ md5_word_t X[16]; -+#else -+ /* Define storage for little-endian or both types of CPUs. */ -+ md5_word_t xbuf[16]; -+ const md5_word_t *X; -+#endif -+ -+ { -+#if BYTE_ORDER == 0 -+ /* -+ * Determine dynamically whether this is a big-endian or -+ * little-endian machine, since we can use a more efficient -+ * algorithm on the latter. -+ */ -+ static const int w = 1; -+ -+ if (*((const md5_byte_t *)&w)) /* dynamic little-endian */ -+#endif -+#if BYTE_ORDER <= 0 /* little-endian */ -+ { -+ /* -+ * On little-endian machines, we can process properly aligned -+ * data without copying it. -+ */ -+ if (!((data - (const md5_byte_t *)0) & 3)) { -+ /* data are properly aligned */ -+ X = (const md5_word_t *)data; -+ } else { -+ /* not aligned */ -+ memcpy(xbuf, data, 64); -+ X = xbuf; -+ } -+ } -+#endif -+#if BYTE_ORDER == 0 -+ else /* dynamic big-endian */ -+#endif -+#if BYTE_ORDER >= 0 /* big-endian */ -+ { -+ /* -+ * On big-endian machines, we must arrange the bytes in the -+ * right order. -+ */ -+ const md5_byte_t *xp = data; -+ int i; -+ -+# if BYTE_ORDER == 0 -+ X = xbuf; /* (dynamic only) */ -+# else -+# define xbuf X /* (static only) */ -+# endif -+ for (i = 0; i < 16; ++i, xp += 4) -+ xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); -+ } -+#endif -+ } -+ -+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) -+ -+ /* Round 1. */ -+ /* Let [abcd k s i] denote the operation -+ a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ -+#define F(x, y, z) (((x) & (y)) | (~(x) & (z))) -+#define SET(a, b, c, d, k, s, Ti)\ -+ t = a + F(b,c,d) + X[k] + Ti;\ -+ a = ROTATE_LEFT(t, s) + b -+ /* Do the following 16 operations. */ -+ SET(a, b, c, d, 0, 7, T1); -+ SET(d, a, b, c, 1, 12, T2); -+ SET(c, d, a, b, 2, 17, T3); -+ SET(b, c, d, a, 3, 22, T4); -+ SET(a, b, c, d, 4, 7, T5); -+ SET(d, a, b, c, 5, 12, T6); -+ SET(c, d, a, b, 6, 17, T7); -+ SET(b, c, d, a, 7, 22, T8); -+ SET(a, b, c, d, 8, 7, T9); -+ SET(d, a, b, c, 9, 12, T10); -+ SET(c, d, a, b, 10, 17, T11); -+ SET(b, c, d, a, 11, 22, T12); -+ SET(a, b, c, d, 12, 7, T13); -+ SET(d, a, b, c, 13, 12, T14); -+ SET(c, d, a, b, 14, 17, T15); -+ SET(b, c, d, a, 15, 22, T16); -+#undef SET -+ -+ /* Round 2. */ -+ /* Let [abcd k s i] denote the operation -+ a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ -+#define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) -+#define SET(a, b, c, d, k, s, Ti)\ -+ t = a + G(b,c,d) + X[k] + Ti;\ -+ a = ROTATE_LEFT(t, s) + b -+ /* Do the following 16 operations. */ -+ SET(a, b, c, d, 1, 5, T17); -+ SET(d, a, b, c, 6, 9, T18); -+ SET(c, d, a, b, 11, 14, T19); -+ SET(b, c, d, a, 0, 20, T20); -+ SET(a, b, c, d, 5, 5, T21); -+ SET(d, a, b, c, 10, 9, T22); -+ SET(c, d, a, b, 15, 14, T23); -+ SET(b, c, d, a, 4, 20, T24); -+ SET(a, b, c, d, 9, 5, T25); -+ SET(d, a, b, c, 14, 9, T26); -+ SET(c, d, a, b, 3, 14, T27); -+ SET(b, c, d, a, 8, 20, T28); -+ SET(a, b, c, d, 13, 5, T29); -+ SET(d, a, b, c, 2, 9, T30); -+ SET(c, d, a, b, 7, 14, T31); -+ SET(b, c, d, a, 12, 20, T32); -+#undef SET -+ -+ /* Round 3. */ -+ /* Let [abcd k s t] denote the operation -+ a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ -+#define H(x, y, z) ((x) ^ (y) ^ (z)) -+#define SET(a, b, c, d, k, s, Ti)\ -+ t = a + H(b,c,d) + X[k] + Ti;\ -+ a = ROTATE_LEFT(t, s) + b -+ /* Do the following 16 operations. */ -+ SET(a, b, c, d, 5, 4, T33); -+ SET(d, a, b, c, 8, 11, T34); -+ SET(c, d, a, b, 11, 16, T35); -+ SET(b, c, d, a, 14, 23, T36); -+ SET(a, b, c, d, 1, 4, T37); -+ SET(d, a, b, c, 4, 11, T38); -+ SET(c, d, a, b, 7, 16, T39); -+ SET(b, c, d, a, 10, 23, T40); -+ SET(a, b, c, d, 13, 4, T41); -+ SET(d, a, b, c, 0, 11, T42); -+ SET(c, d, a, b, 3, 16, T43); -+ SET(b, c, d, a, 6, 23, T44); -+ SET(a, b, c, d, 9, 4, T45); -+ SET(d, a, b, c, 12, 11, T46); -+ SET(c, d, a, b, 15, 16, T47); -+ SET(b, c, d, a, 2, 23, T48); -+#undef SET -+ -+ /* Round 4. */ -+ /* Let [abcd k s t] denote the operation -+ a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ -+#define I(x, y, z) ((y) ^ ((x) | ~(z))) -+#define SET(a, b, c, d, k, s, Ti)\ -+ t = a + I(b,c,d) + X[k] + Ti;\ -+ a = ROTATE_LEFT(t, s) + b -+ /* Do the following 16 operations. */ -+ SET(a, b, c, d, 0, 6, T49); -+ SET(d, a, b, c, 7, 10, T50); -+ SET(c, d, a, b, 14, 15, T51); -+ SET(b, c, d, a, 5, 21, T52); -+ SET(a, b, c, d, 12, 6, T53); -+ SET(d, a, b, c, 3, 10, T54); -+ SET(c, d, a, b, 10, 15, T55); -+ SET(b, c, d, a, 1, 21, T56); -+ SET(a, b, c, d, 8, 6, T57); -+ SET(d, a, b, c, 15, 10, T58); -+ SET(c, d, a, b, 6, 15, T59); -+ SET(b, c, d, a, 13, 21, T60); -+ SET(a, b, c, d, 4, 6, T61); -+ SET(d, a, b, c, 11, 10, T62); -+ SET(c, d, a, b, 2, 15, T63); -+ SET(b, c, d, a, 9, 21, T64); -+#undef SET -+ -+ /* Then perform the following additions. (That is increment each -+ of the four registers by the value it had before this block -+ was started.) */ -+ pms->abcd[0] += a; -+ pms->abcd[1] += b; -+ pms->abcd[2] += c; -+ pms->abcd[3] += d; -+} -+ -+void -+md5_init(md5_state_t *pms) -+{ -+ pms->count[0] = pms->count[1] = 0; -+ pms->abcd[0] = 0x67452301; -+ pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476; -+ pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301; -+ pms->abcd[3] = 0x10325476; -+} -+ -+void -+md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes) -+{ -+ const md5_byte_t *p = data; -+ int left = nbytes; -+ int offset = (pms->count[0] >> 3) & 63; -+ md5_word_t nbits = (md5_word_t)(nbytes << 3); -+ -+ if (nbytes <= 0) -+ return; -+ -+ /* Update the message length. */ -+ pms->count[1] += nbytes >> 29; -+ pms->count[0] += nbits; -+ if (pms->count[0] < nbits) -+ pms->count[1]++; -+ -+ /* Process an initial partial block. */ -+ if (offset) { -+ int copy = (offset + nbytes > 64 ? 64 - offset : nbytes); -+ -+ memcpy(pms->buf + offset, p, copy); -+ if (offset + copy < 64) -+ return; -+ p += copy; -+ left -= copy; -+ md5_process(pms, pms->buf); -+ } -+ -+ /* Process full blocks. */ -+ for (; left >= 64; p += 64, left -= 64) -+ md5_process(pms, p); -+ -+ /* Process a final partial block. */ -+ if (left) -+ memcpy(pms->buf, p, left); -+} -+ -+void -+md5_finish(md5_state_t *pms, md5_byte_t digest[16]) -+{ -+ static const md5_byte_t pad[64] = { -+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -+ }; -+ md5_byte_t data[8]; -+ int i; -+ -+ /* Save the length before padding. */ -+ for (i = 0; i < 8; ++i) -+ data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); -+ /* Pad to 56 bytes mod 64. */ -+ md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); -+ /* Append the length. */ -+ md5_append(pms, data, 8); -+ for (i = 0; i < 16; ++i) -+ digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); -+} -diff -Nbur lua-5.1.4.orig/src/md5.h lua-5.1.4/src/md5.h ---- lua-5.1.4.orig/src/md5.h 1970-01-01 01:00:00.000000000 +0100 -+++ lua-5.1.4/src/md5.h 2009-04-10 23:07:56.000000000 +0200 -@@ -0,0 +1,91 @@ -+/* -+ Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved. -+ -+ This software is provided 'as-is', without any express or implied -+ warranty. In no event will the authors be held liable for any damages -+ arising from the use of this software. -+ -+ Permission is granted to anyone to use this software for any purpose, -+ including commercial applications, and to alter it and redistribute it -+ freely, subject to the following restrictions: -+ -+ 1. The origin of this software must not be misrepresented; you must not -+ claim that you wrote the original software. If you use this software -+ in a product, an acknowledgment in the product documentation would be -+ appreciated but is not required. -+ 2. Altered source versions must be plainly marked as such, and must not be -+ misrepresented as being the original software. -+ 3. This notice may not be removed or altered from any source distribution. -+ -+ L. Peter Deutsch -+ ghost@aladdin.com -+ -+ */ -+/* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */ -+/* -+ Independent implementation of MD5 (RFC 1321). -+ -+ This code implements the MD5 Algorithm defined in RFC 1321, whose -+ text is available at -+ http://www.ietf.org/rfc/rfc1321.txt -+ The code is derived from the text of the RFC, including the test suite -+ (section A.5) but excluding the rest of Appendix A. It does not include -+ any code or documentation that is identified in the RFC as being -+ copyrighted. -+ -+ The original and principal author of md5.h is L. Peter Deutsch -+ <ghost@aladdin.com>. Other authors are noted in the change history -+ that follows (in reverse chronological order): -+ -+ 2002-04-13 lpd Removed support for non-ANSI compilers; removed -+ references to Ghostscript; clarified derivation from RFC 1321; -+ now handles byte order either statically or dynamically. -+ 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. -+ 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5); -+ added conditionalization for C++ compilation from Martin -+ Purschke <purschke@bnl.gov>. -+ 1999-05-03 lpd Original version. -+ */ -+ -+#ifndef md5_INCLUDED -+# define md5_INCLUDED -+ -+/* -+ * This package supports both compile-time and run-time determination of CPU -+ * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be -+ * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is -+ * defined as non-zero, the code will be compiled to run only on big-endian -+ * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to -+ * run on either big- or little-endian CPUs, but will run slightly less -+ * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined. -+ */ -+ -+typedef unsigned char md5_byte_t; /* 8-bit byte */ -+typedef unsigned int md5_word_t; /* 32-bit word */ -+ -+/* Define the state of the MD5 Algorithm. */ -+typedef struct md5_state_s { -+ md5_word_t count[2]; /* message length in bits, lsw first */ -+ md5_word_t abcd[4]; /* digest buffer */ -+ md5_byte_t buf[64]; /* accumulate block */ -+} md5_state_t; -+ -+#ifdef __cplusplus -+extern "C" -+{ -+#endif -+ -+/* Initialize the algorithm. */ -+void md5_init(md5_state_t *pms); -+ -+/* Append a string to the message. */ -+void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes); -+ -+/* Finish the message and return the digest. */ -+void md5_finish(md5_state_t *pms, md5_byte_t digest[16]); -+ -+#ifdef __cplusplus -+} /* end extern "C" */ -+#endif -+ -+#endif /* md5_INCLUDED */ |