From c5b542e79cb05ddfce02c1c3222c88267b87f75b Mon Sep 17 00:00:00 2001 From: Daniel Adolfsson Date: Sun, 18 Sep 2011 01:31:27 +0200 Subject: [PATCH] Small changes * Make iface::read() return a bit more generic address (sockaddr). * Add is_unicast() and is_multicast() to address. * Set default config path to "/etc/ndppd.conf". * Silently ignore solicit messages with bad saddr and/or daddr. --- src/address.cc | 18 ++++++++++++++++++ src/address.h | 6 ++++++ src/conf.cc | 2 +- src/iface.cc | 24 ++++++++++++++---------- src/iface.h | 2 +- src/ndppd.cc | 3 +-- 6 files changed, 41 insertions(+), 14 deletions(-) diff --git a/src/address.cc b/src/address.cc index ac3859e..2ba100a 100644 --- a/src/address.cc +++ b/src/address.cc @@ -131,6 +131,14 @@ bool address::operator==(const address& addr) const ((_addr.s6_addr32[3] ^ addr._addr.s6_addr32[3]) & _mask.s6_addr32[3])); } +bool address::operator!=(const address& addr) const +{ + return !!(((_addr.s6_addr32[0] ^ addr._addr.s6_addr32[0]) & _mask.s6_addr32[0]) | + ((_addr.s6_addr32[1] ^ addr._addr.s6_addr32[1]) & _mask.s6_addr32[1]) | + ((_addr.s6_addr32[2] ^ addr._addr.s6_addr32[2]) & _mask.s6_addr32[2]) | + ((_addr.s6_addr32[3] ^ addr._addr.s6_addr32[3]) & _mask.s6_addr32[3])); +} + int address::prefix() const { if(!_mask.s6_addr[0]) @@ -274,4 +282,14 @@ struct in6_addr& address::mask() return _mask; } +bool address::is_multicast() const +{ + return _addr.s6_addr[0] == 0xff; +} + +bool address::is_unicast() const +{ + return _addr.s6_addr[0] != 0xff; +} + __NDPPD_NS_END diff --git a/src/address.h b/src/address.h index be1aa6a..4962a93 100644 --- a/src/address.h +++ b/src/address.h @@ -49,6 +49,8 @@ public: // Compare _a/_m against a._a. bool operator==(const address& addr) const; + bool operator!=(const address& addr) const; + const std::string to_string() const; bool parse_string(const std::string& str); @@ -57,6 +59,10 @@ public: void prefix(int n); + bool is_unicast() const; + + bool is_multicast() const; + operator std::string() const; }; diff --git a/src/conf.cc b/src/conf.cc index 3e25dcd..a062a69 100644 --- a/src/conf.cc +++ b/src/conf.cc @@ -83,7 +83,7 @@ bool conf::setup(::cfg_t *cfg) { ::cfg_t *rule_cfg; - if(!(rule_cfg = ::cfg_getnsec(proxy_cfg, "rule", i))) + if(!(rule_cfg = ::cfg_getnsec(proxy_cfg, "rule", i2))) continue; address addr(::cfg_title(rule_cfg)); diff --git a/src/iface.cc b/src/iface.cc index 6cb6f80..07baf9a 100644 --- a/src/iface.cc +++ b/src/iface.cc @@ -282,9 +282,8 @@ strong_ptr iface::open_ifd(const std::string& name) return ifa; } -ssize_t iface::read(int fd, address& saddr, uint8_t *msg, size_t size) +ssize_t iface::read(int fd, struct sockaddr *saddr, uint8_t *msg, size_t size) { - struct sockaddr_in6 saddr_tmp; struct msghdr mhdr; struct iovec iov; char cbuf[256]; @@ -297,8 +296,8 @@ ssize_t iface::read(int fd, address& saddr, uint8_t *msg, size_t size) iov.iov_base = (caddr_t)msg; memset(&mhdr, 0, sizeof(mhdr)); - mhdr.msg_name = (caddr_t)&saddr_tmp; - mhdr.msg_namelen = sizeof(saddr_tmp); + mhdr.msg_name = (caddr_t)saddr; + mhdr.msg_namelen = sizeof(struct sockaddr); mhdr.msg_iov = &iov; mhdr.msg_iovlen = 1; @@ -308,9 +307,7 @@ ssize_t iface::read(int fd, address& saddr, uint8_t *msg, size_t size) if(len < sizeof(struct icmp6_hdr)) return -1; - saddr = saddr_tmp.sin6_addr; - - DBG("iface::read() saddr=%s, len=%d", saddr.to_string().c_str(), len); + DBG("iface::read() len=%d", len); return len; } @@ -347,10 +344,11 @@ ssize_t iface::write(int fd, const address& daddr, const uint8_t *msg, size_t si ssize_t iface::read_solicit(address& saddr, address& daddr, address& taddr) { + struct sockaddr_ll t_saddr; uint8_t msg[256]; ssize_t len; - if((len = read(_pfd, saddr, msg, sizeof(msg))) < 0) + if((len = read(_pfd, (struct sockaddr *)&t_saddr, msg, sizeof(msg))) < 0) return -1; struct ip6_hdr *ip6h = @@ -367,7 +365,7 @@ ssize_t iface::read_solicit(address& saddr, address& daddr, address& taddr) saddr = ip6h->ip6_src; DBG("iface::read_solicit() saddr=%s, daddr=%s, taddr=%s, len=%d", - daddr.to_string().c_str(), saddr.to_string().c_str(), + saddr.to_string().c_str(), daddr.to_string().c_str(), taddr.to_string().c_str(), len); return len; @@ -442,12 +440,15 @@ ssize_t iface::write_advert(const address& daddr, const address& taddr) ssize_t iface::read_advert(address& saddr, address& taddr) { + struct sockaddr_in6 t_saddr; uint8_t msg[256]; ssize_t len; - if((len = read(_ifd, saddr, msg, sizeof(msg))) < 0) + if((len = read(_ifd, (struct sockaddr *)&t_saddr, msg, sizeof(msg))) < 0) return -1; + saddr = t_saddr.sin6_addr; + if(((struct icmp6_hdr *)msg)->icmp6_type != ND_NEIGHBOR_ADVERT) return -1; @@ -539,6 +540,9 @@ int iface::poll_all() continue; } + if(!saddr.is_unicast() || !daddr.is_multicast()) + continue; + ifa->_pr->handle_solicit(saddr, daddr, taddr); } else diff --git a/src/iface.h b/src/iface.h index 5e00b09..8fa7422 100644 --- a/src/iface.h +++ b/src/iface.h @@ -86,7 +86,7 @@ public: static int poll_all(); - static ssize_t read(int fd, address& saddr, uint8_t *msg, size_t size); + static ssize_t read(int fd, struct sockaddr *saddr, uint8_t *msg, size_t size); static ssize_t write(int fd, const address& daddr, const uint8_t *msg, size_t size); diff --git a/src/ndppd.cc b/src/ndppd.cc index 326d418..5d11e63 100644 --- a/src/ndppd.cc +++ b/src/ndppd.cc @@ -50,8 +50,7 @@ int daemonize() int main(int argc, char *argv[], char *env[]) { -// std::string config_path("/etc/ndppd.conf"); - std::string config_path("../ndppd.conf"); + std::string config_path("/etc/ndppd.conf"); bool daemon = false; while(1)