objective-C: Как получить адрес маршрутизатора?

Я попытался получить адрес маршрутизатора таким образом.

- (NSString *) routerIp { NSString *address = @"error"; struct ifaddrs *interfaces = NULL; struct ifaddrs *temp_addr = NULL; int success = 0; // retrieve the current interfaces - returns 0 on success success = getifaddrs(&interfaces); if (success == 0) { // Loop through linked list of interfaces temp_addr = interfaces; while(temp_addr != NULL) { if(temp_addr->ifa_addr->sa_family == AF_INET) { // Check if interface is en0 which is the wifi connection on the iPhone if([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"]) { // Get NSString from C String //ifa_addr address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_dstaddr)->sin_addr)]; } } temp_addr = temp_addr->ifa_next; } } // Free memory freeifaddrs(interfaces); return address; } 

Адрес маршрутизатора всегда выглядит как xxx.xxx.255.255, но он должен выглядеть как xxx.xxx.0.1 или что-то в этом роде …

Что делать, чтобы получить действительный адрес?

Спасибо за вашу помощь!

Я искал способ получить IP-адрес шлюза по умолчанию. Я собираюсь сосредоточиться именно на этом – мне не нужно было получать MAC-адрес маршрутизатора по умолчанию, так что это лишь частично отвечает на вопрос OP.

Мне не понравилась идея анализа вывода netstat. Кроме того, вы не можете получить маршрут по умолчанию на основе IP-адреса, который имеет интерфейс на вашем компьютере. Любой IP-адрес в том же диапазоне, что и ваш, может быть шлюзом по умолчанию – единственное правило заключается в том, что ваш IP-адрес и шлюз по умолчанию должны быть частью одной и той же подсети.

Еще одна вещь, которую я хотел обеспечить, – это получить IP-адрес шлюза по умолчанию, даже если для одного из моих локальных интерфейсов назначен назначенный ему IP-адрес (например, я подключен к Wi-Fi и к проводному Ethernet в том же время и оба интерфейса вверх, с IP-адресом на них). Для моего приложения не имеет значения, с каким интерфейсом устанавливается маршрут по умолчанию (он может быть en0, en1, ppp0 или вообще что-либо еще).

Я думаю, что лучший (и самый похожий на Apple) способ получить эту информацию – использовать System Configuration Framework – ссылки в столбце выше в этом streamе указывали мне в этом направлении, но на самом деле не дали подробностей о том, как используйте его, и я не нашел документацию Apple на нем очень полезной (по крайней мере, учитывая мой уровень квалификации).

Пожалуйста, помните, что я не очень опытен в Objective-C. Я нахожусь в середине написания приложения, которое мне нужно (и которое я не мог найти), и для этого приложения мне просто нужен IP-адрес по умолчанию шлюз.

Итак, вот что я делаю в своем приложении, и, похоже, он работает нормально (плюс намного короче и проще, чем большинство других решений, которые я нашел до сих пор:

 - (NSString *)defaultRouter { SCDynamicStoreRef ds = SCDynamicStoreCreate(kCFAllocatorDefault, CFSTR("myapp"), NULL, NULL); CFDictionaryRef dr = SCDynamicStoreCopyValue(ds, CFSTR("State:/Network/Global/IPv4")); CFStringRef router = CFDictionaryGetValue(dr, CFSTR("Router")); NSString *routerString = [NSString stringWithString:(__bridge NSString *)router]; CFRelease(dr); CFRelease(ds); return routerString; } - - (NSString *)defaultRouter { SCDynamicStoreRef ds = SCDynamicStoreCreate(kCFAllocatorDefault, CFSTR("myapp"), NULL, NULL); CFDictionaryRef dr = SCDynamicStoreCopyValue(ds, CFSTR("State:/Network/Global/IPv4")); CFStringRef router = CFDictionaryGetValue(dr, CFSTR("Router")); NSString *routerString = [NSString stringWithString:(__bridge NSString *)router]; CFRelease(dr); CFRelease(ds); return routerString; } 

Обратите внимание, что в моем приложении вышеупомянутое является частью более крупного метода (у меня на самом деле нет метода defaultRouter:). Кроме того, я пропустил некоторые проверки (например, [длина маршрутизатора] и т. Д.) Для краткости.

Надеюсь, кто-то найдет это полезным. Пожалуйста, также не стесняйтесь исправить ошибки, которые я мог бы иметь в коде выше – я все еще новичок!

PS. Я получил представление о том, что искать, когда я проверил вывод «scutil», в котором используется сама система конфигурации системы:

 MacBook:~$ scutil > show State:/Network/Global/IPv4  { PrimaryInterface : en1 PrimaryService :  Router :  } > show State:/Network/Global/IPv6  { PrimaryInterface : en1 PrimaryService :  Router :  } 

Вот код, который я написал, чтобы найти маршруты для машины. Я скопировал системные вызовы из кода для netstat . Обратите внимание, что я настоятельно рекомендовал это делать, поскольку эти системные вызовы не поддерживаются API и могут меняться в любое время. Они рекомендовали мне просто анализировать вывод netstat .

CustomRoute.c:

 #import "CustomRoute.h" @implementation CustomRoute + (NSMutableArray*) getRoutes { NSMutableArray* routeArray = [NSMutableArray array]; CustomRoute* route = nil; size_t needed; int mib[6]; char *buf, *next, *lim; register struct rt_msghdr2 *rtm; mib[0] = CTL_NET; mib[1] = PF_ROUTE; mib[2] = 0; mib[3] = 0; mib[4] = NET_RT_DUMP2; mib[5] = 0; if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) { err(1, "sysctl: net.route.0.0.dump estimate"); } if ((buf = malloc(needed)) == 0) { err(2, "malloc(%lu)", (unsigned long)needed); } if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) { err(1, "sysctl: net.route.0.0.dump"); } lim = buf + needed; for (next = buf; next < lim; next += rtm->rtm_msglen) { rtm = (struct rt_msghdr2 *)next; route = [self getRoute:rtm]; if(route != nil) { [routeArray addObject:route]; } } free(buf); printf("Total routes: %u\n", [routeArray count]); return routeArray; } + (CustomRoute*) getRoute:(struct rt_msghdr2 *)rtm { //sockaddrs are after the message header struct sockaddr* dst_sa = (struct sockaddr *)(rtm + 1); CustomRoute* route = nil; if(rtm->rtm_addrs & RTA_DST) { switch(dst_sa->sa_family) { case AF_INET: if(dst_sa->sa_family == AF_INET && !((rtm->rtm_flags & RTF_WASCLONED) && (rtm->rtm_parentflags & RTF_PRCLONING))) { route = [[CustomRoute alloc] initWithRtm:rtm]; } break; } } return route; } -(void) setAddr:(struct sockaddr*)sa index:(int)rtax_index { if(rtax_index >= 0 && rtax_index < RTAX_MAX) { memcpy(&(m_addrs[rtax_index]), sa, sizeof(struct sockaddr)); } } -(NSString*) getDestination { return [self getAddrStringByIndex:RTAX_DST]; } -(NSString*) getNetmask { return [self getAddrStringByIndex:RTAX_NETMASK]; } -(NSString*) getGateway { return [self getAddrStringByIndex:RTAX_GATEWAY]; } -(NSString*) getDetails { NSMutableString* result = [[NSMutableString alloc] init]; [result appendFormat: [NSString stringWithFormat: @"message type: 0x%06x\n", m_rtm.rtm_type]]; [result appendFormat: [NSString stringWithFormat: @"flags: 0x%06x\n", m_rtm.rtm_flags]]; [result appendFormat: [NSString stringWithFormat: @"addrs: 0x%06x\n", m_rtm.rtm_addrs]]; return result; } -initWithRtm: (struct rt_msghdr2*) rtm { int i; struct sockaddr* sa = (struct sockaddr*)(rtm + 1); //copy over the route message memcpy(&(m_rtm), rtm, sizeof(struct rt_msghdr2)); for(i = 0; i < RTAX_MAX; i++) { [self setAddr:&(sa[i]) index:i]; } return self; } - init { memset(m_addrs, 0, sizeof(m_addrs)); return self; } @end @implementation CustomRoute (Private) -(NSString*) getAddrStringByIndex: (int)rtax_index { NSString * routeString = nil; struct sockaddr* sa = &(m_addrs[rtax_index]); int flagVal = 1 << rtax_index; if(!(m_rtm.rtm_addrs & flagVal)) { return @"none"; } if(rtax_index >= 0 && rtax_index < RTAX_MAX) { switch(sa->sa_family) { case AF_INET: { struct sockaddr_in* si = (struct sockaddr_in *)sa; if(si->sin_addr.s_addr == INADDR_ANY) routeString = @"default"; else routeString = [NSString stringWithCString:(char *)inet_ntoa(si->sin_addr) encoding:NSASCIIStringEncoding]; } break; case AF_LINK: { struct sockaddr_dl* sdl = (struct sockaddr_dl*)sa; if(sdl->sdl_nlen + sdl->sdl_alen + sdl->sdl_slen == 0) { routeString = [NSString stringWithFormat: @"link #%d", sdl->sdl_index]; } else routeString = [NSString stringWithCString:link_ntoa(sdl) encoding:NSASCIIStringEncoding]; } break; default: { char a[3 * sa->sa_len]; char *cp; char *sep = ""; int i; if(sa->sa_len == 0) { routeString = @"empty"; } else { a[0] = (char)NULL; for(i = 0, cp = a; i < sa->sa_len; i++) { cp += sprintf(cp, "%s%02x", sep, (unsigned char)sa->sa_data[i]); sep = ":"; } routeString = [NSString stringWithCString:a encoding:NSASCIIStringEncoding]; } } } } return routeString; } @end 

CustomRoute.h:

 #import  #import  #import  #import  #import  #import  @interface CustomRoute : NSObject { struct sockaddr m_addrs[RTAX_MAX]; struct rt_msghdr2 m_rtm; int m_len; /* length of the sockaddr array */ } + (NSMutableArray*) getRoutes; + (CustomRoute*) getRoute:(struct rt_msghdr2 *)rtm; - (void) setAddr:(struct sockaddr*)sa index:(int)rtax_index; - (NSString*) getDestination; - (NSString*) getNetmask; - (NSString*) getGateway; - initWithRtm: (struct rt_msghdr2*) rtm; @end 

xxx.xxx.255.255 – маска подсети. Вам нужен адрес шлюза.

См. Таблицу 3-10, есть запись для маршрутизатора в thsi pdf: http://developer.apple.com/Mac/library/documentation/Networking/Conceptual/SystemConfigFrameworks/SystemConfigFrameworks.pdf

Версия HTML находится здесь: http://developer.apple.com/Mac/library/documentation/Networking/Conceptual/SystemConfigFrameworks/SC_Overview/SC_Overview.html

  • Пейзажный режим ТОЛЬКО для iPhone или iPad
  • Как установить получателей для UIActivityViewController в iOS 6?
  • Рисование поэтапно в UIView (iPhone)
  • Расчет скорости соединения / загрузки
  • Какую строку формата я использую в миллисекундах в строках даты на iPhone?
  • UITableViewCell расширяется по клику
  • Как я могу программно приостановить NSTimer?
  • Пользовательский интерфейс UINavigationBar
  • iphone error: expected '=', ',', ';', 'asm' или '__attribute__' перед '' foo '
  • Перемещение фигуры Stick, опорных точек, анимации или чего-то еще ...?
  • Восстановить пре-iOS7 UINavigationController pushViewController animation
  • Interesting Posts

    В чем разница между полем и свойством?

    Угловые 2+ и наблюдаемые: не могут привязываться к ‘ngModel’, поскольку это не известное свойство ‘select’

    Врач-врач говорит: «Предупреждение: / usr / local / include не доступно для записи».

    Как я могу разделить каждую строку матрицы на фиксированную строку?

    Предупреждение о недоставке: variant.getOutputFile () и variant.setOutputFile () устарели

    Зачем нужна строка для подключения при использовании boost :: asio?

    Все в .NET является объектом?

    Такая же политика происхождения и CORS (совместное использование ресурсов)

    objective c – Обнаруживать, когда пользователь меняет настройки уведомлений приложения

    Google не открывается в браузерах

    Корректность корректности для значений параметров

    Индекс символов в точке касания для UILabel

    Внешний жесткий диск не пуст, но файлы не отображаются

    Как захватить изображение из пользовательского CameraView в Android?

    Поиск и удаление символов без ascii из Oracle Varchar2

    Давайте будем гением компьютера.