how can i get programmaticaly in Objective-C the name of local domain Knowing the ip adress? - ios

Hi have many iPad in 2 differents local networks and I want to know programatically in Objective-C the local domain based in the IP address in each iPad.
for example I have an iPad in local domain "project.local". In this domain we have many IP address as 192.168.12.50. The IOS device get automaticaly their ip address.
Now I want to get programmaticaly in objective-C the domain name "projet.local" knowing the ip address??

Try this (similar to dreamlax's answer https://stackoverflow.com/a/3575383/1758762):
struct addrinfo *results = NULL;
char hostname[NI_MAXHOST] = {0};
if ( getaddrinfo("192.168.12.50", NULL, NULL, &results) != 0 )
return;
for (struct addrinfo *r = results; r; r = r->ai_next)
{
if (getnameinfo(r->ai_addr, r->ai_addrlen, hostname, sizeof hostname, NULL, 0 , 0) != 0)
continue; // try next one
else
{
NSLog (#"Found hostname: %s", hostname);
break;
}
}
freeaddrinfo(results);

Related

How to select which network interface to use in a ESP32

I'm currently using a Esp32 which presents, in addition to wifi, an ethernet interface.
I'm using the esp-idf v3.3 with FreeRTOS.
To use it I included the "esp_eth.h" library (https://docs.espressif.com/projects/esp-idf/en/release-v3.1/api-reference/ethernet/esp_eth.html#api-reference-phy-lan8720).
I'd like to use both Wifi and ethernet interfaces basing on what I want to do but selecting which one to use, is there a way?
The practical use is to receive a command through the ethernet interface (for example a site to ping), ping the server through the wifi interface and answer back to the ethernet interface the ping result.
How can I select which interface to use (i dont want that the ping is made through the ethernet or that the response go through the wifi).
#edit: i found the method netif_set_default(struct netif * netif), but i dont know if it is the best way to select the interface to use for the specific action(i should swap from one interface to another)
Just get the IP of the Ethernet interface, then bind a socket to that IP address.
struct in_addr iaddr = {0};
#if USE_ANY_IF
// Bind the socket to any address
iaddr.s_addr = htonl(INADDR_ANY);
#else
// bind only to the Ethernet interface
tcpip_adapter_ip_info_t ip_info = {0};
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip_info);
inet_addr_from_ip4addr(&iaddr, &ip_info.ip);
#endif
Then use it to bind a socket, for example:
static int create_multicast_ipv4_socket(struct in_addr bind_iaddr)
{
struct sockaddr_in saddr = {0};
int sock = -1;
int err = 0;
char addrbuf[32] = {0};
sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
if (sock < 0)
{
ESP_LOGE(V4TAG, "Failed to create socket. Error %d", errno);
return -1;
}
saddr.sin_addr.s_addr = bind_iaddr.s_addr; // what interface IP to bind to. Can be htonl(INADDR_ANY)
saddr.sin_family = PF_INET;
saddr.sin_port = htons(UDP_PORT);
inet_ntoa_r(saddr.sin_addr.s_addr, addrbuf, sizeof(addrbuf) - 1);
ESP_LOGI(TAG, "Binding to interface %s...", addrbuf);
err = bind(sock, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in));
if (err < 0)
{
ESP_LOGE(V4TAG, "Failed to bind socket. Error %d", errno);
goto err;
}
// Assign multicast TTL (set separately from normal interface TTL)
uint8_t ttl = MULTICAST_TTL;
setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(uint8_t));
if (err < 0)
{
ESP_LOGE(V4TAG, "Failed to set IP_MULTICAST_TTL. Error %d", errno);
goto err;
}
// All set, socket is configured for sending
return sock;
err:
close(sock);
return -1;
}

Resolve NetBIOS name on iOS

Is there any way on iOS to resolve NetBIOS name using IP address?
One could resolve NetBIOS name on a Mac using terminal command:
smbutil -v status -ae
The smbutil is opensourced so you can find it here:
http://www.apple.com/opensource/ -> http://opensource.apple.com//source/smb/
And the same on GitHub:
https://github.com/unofficial-opensource-apple/smb
But the util extensively uses private and Mac OS-specific frameworks so Xcode couldn't even compile the source for iOS.
I think you just need to do a reverse DNS lookup, gethostbyaddr, because it looks like DNS, gethostbyname, is the only thing being used to go from NetBios name to IP.
Looking at the source from Apple, the smbutil application in the 'status' mode first calls 'nb_resolvehost' which just uses 'gethostbyname' to get the IP address from NetBios name. 'gethostbyname' uses DNS under the hood:
nb_resolvehost_in(const char *name, struct sockaddr **dest)
{
struct hostent* h;
struct sockaddr_in *sinp;
int len;
h = gethostbyname(name);
if (!h) {
warnx("can't get server address `%s': ", name);
herror(NULL);
return ENETDOWN;
}
if (h->h_addrtype != AF_INET) {
warnx("address for `%s' is not in the AF_INET family", name);
return EAFNOSUPPORT;
}
if (h->h_length != 4) {
warnx("address for `%s' has invalid length", name);
return EAFNOSUPPORT;
}
len = sizeof(struct sockaddr_in);
sinp = malloc(len);
if (sinp == NULL)
return ENOMEM;
bzero(sinp, len);
sinp->sin_len = len;
sinp->sin_family = h->h_addrtype;
memcpy(&sinp->sin_addr.s_addr, h->h_addr, 4);
sinp->sin_port = htons(SMB_TCP_PORT);
*dest = (struct sockaddr*)sinp;
return 0;
}
After this call the 'smbutil status' then sends some sort of SMB query using the function 'nbns_getnodestatus' to the previously given IP address on the SMB port. From this query the command gets Workgroup and Servername (not sure which server this is referring to).

RTSP stream to URL on iOS

I'm trying to create a streamer in my app over RTSP protocol to use it for Facebook live. I got this Project and it seems to work perfect except one thing which is the URL. The library get the device IP via this code :
+ (NSString*) getIPAddress
{
NSString* address;
struct ifaddrs *interfaces = nil;
// get all our interfaces and find the one that corresponds to wifi
if (!getifaddrs(&interfaces))
{
for (struct ifaddrs* addr = interfaces; addr != NULL; addr = addr->ifa_next)
{
if (([[NSString stringWithUTF8String:addr->ifa_name] isEqualToString:#"en0"]) &&
(addr->ifa_addr->sa_family == AF_INET))
{
struct sockaddr_in* sa = (struct sockaddr_in*) addr->ifa_addr;
address = [NSString stringWithUTF8String:inet_ntoa(sa->sin_addr)];
break;
}
}
}
freeifaddrs(interfaces);
return address;
}
So the stream can be accessed via the IP. My question is: is there anyway to make the RTSP to stream to a URL so I can provide it to the server?

iOS - Get device's DNS server address on IPv6 only network

I am trying to get device's DNS server address while connected to IPv6 only network on iOS. The following code works well for when connected to IPv4 network but doesn't work on IPv6 network. Code taken from this answer.
res_ninit(&_res);
res_state res = &_res;
for (int i=0; i < res->nscount; i++) {
sa_family_t family = res->nsaddr_list[i].sin_family;
if (family == AF_INET) {
NSLog(#"IPv4");
char str[INET_ADDRSTRLEN]; // String representation of address
inet_ntop(AF_INET, & (res->nsaddr_list[i].sin_addr.s_addr), str, INET_ADDRSTRLEN);
} else if (family == AF_INET6) {
NSLog(#"IPv6");
char address[INET6_ADDRSTRLEN]; // String representation of address
inet_ntop(AF_INET6, &(res->nsaddr_list [i].sin_addr.s_addr), address, INET6_ADDRSTRLEN);
} else {
NSLog(#"Unspecified");
}
}
On IPv6 network, sin_family is always AF_UNSPEC. Any suggestions/alternatives?
Try using res._u._ext.nsaddrs for IPv6.
See https://chromium.googlesource.com/chromium/src/+/master/net/dns/dns_config_service_posix.cc#437

how to resolve the hostname of a device in my LAN from its ip address on this LAN?

I have to resolve the hostname of a device in my LAN from its ip address on this LAN.
I have some code that works for external ip address but not the internally connected devices .
Below i have attached the code .
if you have any idea to get hostname of remote machine from it's IP in iOS/OSX, it'll make my day.
int error;
struct addrinfo *results = NULL;
error = getaddrinfo("173.194.34.24", NULL, NULL, &results);
if (error != 0)
{
NSLog (#"Could not get any info for the address");
}
for (struct addrinfo *r = results; r; r = r->ai_next)
{
char hostname[NI_MAXHOST] = {0};
error = getnameinfo(r->ai_addr, r->ai_addrlen, hostname, sizeof hostname, NULL, 0 , 0);
if (error != 0)
{
continue; // try next one
}
else
{
NSLog (#"Found hostname: %s", hostname);
break;
}
}
freeaddrinfo(results);
or with NSHost
NSLog(#"%# \n%#",[NSHost currentHost],[[NSHost hostWithAddress:#"172.17.241.61"] names]);
Only way to make a DNS lookup directly to a specific DNS is to implement the protocol yourself or use some library.
https://serverfault.com/questions/173187/what-does-a-dns-request-look-like
https://www.ietf.org/rfc/rfc1035.txt
https://github.com/adeboer/rfc1035lib

Resources