|
|||
|
|||
|
Typedefs | |
| typedef sockaddr_in | insp_sockaddr |
| insp_sockaddr for ipv4 | |
| typedef in_addr | insp_inaddr |
| insp_inaddr for ipv4 | |
Functions | |
| bool | MatchCIDRBits (unsigned char *address, unsigned char *mask, unsigned int mask_bits) |
| Match raw binary data using CIDR rules. | |
| bool | MatchCIDR (const char *address, const char *cidr_mask) |
| Match CIDR, without matching username/nickname parts. | |
| bool | MatchCIDR (const char *address, const char *cidr_mask, bool match_with_username) |
| Match CIDR, including an optional username/nickname part. | |
| void | Blocking (int s) |
| Make a socket file descriptor a blocking socket. | |
| void | NonBlocking (int s) |
| Make a socket file descriptor into a nonblocking socket. | |
| int | OpenTCPSocket (char *addr, int socktype=SOCK_STREAM) |
| Create a new valid file descriptor using socket(). | |
| const char * | insp_ntoa (insp_inaddr n) |
| Convert an insp_inaddr into human readable form. | |
| int | insp_aton (const char *a, insp_inaddr *n) |
| Convert a human-readable address into an insp_inaddr. | |
It also contains some types which are often used by the core and modules in place of inet_* functions and types.
|
|
insp_inaddr for ipv4
|
|
|
insp_sockaddr for ipv4
|
|
|
Make a socket file descriptor a blocking socket.
Definition at line 298 of file socket.cpp. 00299 { 00300 #ifndef WIN32 00301 int flags = fcntl(s, F_GETFL, 0); 00302 fcntl(s, F_SETFL, flags ^ O_NONBLOCK); 00303 #else 00304 unsigned long opt = 0; 00305 ioctlsocket(s, FIONBIO, &opt); 00306 #endif 00307 }
|
|
||||||||||||
|
Convert a human-readable address into an insp_inaddr.
Definition at line 563 of file socket.cpp. References AF_FAMILY. Referenced by DispatcherThread(), Resolver::Resolver(), and SQLConn::SendNotify(). 00564 { 00565 return inet_pton(AF_FAMILY, a, n); 00566 }
|
|
|
Convert an insp_inaddr into human readable form.
Definition at line 556 of file socket.cpp. References AF_FAMILY. Referenced by DNS::GetName(). 00557 { 00558 static char buf[1024]; 00559 inet_ntop(AF_FAMILY, &n, buf, sizeof(buf)); 00560 return buf; 00561 }
|
|
||||||||||||||||
|
Match CIDR, including an optional username/nickname part. This function will compare a human-readable address (plus optional username and nickname) against a human-readable CIDR mask, for example joe!bloggs@1.2.3.4 against *!bloggs@1.2.0.0/16. This method supports both IPV4 and IPV6 addresses.
Definition at line 164 of file socket.cpp. References match(), MatchCIDR(), and MatchCIDRBits(). 00165 { 00166 unsigned char addr_raw[16]; 00167 unsigned char mask_raw[16]; 00168 unsigned int bits = 0; 00169 char* mask = NULL; 00170 00171 /* The caller is trying to match ident@<mask>/bits. 00172 * Chop off the ident@ portion, use match() on it 00173 * seperately. 00174 */ 00175 if (match_with_username) 00176 { 00177 /* Duplicate the strings, and try to find the position 00178 * of the @ symbol in each */ 00179 char* address_dupe = strdup(address); 00180 char* cidr_dupe = strdup(cidr_mask); 00181 00182 /* Use strchr not strrchr, because its going to be nearer to the left */ 00183 char* username_mask_pos = strrchr(cidr_dupe, '@'); 00184 char* username_addr_pos = strrchr(address_dupe, '@'); 00185 00186 /* Both strings have an @ symbol in them */ 00187 if (username_mask_pos && username_addr_pos) 00188 { 00189 /* Zero out the location of the @ symbol */ 00190 *username_mask_pos = *username_addr_pos = 0; 00191 00192 /* Try and match() the strings before the @ 00193 * symbols, and recursively call MatchCIDR without 00194 * username matching enabled to match the host part. 00195 */ 00196 bool result = (match(address_dupe, cidr_dupe) && MatchCIDR(username_addr_pos + 1, username_mask_pos + 1, false)); 00197 00198 /* Free the stuff we created */ 00199 free(address_dupe); 00200 free(cidr_dupe); 00201 00202 /* Return a result */ 00203 return result; 00204 } 00205 else 00206 { 00207 /* One or both didnt have an @ in, 00208 * just match as CIDR 00209 */ 00210 free(address_dupe); 00211 free(cidr_dupe); 00212 mask = strdup(cidr_mask); 00213 } 00214 } 00215 else 00216 { 00217 /* Make a copy of the cidr mask string, 00218 * we're going to change it 00219 */ 00220 mask = strdup(cidr_mask); 00221 } 00222 00223 in_addr address_in4; 00224 in_addr mask_in4; 00225 00226 00227 /* Use strrchr for this, its nearer to the right */ 00228 char* bits_chars = strrchr(mask,'/'); 00229 00230 if (bits_chars) 00231 { 00232 bits = atoi(bits_chars + 1); 00233 *bits_chars = 0; 00234 } 00235 else 00236 { 00237 /* No 'number of bits' field! */ 00238 free(mask); 00239 return false; 00240 } 00241 00242 #ifdef SUPPORT_IP6LINKS 00243 in6_addr address_in6; 00244 in6_addr mask_in6; 00245 00246 if (inet_pton(AF_INET6, address, &address_in6) > 0) 00247 { 00248 if (inet_pton(AF_INET6, mask, &mask_in6) > 0) 00249 { 00250 memcpy(&addr_raw, &address_in6.s6_addr, 16); 00251 memcpy(&mask_raw, &mask_in6.s6_addr, 16); 00252 00253 if (bits > 128) 00254 bits = 128; 00255 } 00256 else 00257 { 00258 /* The address was valid ipv6, but the mask 00259 * that goes with it wasnt. 00260 */ 00261 free(mask); 00262 return false; 00263 } 00264 } 00265 else 00266 #endif 00267 if (inet_pton(AF_INET, address, &address_in4) > 0) 00268 { 00269 if (inet_pton(AF_INET, mask, &mask_in4) > 0) 00270 { 00271 memcpy(&addr_raw, &address_in4.s_addr, 4); 00272 memcpy(&mask_raw, &mask_in4.s_addr, 4); 00273 00274 if (bits > 32) 00275 bits = 32; 00276 } 00277 else 00278 { 00279 /* The address was valid ipv4, 00280 * but the mask that went with it wasnt. 00281 */ 00282 free(mask); 00283 return false; 00284 } 00285 } 00286 else 00287 { 00288 /* The address was neither ipv4 or ipv6 */ 00289 free(mask); 00290 return false; 00291 } 00292 00293 /* Low-level-match the bits in the raw data */ 00294 free(mask); 00295 return MatchCIDRBits(addr_raw, mask_raw, bits); 00296 }
|
|
||||||||||||
|
Match CIDR, without matching username/nickname parts. This function will compare a human-readable address against a human- readable CIDR mask, for example 1.2.3.4 against 1.2.0.0/16. This method supports both IPV4 and IPV6 addresses.
Definition at line 152 of file socket.cpp. Referenced by match(), MatchCIDR(), and TreeSocket::OnIncomingConnection(). 00153 { 00154 return MatchCIDR(address, cidr_mask, false); 00155 }
|
|
||||||||||||||||
|
Match raw binary data using CIDR rules. This function will use binary comparison to compare the two bit sequences, address and mask, up to mask_bits bits in size. If they match, it will return true.
Definition at line 132 of file socket.cpp. References inverted_bits. Referenced by MatchCIDR(). 00133 { 00134 unsigned int modulus = mask_bits % 8; /* Number of whole bytes in the mask */ 00135 unsigned int divisor = mask_bits / 8; /* Remaining bits in the mask after whole bytes are dealt with */ 00136 00137 /* First compare the whole bytes, if they dont match, return false */ 00138 if (memcmp(address, mask, divisor)) 00139 return false; 00140 00141 /* Now if there are any remainder bits, we compare them with logic AND */ 00142 if (modulus) 00143 if ((address[divisor] & inverted_bits[modulus]) != (mask[divisor] & inverted_bits[modulus])) 00144 /* If they dont match, return false */ 00145 return false; 00146 00147 /* The address matches the mask, to mask_bits bits of mask */ 00148 return true; 00149 }
|
|
|
Make a socket file descriptor into a nonblocking socket.
Definition at line 309 of file socket.cpp. Referenced by InspIRCd::BindSocket(), ListenSocket::HandleEvent(), IdentRequestSocket::IdentRequestSocket(), InspSocket::Poll(), and DNS::Rehash(). 00310 { 00311 #ifndef WIN32 00312 int flags = fcntl(s, F_GETFL, 0); 00313 fcntl(s, F_SETFL, flags | O_NONBLOCK); 00314 #else 00315 unsigned long opt = 1; 00316 ioctlsocket(s, FIONBIO, &opt); 00317 #endif 00318 }
|
|
||||||||||||
|
Create a new valid file descriptor using socket().
Definition at line 446 of file socket.cpp. References ERROR. Referenced by InspSocket::InspSocket(), ListenSocket::ListenSocket(), and DNS::Rehash(). 00447 { 00448 int sockfd; 00449 int on = 1; 00450 struct linger linger = { 0 }; 00451 #ifdef IPV6 00452 if (strchr(addr,':') || (!*addr)) 00453 sockfd = socket (PF_INET6, socktype, 0); 00454 else 00455 sockfd = socket (PF_INET, socktype, 0); 00456 if (sockfd < 0) 00457 #else 00458 if ((sockfd = socket (PF_INET, socktype, 0)) < 0) 00459 #endif 00460 { 00461 return ERROR; 00462 } 00463 else 00464 { 00465 setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on)); 00466 /* This is BSD compatible, setting l_onoff to 0 is *NOT* http://web.irc.org/mla/ircd-dev/msg02259.html */ 00467 linger.l_onoff = 1; 00468 linger.l_linger = 1; 00469 setsockopt(sockfd, SOL_SOCKET, SO_LINGER, (char*)&linger,sizeof(linger)); 00470 return (sockfd); 00471 } 00472 }
|