blob: 2969e20c4326ea0987b8ac08a03322e154de3bc6 [file] [log] [blame]
Alexander Afanasyev7b9347b2014-02-28 08:37:56 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -07003 * Copyright (c) 2014 Regents of the University of California,
4 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology
9 *
10 * This file is part of NFD (Named Data Networking Forwarding Daemon).
11 * See AUTHORS.md for complete list of NFD authors and contributors.
12 *
13 * NFD is free software: you can redistribute it and/or modify it under the terms
14 * of the GNU General Public License as published by the Free Software Foundation,
15 * either version 3 of the License, or (at your option) any later version.
16 *
17 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
18 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
19 * PURPOSE. See the GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along with
22 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
23 **/
Alexander Afanasyev7b9347b2014-02-28 08:37:56 -080024
25#include "face-uri.hpp"
26#include "core/logger.hpp"
Davide Pesavento1bdef282014-04-08 20:59:50 +020027
Alexander Afanasyev885a85b2014-04-12 21:01:13 -070028#ifdef HAVE_LIBPCAP
Alexander Afanasyev613e2a92014-04-15 13:36:58 -070029#include "ethernet.hpp"
Alexander Afanasyev885a85b2014-04-12 21:01:13 -070030#endif // HAVE_LIBPCAP
Junxiao Shie38b1c42014-04-01 23:45:36 -070031
Alexander Afanasyev7b9347b2014-02-28 08:37:56 -080032#include <boost/regex.hpp>
33
34NFD_LOG_INIT("FaceUri");
35
36namespace nfd {
37
38FaceUri::FaceUri(const std::string& uri)
39{
Junxiao Shi61e3cc52014-03-03 20:40:28 -070040 if (!parse(uri)) {
41 throw Error("Malformed URI: " + uri);
42 }
43}
44
45FaceUri::FaceUri(const char* uri)
46{
47 if (!parse(uri)) {
48 throw Error("Malformed URI: " + std::string(uri));
49 }
Alexander Afanasyev7b9347b2014-02-28 08:37:56 -080050}
51
52bool
53FaceUri::parse(const std::string& uri)
54{
55 m_scheme.clear();
Junxiao Shi61e3cc52014-03-03 20:40:28 -070056 m_host.clear();
57 m_isV6 = false;
Alexander Afanasyev7b9347b2014-02-28 08:37:56 -080058 m_port.clear();
Junxiao Shi61e3cc52014-03-03 20:40:28 -070059 m_path.clear();
60
Junxiao Shie38b1c42014-04-01 23:45:36 -070061 static const boost::regex protocolExp("(\\w+\\d?)://([^/]*)(\\/[^?]*)?");
Alexander Afanasyev7b9347b2014-02-28 08:37:56 -080062 boost::smatch protocolMatch;
Junxiao Shi61e3cc52014-03-03 20:40:28 -070063 if (!boost::regex_match(uri, protocolMatch, protocolExp)) {
64 return false;
65 }
Alexander Afanasyev7b9347b2014-02-28 08:37:56 -080066 m_scheme = protocolMatch[1];
Junxiao Shie38b1c42014-04-01 23:45:36 -070067 const std::string& authority = protocolMatch[2];
Junxiao Shi61e3cc52014-03-03 20:40:28 -070068 m_path = protocolMatch[3];
Alexander Afanasyev7b9347b2014-02-28 08:37:56 -080069
Junxiao Shie38b1c42014-04-01 23:45:36 -070070 // pattern for IPv6 address enclosed in [ ], with optional port number
71 static const boost::regex v6Exp("^\\[([a-fA-F0-9:]+)\\](?:\\:(\\d+))?$");
72 // pattern for Ethernet address in standard hex-digits-and-colons notation
Chengyu Fan514ed5e2014-04-17 13:07:30 -060073 static const boost::regex etherExp("^\\[((?:[a-fA-F0-9]{1,2}\\:){5}(?:[a-fA-F0-9]{1,2}))\\]$");
Junxiao Shie38b1c42014-04-01 23:45:36 -070074 // pattern for IPv4/hostname/fd/ifname, with optional port number
75 static const boost::regex v4HostExp("^([^:]+)(?:\\:(\\d+))?$");
Alexander Afanasyev7b9347b2014-02-28 08:37:56 -080076
Junxiao Shie38b1c42014-04-01 23:45:36 -070077 if (authority.empty()) {
78 // UNIX, internal
Junxiao Shi61e3cc52014-03-03 20:40:28 -070079 }
80 else {
Junxiao Shie38b1c42014-04-01 23:45:36 -070081 boost::smatch match;
82 m_isV6 = boost::regex_match(authority, match, v6Exp);
83 if (m_isV6 ||
84 boost::regex_match(authority, match, etherExp) ||
85 boost::regex_match(authority, match, v4HostExp)) {
86 m_host = match[1];
87 m_port = match[2];
88 }
89 else {
Alexander Afanasyev7b9347b2014-02-28 08:37:56 -080090 return false;
91 }
Junxiao Shi61e3cc52014-03-03 20:40:28 -070092 }
93
94 NFD_LOG_DEBUG("URI [" << uri << "] parsed into: " <<
95 m_scheme << ", " << m_host << ", " << m_port << ", " << m_path);
Alexander Afanasyev7b9347b2014-02-28 08:37:56 -080096 return true;
97}
98
Junxiao Shi61e3cc52014-03-03 20:40:28 -070099FaceUri::FaceUri(const boost::asio::ip::tcp::endpoint& endpoint)
100{
101 m_isV6 = endpoint.address().is_v6();
102 m_scheme = m_isV6 ? "tcp6" : "tcp4";
103 m_host = endpoint.address().to_string();
104 m_port = boost::lexical_cast<std::string>(endpoint.port());
105}
106
107FaceUri::FaceUri(const boost::asio::ip::udp::endpoint& endpoint)
108{
109 m_isV6 = endpoint.address().is_v6();
110 m_scheme = m_isV6 ? "udp6" : "udp4";
111 m_host = endpoint.address().to_string();
112 m_port = boost::lexical_cast<std::string>(endpoint.port());
113}
114
Wentao Shang53df1632014-04-21 12:01:32 -0700115FaceUri::FaceUri(const boost::asio::ip::tcp::endpoint& endpoint, const std::string& scheme)
116 : m_scheme(scheme)
117{
118 m_isV6 = endpoint.address().is_v6();
119 m_host = endpoint.address().to_string();
120 m_port = boost::lexical_cast<std::string>(endpoint.port());
121}
122
Junxiao Shie38b1c42014-04-01 23:45:36 -0700123#ifdef HAVE_UNIX_SOCKETS
Junxiao Shi61e3cc52014-03-03 20:40:28 -0700124FaceUri::FaceUri(const boost::asio::local::stream_protocol::endpoint& endpoint)
125 : m_isV6(false)
126{
127 m_scheme = "unix";
128 m_path = endpoint.path();
129}
Junxiao Shie38b1c42014-04-01 23:45:36 -0700130#endif // HAVE_UNIX_SOCKETS
131
132FaceUri
133FaceUri::fromFd(int fd)
134{
135 FaceUri uri;
136 uri.m_scheme = "fd";
137 uri.m_host = boost::lexical_cast<std::string>(fd);
138 return uri;
139}
140
Alexander Afanasyev885a85b2014-04-12 21:01:13 -0700141#ifdef HAVE_LIBPCAP
Junxiao Shie38b1c42014-04-01 23:45:36 -0700142FaceUri::FaceUri(const ethernet::Address& address)
Chengyu Fan514ed5e2014-04-17 13:07:30 -0600143 : m_isV6(true)
Junxiao Shie38b1c42014-04-01 23:45:36 -0700144{
145 m_scheme = "ether";
Davide Pesaventoedae3532014-04-09 03:07:11 +0200146 m_host = address.toString();
Junxiao Shie38b1c42014-04-01 23:45:36 -0700147}
Alexander Afanasyev885a85b2014-04-12 21:01:13 -0700148#endif // HAVE_LIBPCAP
Junxiao Shie38b1c42014-04-01 23:45:36 -0700149
150FaceUri
151FaceUri::fromDev(const std::string& ifname)
152{
153 FaceUri uri;
154 uri.m_scheme = "dev";
155 uri.m_host = ifname;
156 return uri;
157}
Junxiao Shi61e3cc52014-03-03 20:40:28 -0700158
Alexander Afanasyev7b9347b2014-02-28 08:37:56 -0800159} // namespace nfd