1/* -*- Mode: C; tab-width: 4 -*- 2 * 3 * Copyright (c) 2012 Apple Inc. All rights reserved. 4 * 5 * dnsctl.c 6 * Command-line tool using libdns_services.dylib 7 * 8 * To build only this tool, copy and paste the following on the command line: 9 * On Apple 64bit Platforms ONLY OSX/iOS: 10 * clang -Wall dnsctl.c /usr/lib/libdns_services.dylib -o dnsctl 11 * 12 */ 13 14#include <stdio.h> 15#include <stdlib.h> 16#include <string.h> 17#include <sys/time.h> 18#include <net/if.h> // if_nametoindex() 19 20#include <dispatch/dispatch.h> 21#include "dns_services_mdns.h" 22 23//************************************************************************************************************* 24// Globals: 25//************************************************************************************************************* 26 27static const char kFilePathSep = '/'; 28static DNSXConnRef ClientRef = NULL; 29 30//************************************************************************************************************* 31// Utility Funcs: 32//************************************************************************************************************* 33 34static void printtimestamp(void) 35{ 36 struct tm tm; 37 int ms; 38 static char date[16]; 39 static char new_date[16]; 40 struct timeval tv; 41 gettimeofday(&tv, NULL); 42 localtime_r((time_t*)&tv.tv_sec, &tm); 43 ms = tv.tv_usec/1000; 44 strftime(new_date, sizeof(new_date), "%a %d %b %Y", &tm); 45 //display date only if it has changed 46 if (strncmp(date, new_date, sizeof(new_date))) 47 { 48 printf("DATE: ---%s---\n", new_date); 49 strncpy(date, new_date, sizeof(date)); 50 } 51 printf("%2d:%02d:%02d.%03d ", tm.tm_hour, tm.tm_min, tm.tm_sec, ms); 52} 53 54static void print_usage(const char *arg0) 55{ 56 fprintf(stderr, "%s USAGE: \n", arg0); 57 fprintf(stderr, "%s -DP Enable DNS Proxy with Default Parameters \n", arg0); 58 fprintf(stderr, "%s -DP [-o <output interface>] [-i <input interface(s)>] Enable DNS Proxy \n", arg0); 59} 60 61//************************************************************************************************************* 62// CallBack Funcs: 63//************************************************************************************************************* 64 65// DNSXEnableProxy Callback from the Daemon 66static void dnsproxy_reply(DNSXConnRef connRef, DNSXErrorType errCode) 67{ 68 (void) connRef; 69 printtimestamp(); 70 switch (errCode) 71 { 72 case kDNSX_NoError : printf(" SUCCESS \n"); break; 73 case kDNSX_DictError : printf(" DICT ERROR \n"); break; 74 case kDNSX_DaemonNotRunning : printf(" NO DAEMON \n"); 75 DNSXRefDeAlloc(ClientRef); break; 76 case kDNSX_Engaged : printf(" ENGAGED \n"); 77 DNSXRefDeAlloc(ClientRef); break; 78 case kDNSX_UnknownErr : 79 default : printf("UNKNOWN ERR \n"); 80 DNSXRefDeAlloc(ClientRef); break; 81 } 82 fflush(NULL); 83 84} 85 86//************************************************************************************************************* 87 88int main(int argc, char **argv) 89{ 90 DNSXErrorType err; 91 92 // Default i/p intf is lo0 and o/p intf is primary interface 93 IfIndex Ipintfs[MaxInputIf] = {1, 0, 0, 0, 0}; 94 IfIndex Opintf = kDNSIfindexAny; 95 96 // Extract program name from argv[0], which by convention contains the path to this executable 97 const char *a0 = strrchr(argv[0], kFilePathSep) + 1; 98 if (a0 == (const char *)1) 99 a0 = argv[0]; 100 101 // Must run as root 102 if (0 != geteuid()) 103 { 104 fprintf(stderr, "%s MUST run as root!!\n", a0); 105 exit(-1); 106 } 107 if ((sizeof(argv) == 8)) 108 printf("dnsctl running in 64-bit mode\n"); 109 else if ((sizeof(argv) == 4)) 110 printf("dnsctl running in 32-bit mode\n"); 111 112 // expects atleast one argument 113 if (argc < 2) 114 goto Usage; 115 116 if ( !strcmp(argv[1], "-DP") || !strcmp(argv[1], "-dp") ) 117 { 118 if (argc == 2) 119 { 120 printtimestamp(); 121 printf("Proceeding to Enable DNSProxy on mDNSResponder with Default Parameters\n"); 122 dispatch_queue_t my_Q = dispatch_queue_create("com.apple.dnsctl.callback_queue", NULL); 123 err = DNSXEnableProxy(&ClientRef, kDNSProxyEnable, Ipintfs, Opintf, my_Q, dnsproxy_reply); 124 } 125 else if (argc > 2) 126 { 127 argc--; 128 argv++; 129 if (!strcmp(argv[1], "-o")) 130 { 131 Opintf = if_nametoindex(argv[2]); 132 if (!Opintf) 133 Opintf = atoi(argv[2]); 134 if (!Opintf) 135 { 136 fprintf(stderr, "Could not parse o/p interface [%s]: Passing default primary \n", argv[2]); 137 Opintf = kDNSIfindexAny; 138 } 139 argc -= 2; 140 argv += 2; 141 } 142 if (argc > 2 && !strcmp(argv[1], "-i")) 143 { 144 int i; 145 argc--; 146 argv++; 147 for (i = 0; i < MaxInputIf && argc > 1; i++) 148 { 149 Ipintfs[i] = if_nametoindex(argv[1]); 150 if (!Ipintfs[i]) 151 Ipintfs[i] = atoi(argv[1]); 152 if (!Ipintfs[i]) 153 { 154 fprintf(stderr, "Could not parse i/p interface [%s]: Passing default lo0 \n", argv[2]); 155 Ipintfs[i] = 1; 156 } 157 argc--; 158 argv++; 159 } 160 } 161 printtimestamp(); 162 printf("Proceeding to Enable DNSProxy on mDNSResponder \n"); 163 dispatch_queue_t my_Q = dispatch_queue_create("com.apple.dnsctl.callback_queue", NULL); 164 err = DNSXEnableProxy(&ClientRef, kDNSProxyEnable, Ipintfs, Opintf, my_Q, dnsproxy_reply); 165 } 166 } 167 else 168 { 169 goto Usage; 170 } 171 172 dispatch_main(); 173 174Usage: 175 print_usage(a0); 176 return 0; 177} 178 179