1/* 2 * Copyright (c) 2012-2014 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_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. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 29// 30// Created by Anumita Biswas on 10/30/12. 31// 32 33#include <stdio.h> 34#include <stdlib.h> 35#include <unistd.h> 36#include <string.h> 37#include <stdint.h> 38#include <sys/types.h> 39#include <sys/socket.h> 40#include <sys/ioctl.h> 41#include <errno.h> 42 43 44#include "conn_lib.h" 45 46int 47copyassocids(int s, associd_t **aidpp, uint32_t *cnt) 48{ 49 struct so_aidreq aidr; 50 associd_t *buf; 51 int err; 52 53 if (aidpp == NULL || cnt == NULL) { 54 errno = EINVAL; 55 return (-1); 56 } 57 *aidpp = NULL; 58 *cnt = 0; 59 60 bzero(&aidr, sizeof (aidr)); 61 62 err = ioctl(s, SIOCGASSOCIDS, &aidr); 63 if (err != 0) 64 return (-1); 65 66 /* none, just return */ 67 if (aidr.sar_cnt == 0) 68 return (0); 69 70 buf = calloc(aidr.sar_cnt, sizeof (associd_t)); 71 if (buf == NULL) 72 return (-1); 73 74 aidr.sar_aidp = buf; 75 err = ioctl(s, SIOCGASSOCIDS, &aidr); 76 if (err != 0) { 77 free(buf); 78 return (-1); 79 } 80 81 *aidpp = buf; 82 *cnt = aidr.sar_cnt; 83 84 return (0); 85} 86 87void 88freeassocids(associd_t *aidp) 89{ 90 free(aidp); 91} 92 93int 94copyconnids(int s, associd_t aid, connid_t **cidp, uint32_t *cnt) 95{ 96 struct so_cidreq cidr; 97 connid_t *buf; 98 int err; 99 100 if (cidp == NULL || cnt == NULL) { 101 errno = EINVAL; 102 return (-1); 103 } 104 *cidp = NULL; 105 *cnt = 0; 106 107 bzero(&cidr, sizeof (cidr)); 108 109 cidr.scr_aid = aid; 110 err = ioctl(s, SIOCGCONNIDS, &cidr); 111 if (err != 0) 112 return (-1); 113 114 /* none, just return */ 115 if (cidr.scr_cnt == 0) 116 return (0); 117 118 buf = calloc(cidr.scr_cnt, sizeof (connid_t)); 119 if (buf == NULL) 120 return (-1); 121 122 cidr.scr_cidp = buf; 123 err = ioctl(s, SIOCGCONNIDS, &cidr); 124 if (err != 0) { 125 free(buf); 126 return (-1); 127 } 128 129 *cidp = buf; 130 *cnt = cidr.scr_cnt; 131 132 return (0); 133} 134 135void 136freeconnids(connid_t *cidp) 137{ 138 free(cidp); 139} 140 141int 142copyconninfo(int s, connid_t cid, conninfo_t **cfop) 143{ 144 struct sockaddr *src = NULL, *dst = NULL, *aux = NULL; 145 struct so_cinforeq scir; 146 conninfo_t *buf = NULL; 147 148 if (cfop == NULL) { 149 errno = EINVAL; 150 goto error; 151 } 152 *cfop = NULL; 153 154 bzero(&scir, sizeof (scir)); 155 156 scir.scir_cid = cid; 157 if (ioctl(s, SIOCGCONNINFO, &scir) != 0) 158 goto error; 159 160 if (scir.scir_src_len != 0) { 161 src = calloc(1, scir.scir_src_len); 162 if (src == NULL) 163 goto error; 164 scir.scir_src = src; 165 } 166 if (scir.scir_dst_len != 0) { 167 dst = calloc(1, scir.scir_dst_len); 168 if (dst == NULL) 169 goto error; 170 scir.scir_dst = dst; 171 } 172 if (scir.scir_aux_len != 0) { 173 aux = calloc(1, scir.scir_aux_len); 174 if (aux == NULL) 175 goto error; 176 scir.scir_aux_data = aux; 177 } 178 179 if (ioctl(s, SIOCGCONNINFO, &scir) != 0) 180 goto error; 181 182 buf = calloc(1, sizeof (*buf)); 183 if (buf == NULL) 184 goto error; 185 186 // When we query for the length using the first ioctl call above, the kernel 187 // tells us the length of the aux structure so we know how much to allocate 188 // memory. There may not be any aux data, which will be indicated by the aux 189 // data length using the second ioctl call. 190 if (scir.scir_aux_len == 0 && aux != NULL) { 191 free(aux); 192 aux = NULL; 193 scir.scir_aux_data = NULL; 194 } 195 196 buf->ci_flags = scir.scir_flags; 197 buf->ci_ifindex = scir.scir_ifindex; 198 buf->ci_src = src; 199 buf->ci_dst = dst; 200 buf->ci_error = scir.scir_error; 201 buf->ci_aux_type = scir.scir_aux_type; 202 buf->ci_aux_data = aux; 203 *cfop = buf; 204 205 return (0); 206 207error: 208 if (src != NULL) 209 free(src); 210 if (dst != NULL) 211 free(dst); 212 if (aux != NULL) 213 free(aux); 214 if (buf != NULL) 215 free(buf); 216 217 return (-1); 218} 219 220void 221freeconninfo(conninfo_t *cfo) 222{ 223 if (cfo->ci_src != NULL) 224 free(cfo->ci_src); 225 226 if (cfo->ci_dst != NULL) 227 free(cfo->ci_dst); 228 229 if (cfo->ci_aux_data != NULL) 230 free(cfo->ci_aux_data); 231 232 free(cfo); 233} 234