X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Finet.c;h=17d58d5c2d19b719c1158466b0e03878588c9365;hb=091f5fa9229897a52424cd442b325f97d361dbc3;hp=a0f69713a5e03e05c8c9307244ce4fc6f9e67f16;hpb=ef636ec730a51d3468870546ab6844b270e5b79a;p=framework%2Fconnectivity%2Fconnman.git diff --git a/src/inet.c b/src/inet.c index a0f6971..17d58d5 100644 --- a/src/inet.c +++ b/src/inet.c @@ -44,6 +44,7 @@ #include #include #include +#include #include "connman.h" @@ -1991,27 +1992,37 @@ static int inet_rtnl_recv(GIOChannel *chan, gpointer user_data) struct inet_rtnl_cb_data *rtnl_data = user_data; struct __connman_inet_rtnl_handle *rth = rtnl_data->rtnl; struct nlmsghdr *h = NULL; + struct sockaddr_nl nladdr; + socklen_t addr_len = sizeof(nladdr); unsigned char buf[4096]; void *ptr = buf; gsize len; - int status; + int status, fd; memset(buf, 0, sizeof(buf)); + memset(&nladdr, 0, sizeof(nladdr)); - status = g_io_channel_read_chars(chan, (gchar *) buf, - sizeof(buf), &len, NULL); + fd = g_io_channel_unix_get_fd(chan); - DBG("status %d", status); + status = recvfrom(fd, buf, sizeof(buf), 0, + (struct sockaddr *) &nladdr, &addr_len); + if (status < 0) { + if (errno == EINTR || errno == EAGAIN) + return 0; - switch (status) { - case G_IO_STATUS_NORMAL: - break; - case G_IO_STATUS_AGAIN: - return 0; - default: return -1; } + if (status == 0) + return -1; + + if (nladdr.nl_pid != 0) { /* not sent by kernel, ignore */ + DBG("Received msg from %u, ignoring it", nladdr.nl_pid); + return 0; + } + + len = status; + while (len > 0) { struct nlmsgerr *err; @@ -2162,3 +2173,70 @@ int __connman_inet_rtnl_addattr32(struct nlmsghdr *n, size_t maxlen, int type, return 0; } + +int connman_inet_check_ipaddress(const char *host) +{ + struct addrinfo hints; + struct addrinfo *addr; + int result; + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_flags = AI_NUMERICHOST; + addr = NULL; + + result = getaddrinfo(host, NULL, &hints, &addr); + if (result == 0) + result = addr->ai_family; + else + result = -result; + freeaddrinfo(addr); + + return result; +} + +/* Check routine modified from ics-dhcp 4.2.3-P2 */ +connman_bool_t connman_inet_check_hostname(const char *ptr, size_t len) +{ + const char *p; + + /* + * Not empty or complete length not over 255 characters. + */ + if ((len == 0) || (len > 256)) + return FALSE; + + /* + * Consists of [[:alnum:]-]+ labels separated by [.] + * a [_] is against RFC but seems to be "widely used" + */ + for (p = ptr; (*p != 0) && (len-- > 0); p++) { + + if ((*p == '-') || (*p == '_')) { + /* + * Not allowed at begin or end of a label. + */ + if (((p - ptr) == 0) || (len == 0) || (p[1] == '.')) + return FALSE; + + } else if (*p == '.') { + /* + * Each label has to be 1-63 characters; + * we allow [.] at the end ('foo.bar.') + */ + size_t d = p - ptr; + + if ((d <= 0) || (d >= 64)) + return FALSE; + + ptr = p + 1; /* Jump to the next label */ + + } else if (isalnum((unsigned char)*p) == 0) { + /* + * Also numbers at the begin are fine + */ + return FALSE; + } + } + + return TRUE; +}