]>
Commit | Line | Data |
---|---|---|
afb19109 A |
1 | /* |
2 | * Copyright (c) 2018 Apple Inc. All rights reserved. | |
3 | * | |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
6 | * This file contains Original Code and/or Modifications of Original Code | |
7 | * as defined in and that are subject to the Apple Public Source License | |
8 | * Version 2.0 (the 'License'). You may not use this file except in | |
9 | * compliance with the License. Please obtain a copy of the License at | |
10 | * http://www.opensource.apple.com/apsl/ and read it before using this | |
11 | * file. | |
12 | * | |
13 | * The Original Code and all software distributed under the License are | |
14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. | |
18 | * Please see the License for the specific language governing rights and | |
19 | * limitations under the License. | |
20 | * | |
21 | * @APPLE_LICENSE_HEADER_END@ | |
22 | */ | |
23 | ||
24 | #import <Foundation/Foundation.h> | |
25 | #import <EventFactory/EventFactory.h> | |
26 | #import <arpa/inet.h> | |
27 | ||
28 | #import "SCLogParser.h" | |
29 | ||
30 | @interface SCLogParser () | |
31 | @property uint64_t nextEventCounter; | |
32 | @end | |
33 | ||
34 | @implementation SCLogParser | |
35 | ||
36 | - (instancetype)initWithCategory:(NSString *)category eventParser:(EFLogEventParser *)eventParser | |
37 | { | |
38 | self = [super init]; | |
39 | if (self) { | |
40 | _category = category; | |
41 | _eventParser = eventParser; | |
42 | _nextEventCounter = 1; | |
43 | } | |
44 | return self; | |
45 | } | |
46 | ||
47 | + (NSMutableDictionary<NSString *, NSArray<NSString *> *> *)interfaceMap | |
48 | { | |
49 | static NSMutableDictionary<NSString *, NSArray<NSString *> *> *_interfaceMap = nil; | |
50 | static dispatch_once_t onceToken; | |
51 | dispatch_once(&onceToken, ^{ | |
52 | _interfaceMap = [[NSMutableDictionary alloc] init]; | |
53 | }); | |
54 | return _interfaceMap; | |
55 | } | |
56 | ||
57 | - (NSData *)createSubsystemIdentifier | |
58 | { | |
59 | NSString *identifierString = [[NSString alloc] initWithFormat:@"%@.%llu", _category, _nextEventCounter]; | |
60 | _nextEventCounter++; | |
61 | const char *utf8String = identifierString.UTF8String; | |
62 | return [[NSData alloc] initWithBytes:utf8String length:strlen(utf8String)]; | |
63 | } | |
64 | ||
65 | - (NSArray<NSString *> *)addUniqueString:(NSString *)newString toArray:(NSArray<NSString *> *)array | |
66 | { | |
67 | if (array.count > 0) { | |
68 | NSInteger index = [array indexOfObject:newString]; | |
69 | return (index == NSNotFound ? [array arrayByAddingObject:newString] : array); | |
70 | } else { | |
71 | return @[ newString ]; | |
72 | } | |
73 | } | |
74 | ||
75 | - (NSArray<NSString *> *)addUniqueStrings:(NSArray<NSString *> *)strings toArray:(NSArray<NSString *> *)array | |
76 | { | |
77 | if (array == nil) { | |
78 | return strings; | |
79 | } | |
80 | ||
81 | NSMutableArray<NSString *> *uniqueStrings = [[NSMutableArray alloc] init]; | |
82 | for (NSString *string in strings) { | |
83 | NSInteger index = [array indexOfObject:string]; | |
84 | if (index == NSNotFound) { | |
85 | [uniqueStrings addObject:string]; | |
86 | } | |
87 | } | |
88 | if (uniqueStrings.count > 0) { | |
89 | return [array arrayByAddingObjectsFromArray:uniqueStrings]; | |
90 | } else { | |
91 | return array; | |
92 | } | |
93 | } | |
94 | ||
95 | - (EFNetworkControlPathEvent *)createInterfaceEventWithLogEvent:(EFLogEvent *)logEvent matchResult:(NSTextCheckingResult *)matchResult | |
96 | { | |
97 | EFNetworkControlPathEvent *newEvent = nil; | |
98 | NSString *interfaceName = [logEvent substringForCaptureGroup:@TokenInterfaceName inMatchResult:matchResult]; | |
99 | if (interfaceName != nil) { | |
100 | if (SCLogParser.interfaceMap[interfaceName] == nil) { | |
101 | SCLogParser.interfaceMap[interfaceName] = @[]; | |
102 | } | |
103 | NSData *identifier = [self createSubsystemIdentifier]; | |
104 | newEvent = [[EFNetworkControlPathEvent alloc] initWithLogEvent:logEvent subsystemIdentifier:identifier]; | |
105 | newEvent.interfaceBSDName = interfaceName; | |
106 | } | |
107 | return newEvent; | |
108 | } | |
109 | ||
110 | - (EFNetworkControlPathEvent *)createInterfaceEventWithLogEvent:(EFLogEvent *)logEvent interfaceName:(NSString *)interfaceName | |
111 | { | |
112 | EFNetworkControlPathEvent *newEvent = nil; | |
113 | if (SCLogParser.interfaceMap[interfaceName] == nil) { | |
114 | SCLogParser.interfaceMap[interfaceName] = @[]; | |
115 | } | |
116 | NSData *identifier = [self createSubsystemIdentifier]; | |
117 | newEvent = [[EFNetworkControlPathEvent alloc] initWithLogEvent:logEvent subsystemIdentifier:identifier]; | |
118 | newEvent.interfaceBSDName = interfaceName; | |
119 | return newEvent; | |
120 | } | |
121 | ||
122 | - (void)addAddress:(NSString *)addressString toInterfaceEvent:(EFNetworkControlPathEvent *)event | |
123 | { | |
124 | if (event.interfaceBSDName != nil) { | |
125 | NSArray<NSString *> *addresses = SCLogParser.interfaceMap[event.interfaceBSDName]; | |
126 | event.addresses = [self addUniqueString:addressString toArray:addresses]; | |
127 | SCLogParser.interfaceMap[event.interfaceBSDName] = event.addresses; | |
128 | } | |
129 | } | |
130 | ||
131 | - (BOOL)removeAddress:(NSString *)addressString fromInterfaceEvent:(EFNetworkControlPathEvent *)event | |
132 | { | |
133 | if (event.interfaceBSDName != nil) { | |
134 | NSArray<NSString *> *addresses = SCLogParser.interfaceMap[event.interfaceBSDName]; | |
135 | if (addresses.count > 0) { | |
136 | NSPredicate *matchPredicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, __unused NSDictionary<NSString *,id> *bindings) { | |
137 | NSString *matchString = (NSString *)evaluatedObject; | |
138 | if (matchString != nil) { | |
139 | return ![matchString isEqualToString:addressString]; | |
140 | } else { | |
141 | return NO; | |
142 | } | |
143 | }]; | |
144 | event.addresses = [addresses filteredArrayUsingPredicate:matchPredicate]; | |
145 | SCLogParser.interfaceMap[event.interfaceBSDName] = event.addresses; | |
146 | return YES; | |
147 | } | |
148 | } | |
149 | ||
150 | return NO; | |
151 | } | |
152 | ||
153 | - (NSString *)substringOfString:(NSString *)matchedString forCaptureGroup:(NSString *)groupName inMatchResult:(NSTextCheckingResult *)result | |
154 | { | |
155 | NSString *substring = nil; | |
156 | NSRange groupRange = [result rangeWithName:groupName]; | |
157 | if (!NSEqualRanges(groupRange, NSMakeRange(NSNotFound, 0))) { | |
158 | substring = [matchedString substringWithRange:groupRange]; | |
159 | } | |
160 | return substring; | |
161 | } | |
162 | ||
163 | - (sa_family_t)getAddressFamilyOfAddress:(NSString *)addressString | |
164 | { | |
165 | sa_family_t af = AF_UNSPEC; | |
166 | struct in6_addr v6addr; | |
167 | struct in_addr v4addr; | |
168 | ||
169 | if (inet_pton(AF_INET6, addressString.UTF8String, &v6addr) == 1) { | |
170 | af = AF_INET6; | |
171 | } else if (inet_pton(AF_INET, addressString.UTF8String, &v4addr)) { | |
172 | af = AF_INET; | |
173 | } | |
174 | ||
175 | return af; | |
176 | } | |
177 | ||
178 | @end |