diff options
author | Jiri Pirko <jiri@resnulli.us> | 2013-03-16 20:08:52 +0100 |
---|---|---|
committer | Jiri Pirko <jiri@resnulli.us> | 2013-03-17 11:11:48 +0100 |
commit | 650e30d185fd0b4ef5fcdebf6720e87a08ec90a3 (patch) | |
tree | 64283615084a55b7bd52540e7f7582b3436c826a /libndp | |
parent | 993764c3b2defdf053facbc29eadc0a4abeddb0d (diff) | |
download | libndp-650e30d185fd0b4ef5fcdebf6720e87a08ec90a3.tar.gz |
lib: add support for sending ND messages
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Diffstat (limited to 'libndp')
-rw-r--r-- | libndp/libndp.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/libndp/libndp.c b/libndp/libndp.c index 9272477..99ad3b5 100644 --- a/libndp/libndp.c +++ b/libndp/libndp.c @@ -180,6 +180,33 @@ static int myrecvfrom6(int sockfd, void *buf, size_t *buflen, int flags, return 0; } +static int mysendto6(int sockfd, void *buf, size_t buflen, int flags, + struct in6_addr *addr, uint32_t ifindex) +{ + struct sockaddr_in6 sin6; + ssize_t ret; + + memset(&sin6, 0, sizeof(sin6)); + memcpy(&sin6.sin6_addr, addr, sizeof(sin6.sin6_addr)); + sin6.sin6_scope_id = ifindex; +resend: + ret = sendto(sockfd, buf, buflen, flags, &sin6, sizeof(sin6)); + if (ret == -1) { + switch(errno) { + case EINTR: + goto resend; + case ENETDOWN: + case ENETUNREACH: + case EADDRNOTAVAIL: + case ENXIO: + return 0; + default: + return -errno; + } + } + return 0; +} + static const char *str_in6_addr(struct in6_addr *addr) { static char buf[INET6_ADDRSTRLEN]; @@ -216,6 +243,15 @@ static int ndp_sock_open(struct ndp *ndp) goto close_sock; } + val = 255; + ret = setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, + &val, sizeof(val)); + if (ret == -1) { + err(ndp, "Failed to setsockopt IPV6_MULTICAST_HOPS."); + err = -errno; + goto close_sock; + } + ndp->sock = sock; return 0; close_sock: @@ -998,6 +1034,22 @@ uint32_t ndp_msg_ifindex(struct ndp_msg *msg) return msg->ifindex; } +/** + * ndp_msg_send: + * @ndp: libndp library context + * @msg: message structure + * + * Send message. + * + * Returns: zero on success or negative number in case of an error. + **/ +NDP_EXPORT +int ndp_msg_send(struct ndp *ndp, struct ndp_msg *msg) +{ + return mysendto6(ndp->sock, msg->buf, msg->len, 0, + &msg->addrto, msg->ifindex); +} + static void ndp_process_ra_opt(struct ndp_msgra *msgra, unsigned char *opt_data, uint8_t opt_type, uint8_t opt_len) { |