From 3f8ef40535f4e5438832911ee3065fdb92602364 Mon Sep 17 00:00:00 2001 From: Henning Rogge Date: Wed, 17 Mar 2010 17:35:31 +0100 Subject: [PATCH] More fixes for "strict aliasing rules" --- lib/bmf/src/NetworkInterfaces.c | 45 ++++++++++++++++++-------- lib/httpinfo/src/olsrd_httpinfo.c | 2 +- lib/httpinfo/src/olsrd_plugin.c | 42 +++++++------------------ lib/httpinfo/src/olsrd_plugin.h | 3 +- lib/tas/src/os_unix.c | 52 +++++++++++++++---------------- lib/txtinfo/src/olsrd_txtinfo.c | 43 +++++++++++-------------- src/cfgparser/cfgfile_gen.c | 4 ++- src/cfgparser/oscan.lex | 2 ++ src/ipcalc.c | 23 +++++++++++--- src/olsr_types.h | 7 +++++ 10 files changed, 119 insertions(+), 104 deletions(-) diff --git a/lib/bmf/src/NetworkInterfaces.c b/lib/bmf/src/NetworkInterfaces.c index 5b334a18..c29e7e1a 100644 --- a/lib/bmf/src/NetworkInterfaces.c +++ b/lib/bmf/src/NetworkInterfaces.c @@ -1182,6 +1182,7 @@ static int CreateLocalEtherTunTap(void) { static const char deviceName[] = "/dev/net/tun"; struct ifreq ifreq; + union olsr_sockaddr sock; int etfd; int ioctlSkfd; int ioctlres; @@ -1249,17 +1250,23 @@ static int CreateLocalEtherTunTap(void) EtherTunTapIp = ETHERTUNTAPDEFAULTIP; } - ((struct sockaddr_in*)&ifreq.ifr_addr)->sin_addr.s_addr = htonl(EtherTunTapIp); + memset(&sock, 0, sizeof(sock)); + sock.in4.sin_family = AF_INET; + + sock.in4.sin_addr.s_addr = htonl(EtherTunTapIp); + ifreq.ifr_addr = sock.in; ioctlres = ioctl(ioctlSkfd, SIOCSIFADDR, &ifreq); if (ioctlres >= 0) { /* Set net mask */ - ((struct sockaddr_in*)&ifreq.ifr_netmask)->sin_addr.s_addr = htonl(EtherTunTapIpMask); + sock.in4.sin_addr.s_addr = htonl(EtherTunTapIpMask); + ifreq.ifr_netmask = sock.in; ioctlres = ioctl(ioctlSkfd, SIOCSIFNETMASK, &ifreq); if (ioctlres >= 0) { /* Set broadcast IP */ - ((struct sockaddr_in*)&ifreq.ifr_broadaddr)->sin_addr.s_addr = htonl(EtherTunTapIpBroadcast); + sock.in4.sin_addr.s_addr = htonl(EtherTunTapIpBroadcast); + ifreq.ifr_broadaddr = sock.in; ioctlres = ioctl(ioctlSkfd, SIOCSIFBRDADDR, &ifreq); if (ioctlres >= 0) { @@ -1869,6 +1876,8 @@ void CheckAndUpdateLocalBroadcast(unsigned char* ipPacket, union olsr_ip_addr* b void AddMulticastRoute(void) { struct rtentry kernel_route; + union olsr_sockaddr sock; + int ioctlSkfd = socket(PF_INET, SOCK_DGRAM, 0); if (ioctlSkfd < 0) { @@ -1878,13 +1887,17 @@ void AddMulticastRoute(void) memset(&kernel_route, 0, sizeof(struct rtentry)); - ((struct sockaddr_in*)&kernel_route.rt_dst)->sin_family = AF_INET; - ((struct sockaddr_in*)&kernel_route.rt_gateway)->sin_family = AF_INET; - ((struct sockaddr_in*)&kernel_route.rt_genmask)->sin_family = AF_INET; + kernel_route.rt_gateway.sa_family = AF_INET; /* 224.0.0.0/4 */ - ((struct sockaddr_in *)&kernel_route.rt_dst)->sin_addr.s_addr = htonl(0xE0000000); - ((struct sockaddr_in *)&kernel_route.rt_genmask)->sin_addr.s_addr = htonl(0xF0000000); + memset(&sock, 0, sizeof(sock)); + sock.in4.sin_family = AF_INET; + + sock.in4.sin_addr.s_addr = htonl(0xE0000000); + kernel_route.rt_dst = sock.in; + + sock.in4.sin_addr.s_addr = htonl(0xF0000000); + kernel_route.rt_genmask = sock.in; kernel_route.rt_metric = 0; kernel_route.rt_flags = RTF_UP; @@ -1914,6 +1927,8 @@ void DeleteMulticastRoute(void) if (EtherTunTapIp != ETHERTUNTAPDEFAULTIP) { struct rtentry kernel_route; + union olsr_sockaddr sock; + int ioctlSkfd = socket(PF_INET, SOCK_DGRAM, 0); if (ioctlSkfd < 0) { @@ -1923,13 +1938,17 @@ void DeleteMulticastRoute(void) memset(&kernel_route, 0, sizeof(struct rtentry)); - ((struct sockaddr_in*)&kernel_route.rt_dst)->sin_family = AF_INET; - ((struct sockaddr_in*)&kernel_route.rt_gateway)->sin_family = AF_INET; - ((struct sockaddr_in*)&kernel_route.rt_genmask)->sin_family = AF_INET; + kernel_route.rt_gateway.sa_family = AF_INET; /* 224.0.0.0/4 */ - ((struct sockaddr_in *)&kernel_route.rt_dst)->sin_addr.s_addr = htonl(0xE0000000); - ((struct sockaddr_in *)&kernel_route.rt_genmask)->sin_addr.s_addr = htonl(0xF0000000); + memset(&sock, 0, sizeof(sock)); + sock.in4.sin_family = AF_INET; + + sock.in4.sin_addr.s_addr = htonl(0xE0000000); + kernel_route.rt_dst = sock.in; + + sock.in4.sin_addr.s_addr = htonl(0xF0000000); + kernel_route.rt_genmask = sock.in; kernel_route.rt_metric = 0; kernel_route.rt_flags = RTF_UP; diff --git a/lib/httpinfo/src/olsrd_httpinfo.c b/lib/httpinfo/src/olsrd_httpinfo.c index 06067822..1be7e92c 100644 --- a/lib/httpinfo/src/olsrd_httpinfo.c +++ b/lib/httpinfo/src/olsrd_httpinfo.c @@ -1153,7 +1153,7 @@ check_allowed_ip(const struct allowed_net *const my_allowed_nets, const union ol { const struct allowed_net *alln; for (alln = my_allowed_nets; alln != NULL; alln = alln->next) { - if ((addr->v4.s_addr & alln->mask.v4.s_addr) == (alln->net.v4.s_addr & alln->mask.v4.s_addr)) { + if (ip_in_net(addr, &alln->prefix)) { return 1; } } diff --git a/lib/httpinfo/src/olsrd_plugin.c b/lib/httpinfo/src/olsrd_plugin.c index 48f8a942..2e8c3d84 100644 --- a/lib/httpinfo/src/olsrd_plugin.c +++ b/lib/httpinfo/src/olsrd_plugin.c @@ -64,10 +64,7 @@ union olsr_ip_addr httpinfo_listen_ip; static void my_init(void) __attribute__ ((constructor)); static void my_fini(void) __attribute__ ((destructor)); -static int add_plugin_ipnet(const char *value, void *data, set_plugin_parameter_addon); -static int add_plugin_ipaddr(const char *value, void *data, set_plugin_parameter_addon); - -static int insert_plugin_ipnet(const char */*sz_net*/, const char */*sz_mask*/, struct allowed_net **/*allowed_nets*/); +static int add_plugin_access(const char *value, void *data, set_plugin_parameter_addon); /* * Defines the version of the plugin interface that is used @@ -108,8 +105,8 @@ my_fini(void) static const struct olsrd_plugin_parameters plugin_parameters[] = { {.name = "port",.set_plugin_parameter = &set_plugin_port,.data = &http_port}, - {.name = "host",.set_plugin_parameter = &add_plugin_ipaddr,.data = &allowed_nets}, - {.name = "net",.set_plugin_parameter = &add_plugin_ipnet,.data = &allowed_nets}, + {.name = "host",.set_plugin_parameter = &add_plugin_access,.data = &allowed_nets}, + {.name = "net",.set_plugin_parameter = &add_plugin_access,.data = &allowed_nets}, {.name = "resolve",.set_plugin_parameter = &set_plugin_boolean,.data = &resolve_ip_addresses}, }; @@ -121,43 +118,28 @@ olsrd_get_plugin_parameters(const struct olsrd_plugin_parameters **params, int * } static int -insert_plugin_ipnet(const char *sz_net, const char *sz_mask, struct allowed_net **my_allowed_nets) +add_plugin_access(const char *value, void *data, set_plugin_parameter_addon addon __attribute__ ((unused))) { + struct olsr_ip_prefix prefix; + struct allowed_net **my_allowed_nets = data; struct allowed_net *an; + if (olsr_string_to_prefix(olsr_cnf->ip_version, &prefix, value)) { + fprintf(stderr, "(HTTPINFO) unknown access restriction parameter: %s!\n", value); + exit(0); + } + an = olsr_malloc(sizeof(*an), __func__); if (an == NULL) { fprintf(stderr, "(HTTPINFO) register param net out of memory!\n"); exit(0); } - if (inet_aton(sz_net, &an->net.v4) == 0 || inet_aton(sz_mask, &an->mask.v4) == 0) { - free(an); - return 1; - } + an->prefix = prefix; an->next = *my_allowed_nets; *my_allowed_nets = an; return 0; } - -static int -add_plugin_ipnet(const char *value, void *data, set_plugin_parameter_addon addon __attribute__ ((unused))) -{ - char sz_net[100], sz_mask[100]; /* IPv6 in the future */ - - if (sscanf(value, "%99s %99s", sz_net, sz_mask) != 2) { - olsr_printf(1, "(HTTPINFO) Error parsing net param \"%s\"!\n", value); - return 0; - } - return insert_plugin_ipnet(sz_net, sz_mask, data); -} - -static int -add_plugin_ipaddr(const char *value, void *data, set_plugin_parameter_addon addon __attribute__ ((unused))) -{ - return insert_plugin_ipnet(value, "255.255.255.255", data); -} - /* * Local Variables: * mode: c diff --git a/lib/httpinfo/src/olsrd_plugin.h b/lib/httpinfo/src/olsrd_plugin.h index 15d2a8b9..b189d716 100644 --- a/lib/httpinfo/src/olsrd_plugin.h +++ b/lib/httpinfo/src/olsrd_plugin.h @@ -77,8 +77,7 @@ extern int resolve_ip_addresses; /* Allowed hosts stuff */ struct allowed_net { - union olsr_ip_addr net; - union olsr_ip_addr mask; + struct olsr_ip_prefix prefix; struct allowed_net *next; }; diff --git a/lib/tas/src/os_unix.c b/lib/tas/src/os_unix.c index 576f4ad6..83403ff0 100644 --- a/lib/tas/src/os_unix.c +++ b/lib/tas/src/os_unix.c @@ -402,29 +402,30 @@ rawIpAddrToString(void *rawAddr, int len) } static int -createSockAddr(struct sockaddr *sockAddr, const struct ipAddr *addr, int port) +createSockAddr(struct sockaddr_storage *sockAddr, const struct ipAddr *addr, int port) { - struct sockaddr_in *sockAddr4; - struct sockaddr_in6 *sockAddr6; - - memset(sockAddr, 0, sizeof(struct sockaddr)); + memset(sockAddr, 0, sizeof(struct sockaddr_storage)); if (addr->domain == PF_INET) { - sockAddr4 = (struct sockaddr_in *)ARM_NOWARN_ALIGN(sockAddr); + struct sockaddr_in sin; + memset(&sin, 0, sizeof(sin)); - sockAddr4->sin_family = AF_INET; - sockAddr4->sin_port = htons((short)port); - sockAddr4->sin_addr.s_addr = addr->addr.v4.s_addr; + sin.sin_family = AF_INET; + sin.sin_port = htons((short)port); + sin.sin_addr.s_addr = addr->addr.v4.s_addr; + memcpy(sockAddr, &sin, sizeof(sin)); return 0; } if (addr->domain == PF_INET6) { - sockAddr6 = (struct sockaddr_in6 *)ARM_NOWARN_ALIGN(sockAddr); + struct sockaddr_in6 sin6; + memset(&sin6, 0, sizeof(sin6)); - sockAddr6->sin6_family = AF_INET6; - sockAddr6->sin6_port = htons((short)port); - memcpy(&sockAddr6->sin6_addr, &addr->addr.v6, sizeof(struct in6_addr)); + sin6.sin6_family = AF_INET6; + sin6.sin6_port = htons((short)port); + sin6.sin6_addr = addr->addr.v6; + memcpy(sockAddr, &sin6, sizeof(sin6)); return 0; } @@ -434,33 +435,30 @@ createSockAddr(struct sockaddr *sockAddr, const struct ipAddr *addr, int port) } static int -addrFromSockAddr(struct ipAddr *addr, const struct sockaddr *sockAddr) +addrFromSockAddr(struct ipAddr *addr, const union olsr_sockaddr *sockAddr) { - const struct sockaddr_in *sockAddr4 = (const struct sockaddr_in *)CONST_ARM_NOWARN_ALIGN(sockAddr); - const struct sockaddr_in6 *sockAddr6 = (const struct sockaddr_in6 *)CONST_ARM_NOWARN_ALIGN(sockAddr); - memset(addr, 0, sizeof(struct ipAddr)); - if (sockAddr4->sin_family == AF_INET) { + if (sockAddr->in.sa_family == AF_INET) { addr->domain = PF_INET; - addr->addr.v4.s_addr = sockAddr4->sin_addr.s_addr; + addr->addr.v4.s_addr = sockAddr->in4.sin_addr.s_addr; return 0; } - if (sockAddr6->sin6_family == AF_INET6) { + if (sockAddr->in.sa_family == AF_INET6) { addr->domain = PF_INET6; - memcpy(&addr->addr.v6, &sockAddr6->sin6_addr, sizeof(struct in6_addr)); + memcpy(&addr->addr.v6, &sockAddr->in6.sin6_addr, sizeof(struct in6_addr)); return 0; } - fprintf(stderr, "invalid address family: %d\n", sockAddr4->sin_family); + fprintf(stderr, "invalid address family: %d\n", sockAddr->in.sa_family); return -1; } int createMainSocket(const struct ipAddr *addr, int port) { - struct sockaddr sockAddr; + struct sockaddr_storage sockAddr; static int truePara = 1; int flags; @@ -496,7 +494,7 @@ createMainSocket(const struct ipAddr *addr, int port) return -1; } - if (bind(mainSocket, &sockAddr, sizeof(struct sockaddr)) < 0) { + if (bind(mainSocket, (struct sockaddr *)&sockAddr, sizeof(struct sockaddr)) < 0) { error("cannot bind main socket: %s\n", strerror(errno)); close(mainSocket); return -1; @@ -514,15 +512,15 @@ createMainSocket(const struct ipAddr *addr, int port) int acceptConn(struct fileId **sockId, struct ipAddr **addr) { - struct sockaddr sockAddr; + union olsr_sockaddr sockAddr; socklen_t len; int sock; int flags; do { - len = sizeof(struct sockaddr); + len = sizeof(struct sockaddr_storage); - sock = accept(mainSocket, &sockAddr, &len); + sock = accept(mainSocket, &sockAddr.in, &len); } while (sock < 0 && errno == EINTR); diff --git a/lib/txtinfo/src/olsrd_txtinfo.c b/lib/txtinfo/src/olsrd_txtinfo.c index 1ba47505..72ffeb78 100644 --- a/lib/txtinfo/src/olsrd_txtinfo.c +++ b/lib/txtinfo/src/olsrd_txtinfo.c @@ -163,9 +163,7 @@ olsr_plugin_exit(void) static int plugin_ipc_init(void) { - struct sockaddr_storage sst; - struct sockaddr_in *sock_in; - struct sockaddr_in6 *sin6; + union olsr_sockaddr sst; uint32_t yes = 1; socklen_t addrlen; @@ -193,27 +191,25 @@ plugin_ipc_init(void) /* complete the socket structure */ memset(&sst, 0, sizeof(sst)); if (olsr_cnf->ip_version == AF_INET) { - sock_in = (struct sockaddr_in *)&sst; - sock_in->sin_family = AF_INET; + sst.in4.sin_family = AF_INET; addrlen = sizeof(struct sockaddr_in); #ifdef SIN6_LEN - sock_in->sin_len = addrlen; + sst.in4.sin_len = addrlen; #endif - sock_in->sin_addr.s_addr = txtinfo_listen_ip.v4.s_addr; - sock_in->sin_port = htons(ipc_port); + sst.in4.sin_addr.s_addr = txtinfo_listen_ip.v4.s_addr; + sst.in4.sin_port = htons(ipc_port); } else { - sin6 = (struct sockaddr_in6 *)&sst; - sin6->sin6_family = AF_INET6; + sst.in6.sin6_family = AF_INET6; addrlen = sizeof(struct sockaddr_in6); #ifdef SIN6_LEN - sin6->sin6_len = addrlen; + sst.in6.sin6_len = addrlen; #endif - sin6->sin6_addr = txtinfo_listen_ip.v6; - sin6->sin6_port = htons(ipc_port); + sst.in6.sin6_addr = txtinfo_listen_ip.v6; + sst.in6.sin6_port = htons(ipc_port); } /* bind the socket to the port number */ - if (bind(ipc_socket, (struct sockaddr *)&sst, addrlen) == -1) { + if (bind(ipc_socket, &sst.in, addrlen) == -1) { #ifndef NODEBUG olsr_printf(1, "(TXTINFO) bind()=%s\n", strerror(errno)); #endif @@ -241,18 +237,17 @@ plugin_ipc_init(void) static void ipc_action(int fd, void *data __attribute__ ((unused)), unsigned int flags __attribute__ ((unused))) { - struct sockaddr_storage pin; - struct sockaddr_in *sin4; - struct sockaddr_in6 *sin6; + union olsr_sockaddr pin; + char addr[INET6_ADDRSTRLEN]; fd_set rfds; struct timeval tv; int send_what = 0; int ipc_connection; - socklen_t addrlen = sizeof(struct sockaddr_storage); + socklen_t addrlen = sizeof(pin); - if ((ipc_connection = accept(fd, (struct sockaddr *)&pin, &addrlen)) == -1) { + if ((ipc_connection = accept(fd, &pin.in, &addrlen)) == -1) { #ifndef NODEBUG olsr_printf(1, "(TXTINFO) accept()=%s\n", strerror(errno)); #endif @@ -261,10 +256,9 @@ ipc_action(int fd, void *data __attribute__ ((unused)), unsigned int flags __att tv.tv_sec = tv.tv_usec = 0; if (olsr_cnf->ip_version == AF_INET) { - sin4 = (struct sockaddr_in *)&pin; - if (inet_ntop(olsr_cnf->ip_version, &sin4->sin_addr, addr, INET6_ADDRSTRLEN) == NULL) + if (inet_ntop(olsr_cnf->ip_version, &pin.in4.sin_addr, addr, INET6_ADDRSTRLEN) == NULL) addr[0] = '\0'; - if (!ip4equal(&sin4->sin_addr, &txtinfo_accept_ip.v4) && txtinfo_accept_ip.v4.s_addr != INADDR_ANY) { + if (!ip4equal(&pin.in4.sin_addr, &txtinfo_accept_ip.v4) && txtinfo_accept_ip.v4.s_addr != INADDR_ANY) { #ifdef TXTINFO_ALLOW_LOCALHOST if (sin4->sin_addr.s_addr!=INADDR_LOOPBACK) { #endif @@ -276,11 +270,10 @@ ipc_action(int fd, void *data __attribute__ ((unused)), unsigned int flags __att #endif } } else { - sin6 = (struct sockaddr_in6 *)&pin; - if (inet_ntop(olsr_cnf->ip_version, &sin6->sin6_addr, addr, INET6_ADDRSTRLEN) == NULL) + if (inet_ntop(olsr_cnf->ip_version, &pin.in6.sin6_addr, addr, INET6_ADDRSTRLEN) == NULL) addr[0] = '\0'; /* Use in6addr_any (::) in olsr.conf to allow anybody. */ - if (!ip6equal(&in6addr_any, &txtinfo_accept_ip.v6) && !ip6equal(&sin6->sin6_addr, &txtinfo_accept_ip.v6)) { + if (!ip6equal(&in6addr_any, &txtinfo_accept_ip.v6) && !ip6equal(&pin.in6.sin6_addr, &txtinfo_accept_ip.v6)) { olsr_printf(1, "(TXTINFO) From host(%s) not allowed!\n", addr); close(ipc_connection); return; diff --git a/src/cfgparser/cfgfile_gen.c b/src/cfgparser/cfgfile_gen.c index fbb7fa16..e357b3e4 100644 --- a/src/cfgparser/cfgfile_gen.c +++ b/src/cfgparser/cfgfile_gen.c @@ -65,7 +65,9 @@ int olsrd_write_cnf(struct olsrd_config *cnf, const char *fname) { printf("Writing config to file \"%s\".... ", fname); abuf_init(&abuf, 1024); olsrd_write_cnf_autobuf(&abuf, cnf); - fwrite(abuf.buf, abuf.len, 1, fd); + if (fwrite(abuf.buf, abuf.len, 1, fd) < (size_t)abuf.len) { + fprintf(stderr, "Error, could not write the complete config file.\n"); + } abuf_free(&abuf); fclose(fd); diff --git a/src/cfgparser/oscan.lex b/src/cfgparser/oscan.lex index 543f5451..35abe425 100644 --- a/src/cfgparser/oscan.lex +++ b/src/cfgparser/oscan.lex @@ -55,6 +55,8 @@ #include "oparse.h" +#define ECHO if(fwrite( yytext, yyleng, 1, yyout )) {} + /* Prototypes */ int yyget_lineno(void); FILE * yyget_in(void); diff --git a/src/ipcalc.c b/src/ipcalc.c index 9f4cc71e..33a62d46 100644 --- a/src/ipcalc.c +++ b/src/ipcalc.c @@ -178,17 +178,30 @@ olsr_ip_prefix_to_string(const struct olsr_ip_prefix *prefix) int olsr_string_to_prefix(int ipversion, struct olsr_ip_prefix *dst, const char *string) { static char buf[MAX(INET6_ADDRSTRLEN + 1 + 3, INET_ADDRSTRLEN + 1 + INET_ADDRSTRLEN)]; - char *prefix; + char *ptr; strscpy(buf, string, sizeof(buf)); dst->prefix_len = ipversion == AF_INET ? 32 : 128; - prefix = strchr(buf, '/'); - if (prefix) { - *prefix++ = 0; - dst->prefix_len = atoi(prefix); + ptr = strchr(buf, '/'); + if (!ptr) { + ptr = strchr(buf, ' '); } + if (ptr) { + *ptr++ = 0; + if (olsr_cnf->ip_version == AF_INET && strchr(ptr, '.')) { + uint8_t subnetbuf[4]; + if (inet_pton(AF_INET, ptr, subnetbuf)) { + return 1; + } + + dst->prefix_len = netmask_to_prefix(subnetbuf, sizeof(subnetbuf)); + } + else { + dst->prefix_len = atoi(ptr); + } + } return inet_pton(ipversion, buf, &dst->prefix); } diff --git a/src/olsr_types.h b/src/olsr_types.h index 730978fd..e25a0441 100644 --- a/src/olsr_types.h +++ b/src/olsr_types.h @@ -101,6 +101,13 @@ typedef uint16_t olsr_cookie_t; #include #endif +union olsr_sockaddr { + struct sockaddr_storage storage; + struct sockaddr in; + struct sockaddr_in in4; + struct sockaddr_in6 in6; +}; + union olsr_ip_addr { struct in_addr v4; struct in6_addr v6; -- 2.20.1