blob: 14751d65d84af74399b57b0555120839b053311e [file] [log] [blame]
Alexander Afanasyev7b9347b2014-02-28 08:37:56 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (C) 2014 Named Data Networking Project
4 * See COPYING for copyright and distribution information.
5 */
6
7#include "face-uri.hpp"
8#include "core/logger.hpp"
Junxiao Shie38b1c42014-04-01 23:45:36 -07009#ifdef HAVE_PCAP
10#include "face/ethernet.hpp"
11#endif // HAVE_PCAP
12
Alexander Afanasyev7b9347b2014-02-28 08:37:56 -080013#include <boost/regex.hpp>
14
15NFD_LOG_INIT("FaceUri");
16
17namespace nfd {
18
19FaceUri::FaceUri(const std::string& uri)
20{
Junxiao Shi61e3cc52014-03-03 20:40:28 -070021 if (!parse(uri)) {
22 throw Error("Malformed URI: " + uri);
23 }
24}
25
26FaceUri::FaceUri(const char* uri)
27{
28 if (!parse(uri)) {
29 throw Error("Malformed URI: " + std::string(uri));
30 }
Alexander Afanasyev7b9347b2014-02-28 08:37:56 -080031}
32
33bool
34FaceUri::parse(const std::string& uri)
35{
36 m_scheme.clear();
Junxiao Shi61e3cc52014-03-03 20:40:28 -070037 m_host.clear();
38 m_isV6 = false;
Alexander Afanasyev7b9347b2014-02-28 08:37:56 -080039 m_port.clear();
Junxiao Shi61e3cc52014-03-03 20:40:28 -070040 m_path.clear();
41
Junxiao Shie38b1c42014-04-01 23:45:36 -070042 static const boost::regex protocolExp("(\\w+\\d?)://([^/]*)(\\/[^?]*)?");
Alexander Afanasyev7b9347b2014-02-28 08:37:56 -080043 boost::smatch protocolMatch;
Junxiao Shi61e3cc52014-03-03 20:40:28 -070044 if (!boost::regex_match(uri, protocolMatch, protocolExp)) {
45 return false;
46 }
Alexander Afanasyev7b9347b2014-02-28 08:37:56 -080047 m_scheme = protocolMatch[1];
Junxiao Shie38b1c42014-04-01 23:45:36 -070048 const std::string& authority = protocolMatch[2];
Junxiao Shi61e3cc52014-03-03 20:40:28 -070049 m_path = protocolMatch[3];
Alexander Afanasyev7b9347b2014-02-28 08:37:56 -080050
Junxiao Shie38b1c42014-04-01 23:45:36 -070051 // pattern for IPv6 address enclosed in [ ], with optional port number
52 static const boost::regex v6Exp("^\\[([a-fA-F0-9:]+)\\](?:\\:(\\d+))?$");
53 // pattern for Ethernet address in standard hex-digits-and-colons notation
54 static const boost::regex etherExp("^((?:[a-fA-F0-9]{1,2}\\:){5}(?:[a-fA-F0-9]{1,2}))$");
55 // pattern for IPv4/hostname/fd/ifname, with optional port number
56 static const boost::regex v4HostExp("^([^:]+)(?:\\:(\\d+))?$");
Alexander Afanasyev7b9347b2014-02-28 08:37:56 -080057
Junxiao Shie38b1c42014-04-01 23:45:36 -070058 if (authority.empty()) {
59 // UNIX, internal
Junxiao Shi61e3cc52014-03-03 20:40:28 -070060 }
61 else {
Junxiao Shie38b1c42014-04-01 23:45:36 -070062 boost::smatch match;
63 m_isV6 = boost::regex_match(authority, match, v6Exp);
64 if (m_isV6 ||
65 boost::regex_match(authority, match, etherExp) ||
66 boost::regex_match(authority, match, v4HostExp)) {
67 m_host = match[1];
68 m_port = match[2];
69 }
70 else {
Alexander Afanasyev7b9347b2014-02-28 08:37:56 -080071 return false;
72 }
Junxiao Shi61e3cc52014-03-03 20:40:28 -070073 }
74
75 NFD_LOG_DEBUG("URI [" << uri << "] parsed into: " <<
76 m_scheme << ", " << m_host << ", " << m_port << ", " << m_path);
Alexander Afanasyev7b9347b2014-02-28 08:37:56 -080077 return true;
78}
79
Junxiao Shi61e3cc52014-03-03 20:40:28 -070080FaceUri::FaceUri(const boost::asio::ip::tcp::endpoint& endpoint)
81{
82 m_isV6 = endpoint.address().is_v6();
83 m_scheme = m_isV6 ? "tcp6" : "tcp4";
84 m_host = endpoint.address().to_string();
85 m_port = boost::lexical_cast<std::string>(endpoint.port());
86}
87
88FaceUri::FaceUri(const boost::asio::ip::udp::endpoint& endpoint)
89{
90 m_isV6 = endpoint.address().is_v6();
91 m_scheme = m_isV6 ? "udp6" : "udp4";
92 m_host = endpoint.address().to_string();
93 m_port = boost::lexical_cast<std::string>(endpoint.port());
94}
95
Junxiao Shie38b1c42014-04-01 23:45:36 -070096#ifdef HAVE_UNIX_SOCKETS
Junxiao Shi61e3cc52014-03-03 20:40:28 -070097FaceUri::FaceUri(const boost::asio::local::stream_protocol::endpoint& endpoint)
98 : m_isV6(false)
99{
100 m_scheme = "unix";
101 m_path = endpoint.path();
102}
Junxiao Shie38b1c42014-04-01 23:45:36 -0700103#endif // HAVE_UNIX_SOCKETS
104
105FaceUri
106FaceUri::fromFd(int fd)
107{
108 FaceUri uri;
109 uri.m_scheme = "fd";
110 uri.m_host = boost::lexical_cast<std::string>(fd);
111 return uri;
112}
113
114#ifdef HAVE_PCAP
115FaceUri::FaceUri(const ethernet::Address& address)
116 : m_isV6(false)
117{
118 m_scheme = "ether";
119 m_host = address.toString(':');
120}
121#endif // HAVE_PCAP
122
123FaceUri
124FaceUri::fromDev(const std::string& ifname)
125{
126 FaceUri uri;
127 uri.m_scheme = "dev";
128 uri.m_host = ifname;
129 return uri;
130}
Junxiao Shi61e3cc52014-03-03 20:40:28 -0700131
Alexander Afanasyev7b9347b2014-02-28 08:37:56 -0800132} // namespace nfd