Home | History | Annotate | Download | only in service_discovery_sniffer
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <vector>
      6 
      7 #include "base/at_exit.h"
      8 #include "base/bind.h"
      9 #include "base/memory/scoped_ptr.h"
     10 #include "base/message_loop/message_loop.h"
     11 #include "chrome/common/local_discovery/service_discovery_client_impl.h"
     12 #include "chrome/tools/service_discovery_sniffer/service_discovery_sniffer.h"
     13 #include "net/dns/mdns_client.h"
     14 
     15 namespace local_discovery {
     16 
     17 ServicePrinter::ServicePrinter(ServiceDiscoveryClient* client,
     18                                const std::string& service_name)
     19     : changed_(false) {
     20   service_resolver_ =
     21       client->CreateServiceResolver(
     22           service_name,
     23           base::Bind(&ServicePrinter::OnServiceResolved,
     24                      base::Unretained(this)));
     25 }
     26 
     27 ServicePrinter::~ServicePrinter() {
     28 }
     29 
     30 void ServicePrinter::Added() {
     31   changed_ = false;
     32   service_resolver_->StartResolving();
     33 }
     34 
     35 void ServicePrinter::Changed() {
     36   changed_ = true;
     37   service_resolver_->StartResolving();
     38 }
     39 
     40 void ServicePrinter::Removed() {
     41   printf("Service Removed: %s\n", service_resolver_->GetName().c_str());
     42 }
     43 
     44 void ServicePrinter::OnServiceResolved(ServiceResolver::RequestStatus status,
     45                                        const ServiceDescription& service) {
     46   if (changed_) {
     47     printf("Service Updated: %s\n", service.instance_name().c_str());
     48   } else {
     49     printf("Service Added: %s\n", service.instance_name().c_str());
     50   }
     51 
     52   printf("\tAddress: %s:%d\n", service.address.host().c_str(),
     53          service.address.port());
     54   printf("\tMetadata: \n");
     55   for (std::vector<std::string>::const_iterator i = service.metadata.begin();
     56        i != service.metadata.end(); i++) {
     57     printf("\t\t%s\n", i->c_str());
     58   }
     59 
     60   if (service.ip_address != net::IPAddressNumber()) {
     61     printf("\tIP Address: %s\n", net::IPAddressToString(
     62         service.ip_address).c_str());
     63   }
     64 }
     65 
     66 ServiceTypePrinter::ServiceTypePrinter(ServiceDiscoveryClient* client,
     67                                        const std::string& service_type)
     68     : client_(client)  {
     69   watcher_ = client_->CreateServiceWatcher(
     70       service_type, base::Bind(&ServiceTypePrinter::OnServiceUpdated,
     71                                base::Unretained(this)));
     72 }
     73 
     74 void ServiceTypePrinter::Start() {
     75   watcher_->Start();
     76   watcher_->DiscoverNewServices(false);
     77 }
     78 
     79 ServiceTypePrinter::~ServiceTypePrinter() {
     80 }
     81 
     82 void ServiceTypePrinter::OnServiceUpdated(ServiceWatcher::UpdateType update,
     83                                           const std::string& service_name) {
     84   if (update == ServiceWatcher::UPDATE_ADDED) {
     85     services_[service_name].reset(new ServicePrinter(client_, service_name));
     86     services_[service_name]->Added();
     87   } else if (update == ServiceWatcher::UPDATE_CHANGED) {
     88     services_[service_name]->Changed();
     89   } else if (update == ServiceWatcher::UPDATE_REMOVED) {
     90     services_[service_name]->Removed();
     91     services_.erase(service_name);
     92   }
     93 }
     94 
     95 }  // namespace local_discovery
     96 
     97 int main(int argc, char** argv) {
     98   base::AtExitManager at_exit_manager;
     99   base::MessageLoopForIO message_loop;
    100 
    101   if (argc != 2) {
    102     printf("Please provide exactly 1 argument.\n");
    103     return 1;
    104   }
    105 
    106   scoped_ptr<net::MDnsClient> mdns_client = net::MDnsClient::CreateDefault();
    107   scoped_ptr<net::MDnsSocketFactory> socket_factory =
    108       net::MDnsSocketFactory::CreateDefault();
    109   mdns_client->StartListening(socket_factory.get());
    110   scoped_ptr<local_discovery::ServiceDiscoveryClient> service_discovery_client;
    111   service_discovery_client.reset(
    112       new local_discovery::ServiceDiscoveryClientImpl(mdns_client.get()));
    113   {
    114     // To guarantee/make explicit the ordering constraint.
    115     local_discovery::ServiceTypePrinter print_changes(
    116         service_discovery_client.get(),
    117         std::string(argv[1]) + "._tcp.local");
    118 
    119     print_changes.Start();
    120     message_loop.Run();
    121   }
    122 }
    123