1
- //
2
1
// MacFinder.m
3
2
// MacFinder
4
3
//
5
4
// Created by Michael Mavris on 08/06/16.
6
5
// Copyright © 2016 Miksoft. All rights reserved.
7
6
//
7
+
8
8
#import " MacFinder.h"
9
+ #define BUFLEN (sizeof (struct rt_msghdr) + 512 )
10
+ #define SEQ 9999
11
+ #define RTM_VERSION 5 // important, version 2 does not return a mac address!
12
+ #define RTM_GET 0x4 // Report Metrics
13
+ #define RTF_LLINFO 0x400 // generated by link layer (e.g. ARP)
14
+ #define RTF_IFSCOPE 0x1000000 // has valid interface scope
15
+ #define RTA_DST 0x1 // destination sockaddr present
9
16
10
17
@implementation MacFinder
11
18
12
- +(NSString *)ip2mac : (NSString *)strIP {
19
+ +(NSString *)ip2mac : (NSString *)strIP {
13
20
14
21
const char *ip = [strIP UTF8String ];
15
22
16
- int found_entry = 0 ;
17
- int nflag=0 ;
18
-
19
- NSString *mAddr = nil ;
20
- u_long addr = inet_addr (ip);
21
- int mib[6 ];
22
- size_t needed;
23
- char *host, *lim, *buf, *next;
23
+ int sockfd;
24
+ unsigned char buf[BUFLEN];
25
+ unsigned char buf2[BUFLEN];
26
+ ssize_t n;
24
27
struct rt_msghdr *rtm;
25
- struct sockaddr_inarp *sin;
26
- struct sockaddr_dl *sdl;
27
- extern int h_errno;
28
- struct hostent *hp;
29
-
30
- mib[0 ] = CTL_NET;
31
- mib[1 ] = PF_ROUTE;
32
- mib[2 ] = 0 ;
33
- mib[3 ] = AF_INET;
34
- mib[4 ] = NET_RT_FLAGS;
35
- mib[5 ] = RTF_LLINFO;
36
-
37
- if (sysctl (mib, 6 , NULL , &needed, NULL , 0 ) < 0 )
38
- err (1 , " route-sysctl-estimate" );
39
- if ((buf = malloc (needed)) == NULL )
40
- err (1 , " malloc" );
41
- if (sysctl (mib, 6 , buf, &needed, NULL , 0 ) < 0 )
42
- err (1 , " actual retrieval of routing table" );
43
-
44
- lim = buf + needed;
45
-
46
- for (next = buf; next < lim; next += rtm->rtm_msglen ) {
47
- rtm = (struct rt_msghdr *)next;
48
- sin = (struct sockaddr_inarp *)(rtm + 1 );
49
- sdl = (struct sockaddr_dl *)(sin + 1 );
50
- if (addr) {
51
- if (addr != sin->sin_addr .s_addr )
52
- continue ;
53
- found_entry = 1 ;
54
- }
55
- if (nflag == 0 )
56
- hp = gethostbyaddr ((caddr_t )&(sin->sin_addr ),
57
- sizeof sin->sin_addr , AF_INET);
58
- else
59
- hp = 0 ;
60
- if (hp)
61
- host = hp->h_name ;
62
- else {
63
- host = " ?" ;
64
- if (h_errno == TRY_AGAIN)
65
- nflag = 1 ;
66
- }
67
-
68
-
69
- if (sdl->sdl_alen ) {
70
-
71
- u_char *cp =(u_char*)LLADDR (sdl);
72
-
73
- mAddr = [NSString stringWithFormat: @" %x :%x :%x :%x :%x :%x " , cp[0 ], cp[1 ], cp[2 ], cp[3 ], cp[4 ], cp[5 ]];
74
- }
75
- else
76
- mAddr = nil ;
77
- }
28
+ struct sockaddr_in *sin;
29
+ memset (buf,0 ,sizeof (buf));
30
+ memset (buf2,0 ,sizeof (buf2));
78
31
32
+ sockfd = socket (AF_ROUTE, SOCK_RAW, 0 );
33
+ rtm = (struct rt_msghdr *) buf;
34
+ rtm->rtm_msglen = sizeof (struct rt_msghdr) + sizeof (struct sockaddr_in);
35
+ rtm->rtm_version = RTM_VERSION;
36
+ rtm->rtm_type = RTM_GET;
37
+ rtm->rtm_addrs = RTA_DST;
38
+ rtm->rtm_flags = RTF_LLINFO;
39
+ rtm->rtm_pid = 1234 ;
40
+ rtm->rtm_seq = SEQ;
79
41
80
- if (!mAddr) {
81
- return nil ;
82
- }
83
42
84
- // Fixing the issue with 0 in MAC Address (eg. 00 will be displayed as 0. We fix this here).
85
- NSArray *macArray = [mAddr componentsSeparatedByString: @" :" ];
43
+ sin = (struct sockaddr_in *) (rtm + 1 );
44
+ sin->sin_len = sizeof (struct sockaddr_in);
45
+ sin->sin_family = AF_INET;
46
+ sin->sin_addr .s_addr = inet_addr (ip);
47
+ write (sockfd, rtm, rtm->rtm_msglen );
86
48
87
- NSMutableString *mutStr = [[NSMutableString alloc ] init ];
49
+ n = read (sockfd, buf2, BUFLEN);
50
+ close (sockfd);
88
51
89
- for (int i=0 ; i < [macArray count ]; i++) {
90
- NSString *str = [macArray objectAtIndex: i];
91
- if ([str length ]<2 ) {
92
- [mutStr appendString: @" 0" ];
52
+ if (n != 0 ) {
53
+ int index = sizeof (struct rt_msghdr) + sizeof (struct sockaddr_inarp) + 8 ;
54
+ // savedata("test",buf2,n);
55
+ NSString *macAddress =[NSString stringWithFormat: @" %2.2x :%2.2x :%2.2x :%2.2x :%2.2x :%2.2x " ,buf2[index+0 ], buf2[index+1 ], buf2[index+2 ], buf2[index+3 ], buf2[index+4 ], buf2[index+5 ]];
56
+ // If macAddress is equal to 00:00.. then mac address not exist in ARP table and returns nil. If it retuns 08:00.. then the mac address not exist because it's not in the same subnet with the device and return nils
57
+ if ([macAddress isEqualToString: @" 00:00:00:00:00:00" ] ||[macAddress isEqualToString: @" 08:00:00:00:00:00" ] ) {
58
+ return nil ;
93
59
}
94
-
95
- NSString *strToAppend = i < [macArray count ] - 1 ? [NSString stringWithFormat: @" %@ :" ,str] : str;
96
-
97
- [mutStr appendString: strToAppend];
98
- }
99
-
100
- if (found_entry == 0 ) {
101
-
102
- return nil ;
103
- }
104
- else {
105
-
106
- return mutStr;
60
+ return macAddress;
107
61
}
62
+ return nil ;
108
63
}
109
- @end
64
+ @end
65
+
0 commit comments