irfcommd.c - rfcommd - RFCOMM daemon to run filters on clients. Err bitreich.org 70 hgit clone git://bitreich.org/rfcommd/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/rfcommd/ URL:git://bitreich.org/rfcommd/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/rfcommd/ bitreich.org 70 1Log /scm/rfcommd/log.gph bitreich.org 70 1Files /scm/rfcommd/files.gph bitreich.org 70 1Refs /scm/rfcommd/refs.gph bitreich.org 70 1Tags /scm/rfcommd/tag bitreich.org 70 1README /scm/rfcommd/file/README.md.gph bitreich.org 70 1LICENSE /scm/rfcommd/file/LICENSE.gph bitreich.org 70 i--- Err bitreich.org 70 irfcommd.c (12906B) Err bitreich.org 70 i--- Err bitreich.org 70 i 1 /* Err bitreich.org 70 i 2 * See LICENSE for copyright details. Err bitreich.org 70 i 3 * Err bitreich.org 70 i 4 * Logic copied from rfcomm.c in bluez. Err bitreich.org 70 i 5 * SDP code from pybluez. Err bitreich.org 70 i 6 * Err bitreich.org 70 i 7 * Copy me if you can. Err bitreich.org 70 i 8 * by 20h Err bitreich.org 70 i 9 */ Err bitreich.org 70 i 10 Err bitreich.org 70 i 11 #include Err bitreich.org 70 i 12 #include Err bitreich.org 70 i 13 #include Err bitreich.org 70 i 14 #include Err bitreich.org 70 i 15 #include Err bitreich.org 70 i 16 #include Err bitreich.org 70 i 17 #include Err bitreich.org 70 i 18 #include Err bitreich.org 70 i 19 #include Err bitreich.org 70 i 20 #include Err bitreich.org 70 i 21 #include Err bitreich.org 70 i 22 #include Err bitreich.org 70 i 23 #include Err bitreich.org 70 i 24 #include Err bitreich.org 70 i 25 #include Err bitreich.org 70 i 26 #include Err bitreich.org 70 i 27 #include Err bitreich.org 70 i 28 #include Err bitreich.org 70 i 29 Err bitreich.org 70 i 30 #include Err bitreich.org 70 i 31 #include Err bitreich.org 70 i 32 #include Err bitreich.org 70 i 33 #include Err bitreich.org 70 i 34 #include Err bitreich.org 70 i 35 #include Err bitreich.org 70 i 36 Err bitreich.org 70 i 37 #include "arg.h" Err bitreich.org 70 i 38 Err bitreich.org 70 i 39 volatile sig_atomic_t __io_canceled = 0; Err bitreich.org 70 i 40 Err bitreich.org 70 i 41 int dodebug = 0; Err bitreich.org 70 i 42 Err bitreich.org 70 i 43 void Err bitreich.org 70 i 44 debug(char *fmt, ...) Err bitreich.org 70 i 45 { Err bitreich.org 70 i 46 va_list fmtargs; Err bitreich.org 70 i 47 Err bitreich.org 70 i 48 if (!dodebug) Err bitreich.org 70 i 49 return; Err bitreich.org 70 i 50 Err bitreich.org 70 i 51 va_start(fmtargs, fmt); Err bitreich.org 70 i 52 vfprintf(stderr, fmt, fmtargs); Err bitreich.org 70 i 53 va_end(fmtargs); Err bitreich.org 70 i 54 } Err bitreich.org 70 i 55 Err bitreich.org 70 i 56 void Err bitreich.org 70 i 57 sig_hup(int sig) Err bitreich.org 70 i 58 { Err bitreich.org 70 i 59 return; Err bitreich.org 70 i 60 } Err bitreich.org 70 i 61 Err bitreich.org 70 i 62 void Err bitreich.org 70 i 63 sig_term(int sig) Err bitreich.org 70 i 64 { Err bitreich.org 70 i 65 __io_canceled = 1; Err bitreich.org 70 i 66 } Err bitreich.org 70 i 67 Err bitreich.org 70 i 68 void Err bitreich.org 70 i 69 setup_signals(void) Err bitreich.org 70 i 70 { Err bitreich.org 70 i 71 struct sigaction sa; Err bitreich.org 70 i 72 Err bitreich.org 70 i 73 memset(&sa, 0, sizeof(sa)); Err bitreich.org 70 i 74 sa.sa_flags = SA_NOCLDSTOP; Err bitreich.org 70 i 75 sa.sa_handler = SIG_IGN; Err bitreich.org 70 i 76 sigaction(SIGCHLD, &sa, NULL); Err bitreich.org 70 i 77 sigaction(SIGPIPE, &sa, NULL); Err bitreich.org 70 i 78 Err bitreich.org 70 i 79 sa.sa_handler = sig_term; Err bitreich.org 70 i 80 sigaction(SIGTERM, &sa, NULL); Err bitreich.org 70 i 81 sigaction(SIGINT, &sa, NULL); Err bitreich.org 70 i 82 Err bitreich.org 70 i 83 sa.sa_handler = sig_hup; Err bitreich.org 70 i 84 sigaction(SIGHUP, &sa, NULL); Err bitreich.org 70 i 85 } Err bitreich.org 70 i 86 Err bitreich.org 70 i 87 int Err bitreich.org 70 i 88 _adv_available(struct hci_dev_info *di) Err bitreich.org 70 i 89 { Err bitreich.org 70 i 90 uint32_t *flags = &di->flags; Err bitreich.org 70 i 91 int dd; Err bitreich.org 70 i 92 Err bitreich.org 70 i 93 if (hci_test_bit(HCI_RAW, &flags) && !bacmp(&di->bdaddr, BDADDR_ANY)) { Err bitreich.org 70 i 94 dd = hci_open_dev(di->dev_id); Err bitreich.org 70 i 95 Err bitreich.org 70 i 96 if (dd < 0) Err bitreich.org 70 i 97 return -1; Err bitreich.org 70 i 98 hci_read_bd_addr(dd, &di->bdaddr, 1000); Err bitreich.org 70 i 99 hci_close_dev(dd); Err bitreich.org 70 i 100 } Err bitreich.org 70 i 101 Err bitreich.org 70 i 102 return (hci_test_bit(HCI_UP, flags) && Err bitreich.org 70 i 103 hci_test_bit(HCI_RUNNING, flags) && Err bitreich.org 70 i 104 hci_test_bit(HCI_PSCAN, flags) && Err bitreich.org 70 i 105 hci_test_bit(HCI_ISCAN, flags)) != 0 ? 0 : -1; Err bitreich.org 70 i 106 } Err bitreich.org 70 i 107 Err bitreich.org 70 i 108 int Err bitreich.org 70 i 109 _any_adv_available(void) Err bitreich.org 70 i 110 { Err bitreich.org 70 i 111 struct hci_dev_list_req *dl = NULL; Err bitreich.org 70 i 112 struct hci_dev_req *dr = NULL; Err bitreich.org 70 i 113 struct hci_dev_info di = {0, }; Err bitreich.org 70 i 114 int result = -1; Err bitreich.org 70 i 115 int ctl = -1; Err bitreich.org 70 i 116 int i; Err bitreich.org 70 i 117 Err bitreich.org 70 i 118 if ((ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) Err bitreich.org 70 i 119 return -1; Err bitreich.org 70 i 120 Err bitreich.org 70 i 121 if (!(dl = malloc(HCI_MAX_DEV * sizeof(struct hci_dev_req) + Err bitreich.org 70 i 122 sizeof(uint16_t)))) { Err bitreich.org 70 i 123 goto CLEAN_UP_RETURN; Err bitreich.org 70 i 124 } Err bitreich.org 70 i 125 dl->dev_num = HCI_MAX_DEV; Err bitreich.org 70 i 126 dr = dl->dev_req; Err bitreich.org 70 i 127 Err bitreich.org 70 i 128 if (ioctl(ctl, HCIGETDEVLIST, (void *)dl) < 0) Err bitreich.org 70 i 129 goto CLEAN_UP_RETURN; Err bitreich.org 70 i 130 Err bitreich.org 70 i 131 for (i = 0; i < dl->dev_num; i++) { Err bitreich.org 70 i 132 di.dev_id = (dr+i)->dev_id; Err bitreich.org 70 i 133 if (ioctl(ctl, HCIGETDEVINFO, (void *)&di) < 0) Err bitreich.org 70 i 134 continue; Err bitreich.org 70 i 135 Err bitreich.org 70 i 136 if (_adv_available(&di) == 0) { Err bitreich.org 70 i 137 result = 0; Err bitreich.org 70 i 138 goto CLEAN_UP_RETURN; Err bitreich.org 70 i 139 } Err bitreich.org 70 i 140 } Err bitreich.org 70 i 141 Err bitreich.org 70 i 142 CLEAN_UP_RETURN: Err bitreich.org 70 i 143 close(ctl); Err bitreich.org 70 i 144 free(dl); Err bitreich.org 70 i 145 Err bitreich.org 70 i 146 return result; Err bitreich.org 70 i 147 } Err bitreich.org 70 i 148 Err bitreich.org 70 i 149 int Err bitreich.org 70 i 150 adv_available(int sock) Err bitreich.org 70 i 151 { Err bitreich.org 70 i 152 bdaddr_t ba = {{0, }}; Err bitreich.org 70 i 153 struct sockaddr addr = {0, }; Err bitreich.org 70 i 154 int dev_id = -1; Err bitreich.org 70 i 155 socklen_t alen = sizeof(addr); Err bitreich.org 70 i 156 struct sockaddr_rc const *addr_rc = (struct sockaddr_rc const *)&addr; Err bitreich.org 70 i 157 struct hci_dev_info di; Err bitreich.org 70 i 158 Err bitreich.org 70 i 159 if (getsockname(sock, &addr, &alen) < 0) Err bitreich.org 70 i 160 return -1; Err bitreich.org 70 i 161 Err bitreich.org 70 i 162 ba = addr_rc->rc_bdaddr; Err bitreich.org 70 i 163 Err bitreich.org 70 i 164 if (bacmp(&ba, BDADDR_ANY) == 0) { Err bitreich.org 70 i 165 dev_id = -1; Err bitreich.org 70 i 166 } else { Err bitreich.org 70 i 167 dev_id = hci_get_route(&ba); Err bitreich.org 70 i 168 } Err bitreich.org 70 i 169 Err bitreich.org 70 i 170 if (dev_id == -1) { Err bitreich.org 70 i 171 return _any_adv_available(); Err bitreich.org 70 i 172 } else { Err bitreich.org 70 i 173 if (hci_devinfo(dev_id, &di)) Err bitreich.org 70 i 174 return -1; Err bitreich.org 70 i 175 return _adv_available(&di); Err bitreich.org 70 i 176 } Err bitreich.org 70 i 177 } Err bitreich.org 70 i 178 Err bitreich.org 70 i 179 int Err bitreich.org 70 i 180 str2uuid(char *uuidstr, uuid_t *uuid) Err bitreich.org 70 i 181 { Err bitreich.org 70 i 182 uint32_t uuid_int[4]; Err bitreich.org 70 i 183 int i; Err bitreich.org 70 i 184 char *endptr, buf[9] = { 0 }; Err bitreich.org 70 i 185 Err bitreich.org 70 i 186 if (strlen(uuidstr) == 36) { Err bitreich.org 70 i 187 if (uuidstr[8] != '-' && uuidstr[13] != '-' && Err bitreich.org 70 i 188 uuidstr[18] != '-' && uuidstr[23] != '-') { Err bitreich.org 70 i 189 return 1; Err bitreich.org 70 i 190 } Err bitreich.org 70 i 191 Err bitreich.org 70 i 192 strncpy(buf, uuidstr, 8); Err bitreich.org 70 i 193 uuid_int[0] = htonl(strtoul(buf, &endptr, 16)); Err bitreich.org 70 i 194 if (endptr != buf+8) Err bitreich.org 70 i 195 return 1; Err bitreich.org 70 i 196 Err bitreich.org 70 i 197 strncpy(buf, uuidstr+9, 4); Err bitreich.org 70 i 198 strncpy(buf+4, uuidstr+14, 4); Err bitreich.org 70 i 199 uuid_int[1] = htonl(strtoul(buf, &endptr, 16)); Err bitreich.org 70 i 200 if (endptr != buf+8) Err bitreich.org 70 i 201 return 1; Err bitreich.org 70 i 202 Err bitreich.org 70 i 203 strncpy(buf, uuidstr+19, 4); Err bitreich.org 70 i 204 strncpy(buf+4, uuidstr+24, 4); Err bitreich.org 70 i 205 uuid_int[2] = htonl(strtoul(buf, &endptr, 16)); Err bitreich.org 70 i 206 if (endptr != buf+8) Err bitreich.org 70 i 207 return 1; Err bitreich.org 70 i 208 Err bitreich.org 70 i 209 strncpy(buf, uuidstr+28, 4); Err bitreich.org 70 i 210 uuid_int[3] = htonl(strtoul(buf, &endptr, 16)); Err bitreich.org 70 i 211 if (endptr != buf+8) Err bitreich.org 70 i 212 return 1; Err bitreich.org 70 i 213 Err bitreich.org 70 i 214 if (uuid != NULL) Err bitreich.org 70 i 215 sdp_uuid128_create(uuid, uuid_int); Err bitreich.org 70 i 216 } else if (strlen(uuidstr) == 8) { Err bitreich.org 70 i 217 uuid_int[0] = strtoul(uuidstr, &endptr, 16); Err bitreich.org 70 i 218 if (endptr != uuidstr+8) Err bitreich.org 70 i 219 return 1; Err bitreich.org 70 i 220 if (uuid != NULL) Err bitreich.org 70 i 221 sdp_uuid32_create(uuid, uuid_int[0]); Err bitreich.org 70 i 222 } else if (strlen(uuidstr) == 4) { Err bitreich.org 70 i 223 i = strtol(uuidstr, &endptr, 16); Err bitreich.org 70 i 224 if (endptr != uuidstr+4) Err bitreich.org 70 i 225 return 1; Err bitreich.org 70 i 226 if (uuid != NULL) Err bitreich.org 70 i 227 sdp_uuid16_create(uuid, i); Err bitreich.org 70 i 228 } else { Err bitreich.org 70 i 229 return 1; Err bitreich.org 70 i 230 } Err bitreich.org 70 i 231 Err bitreich.org 70 i 232 return 0; Err bitreich.org 70 i 233 } Err bitreich.org 70 i 234 Err bitreich.org 70 i 235 int Err bitreich.org 70 i 236 sdp_advertise_service(int sock, char *svcname, Err bitreich.org 70 i 237 char *svcid, int svc_class, int profiles, Err bitreich.org 70 i 238 char *svcprovider, char *svcdescription) Err bitreich.org 70 i 239 { Err bitreich.org 70 i 240 char addrbuf[256]; Err bitreich.org 70 i 241 int res, err = 0; Err bitreich.org 70 i 242 struct sockaddr *sockaddr; Err bitreich.org 70 i 243 uuid_t root_uuid, l2cap_uuid, rfcomm_uuid, svc_class_uuid, Err bitreich.org 70 i 244 svc_uuid; Err bitreich.org 70 i 245 sdp_profile_desc_t *profile_desc; Err bitreich.org 70 i 246 sdp_list_t *l2cap_list = NULL, *rfcomm_list = NULL, *root_list = NULL, Err bitreich.org 70 i 247 *proto_list = NULL, *profile_list = NULL, Err bitreich.org 70 i 248 *svc_class_list = NULL, *access_proto_list = NULL; Err bitreich.org 70 i 249 sdp_data_t *channel = 0; Err bitreich.org 70 i 250 sdp_record_t record; Err bitreich.org 70 i 251 sdp_session_t *session = 0; Err bitreich.org 70 i 252 uint8_t rfcomm_channel; Err bitreich.org 70 i 253 socklen_t addrlen = sizeof(struct sockaddr_rc); Err bitreich.org 70 i 254 Err bitreich.org 70 i 255 str2uuid(svcid, &svc_uuid); Err bitreich.org 70 i 256 sdp_uuid16_create(&svc_class_uuid, svc_class); Err bitreich.org 70 i 257 Err bitreich.org 70 i 258 memset(addrbuf, 0, sizeof(addrbuf)); Err bitreich.org 70 i 259 Err bitreich.org 70 i 260 if (adv_available(sock) < 0) Err bitreich.org 70 i 261 return -1; Err bitreich.org 70 i 262 Err bitreich.org 70 i 263 res = getsockname(sock, (struct sockaddr *)addrbuf, &addrlen); Err bitreich.org 70 i 264 if (res < 0) Err bitreich.org 70 i 265 return -1; Err bitreich.org 70 i 266 sockaddr = (struct sockaddr *)addrbuf; Err bitreich.org 70 i 267 Err bitreich.org 70 i 268 memset(&record, 0, sizeof(record)); Err bitreich.org 70 i 269 memset(&record.handle, 0xff, sizeof(record.handle)); Err bitreich.org 70 i 270 Err bitreich.org 70 i 271 sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); Err bitreich.org 70 i 272 root_list = sdp_list_append(0, &root_uuid); Err bitreich.org 70 i 273 sdp_set_browse_groups(&record, root_list); Err bitreich.org 70 i 274 sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); Err bitreich.org 70 i 275 l2cap_list = sdp_list_append(0, &l2cap_uuid); Err bitreich.org 70 i 276 proto_list = sdp_list_append(0, l2cap_list); Err bitreich.org 70 i 277 rfcomm_channel = ((struct sockaddr_rc *)sockaddr)->rc_channel; Err bitreich.org 70 i 278 sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); Err bitreich.org 70 i 279 channel = sdp_data_alloc(SDP_UINT8, &rfcomm_channel); Err bitreich.org 70 i 280 rfcomm_list = sdp_list_append(0, &rfcomm_uuid); Err bitreich.org 70 i 281 sdp_list_append(rfcomm_list, channel); Err bitreich.org 70 i 282 sdp_list_append(proto_list, rfcomm_list); Err bitreich.org 70 i 283 access_proto_list = sdp_list_append(0, proto_list); Err bitreich.org 70 i 284 sdp_set_access_protos(&record, access_proto_list); Err bitreich.org 70 i 285 svc_class_list = sdp_list_append(svc_class_list, &svc_class_uuid); Err bitreich.org 70 i 286 sdp_set_service_classes(&record, svc_class_list); Err bitreich.org 70 i 287 Err bitreich.org 70 i 288 profile_desc = (sdp_profile_desc_t *)malloc(sizeof(sdp_profile_desc_t)); Err bitreich.org 70 i 289 if (profile_desc == NULL) Err bitreich.org 70 i 290 return -1; Err bitreich.org 70 i 291 sdp_uuid16_create(&profile_desc->uuid, profiles); Err bitreich.org 70 i 292 profile_list = sdp_list_append(profile_list, profile_desc); Err bitreich.org 70 i 293 sdp_set_profile_descs(&record, profile_list); Err bitreich.org 70 i 294 Err bitreich.org 70 i 295 sdp_set_info_attr(&record, svcname, svcprovider, svcdescription); Err bitreich.org 70 i 296 sdp_set_service_id(&record, svc_uuid); Err bitreich.org 70 i 297 Err bitreich.org 70 i 298 session = sdp_connect(BDADDR_ANY, BDADDR_LOCAL, 0); Err bitreich.org 70 i 299 if (!session) Err bitreich.org 70 i 300 return -1; Err bitreich.org 70 i 301 err = sdp_record_register(session, &record, 0); Err bitreich.org 70 i 302 Err bitreich.org 70 i 303 if (channel) Err bitreich.org 70 i 304 sdp_data_free(channel); Err bitreich.org 70 i 305 sdp_list_free(l2cap_list, 0); Err bitreich.org 70 i 306 sdp_list_free(rfcomm_list, 0); Err bitreich.org 70 i 307 sdp_list_free(root_list, 0); Err bitreich.org 70 i 308 sdp_list_free(access_proto_list, 0); Err bitreich.org 70 i 309 sdp_list_free(svc_class_list, 0); Err bitreich.org 70 i 310 sdp_list_free(profile_list, free); Err bitreich.org 70 i 311 Err bitreich.org 70 i 312 if (err) Err bitreich.org 70 i 313 return -1; Err bitreich.org 70 i 314 Err bitreich.org 70 i 315 return 0; Err bitreich.org 70 i 316 } Err bitreich.org 70 i 317 Err bitreich.org 70 i 318 void Err bitreich.org 70 i 319 usage(char *argv0) Err bitreich.org 70 i 320 { Err bitreich.org 70 i 321 fprintf(stderr, "%s [-dhrAESM] [-i hciX|bdaddr] [-L linger] [-c channel] [-f filter cmd] [cmd]\n", Err bitreich.org 70 i 322 basename(argv0)); Err bitreich.org 70 i 323 exit(1); Err bitreich.org 70 i 324 } Err bitreich.org 70 i 325 Err bitreich.org 70 i 326 int Err bitreich.org 70 i 327 main(int argc, char *argv[]) Err bitreich.org 70 i 328 { Err bitreich.org 70 i 329 int rfcomm_raw_tty = 0, auth = 0, encryption = 0, Err bitreich.org 70 i 330 secure = 0, master = 0, linger = 0, sk, nsk, fd, lm , try = 30, Err bitreich.org 70 i 331 ctl, rc_channel = 1, filteri, dev; Err bitreich.org 70 i 332 char *argv0, *optarg, dst[18], devname[MAXPATHLEN], *replace, Err bitreich.org 70 i 333 *cmd, *oldcmd, *defaultcmd = NULL, *runcmd; Err bitreich.org 70 i 334 struct sockaddr_rc laddr, raddr; Err bitreich.org 70 i 335 struct rfcomm_dev_req req; Err bitreich.org 70 i 336 struct termios ti; Err bitreich.org 70 i 337 socklen_t alen; Err bitreich.org 70 i 338 bdaddr_t bdaddr; Err bitreich.org 70 i 339 struct linger l; Err bitreich.org 70 i 340 Err bitreich.org 70 i 341 char **cmds = NULL; Err bitreich.org 70 i 342 char **filteraddrs = NULL; Err bitreich.org 70 i 343 bdaddr_t **filterbds = NULL; Err bitreich.org 70 i 344 int filtern = 0; Err bitreich.org 70 i 345 Err bitreich.org 70 i 346 bacpy(&bdaddr, BDADDR_ANY); Err bitreich.org 70 i 347 Err bitreich.org 70 i 348 ARGBEGIN(argv0) { Err bitreich.org 70 i 349 case 'c': Err bitreich.org 70 i 350 rc_channel = atoi(EARGF(usage(argv0))); Err bitreich.org 70 i 351 break; Err bitreich.org 70 i 352 case 'd': Err bitreich.org 70 i 353 dodebug = 1; Err bitreich.org 70 i 354 break; Err bitreich.org 70 i 355 case 'i': Err bitreich.org 70 i 356 optarg = EARGF(usage(argv0)); Err bitreich.org 70 i 357 if (strncmp(optarg, "hci", 3) == 0) { Err bitreich.org 70 i 358 hci_devba(atoi(optarg + 3), &bdaddr); Err bitreich.org 70 i 359 } else { Err bitreich.org 70 i 360 str2ba(optarg, &bdaddr); Err bitreich.org 70 i 361 } Err bitreich.org 70 i 362 break; Err bitreich.org 70 i 363 case 'f': Err bitreich.org 70 i 364 ++filtern; Err bitreich.org 70 i 365 filteraddrs = realloc(filteraddrs, Err bitreich.org 70 i 366 filtern * sizeof(*filteraddrs)); Err bitreich.org 70 i 367 if (filteraddrs == NULL) Err bitreich.org 70 i 368 exit(1); Err bitreich.org 70 i 369 Err bitreich.org 70 i 370 cmds = realloc(cmds, filtern * sizeof(*cmds)); Err bitreich.org 70 i 371 if (cmds == NULL) Err bitreich.org 70 i 372 exit(1); Err bitreich.org 70 i 373 Err bitreich.org 70 i 374 filterbds = realloc(filterbds, filtern * sizeof(*filterbds)); Err bitreich.org 70 i 375 if (filterbds == NULL) Err bitreich.org 70 i 376 exit(1); Err bitreich.org 70 i 377 Err bitreich.org 70 i 378 filteraddrs[filtern-1] = EARGF(usage(argv0)); Err bitreich.org 70 i 379 argv++, argc--; Err bitreich.org 70 i 380 if (argc <= 0) Err bitreich.org 70 i 381 usage(argv0); Err bitreich.org 70 i 382 cmds[filtern-1] = argv[0]; Err bitreich.org 70 i 383 Err bitreich.org 70 i 384 filterbds[filtern-1] = malloc(sizeof(*filterbds)); Err bitreich.org 70 i 385 if (filterbds[filtern-1] == NULL) Err bitreich.org 70 i 386 exit(1); Err bitreich.org 70 i 387 str2ba(filteraddrs[filtern-1], filterbds[filtern-1]); Err bitreich.org 70 i 388 break; Err bitreich.org 70 i 389 case 'r': Err bitreich.org 70 i 390 rfcomm_raw_tty = 1; Err bitreich.org 70 i 391 break; Err bitreich.org 70 i 392 case 'A': Err bitreich.org 70 i 393 auth = 1; Err bitreich.org 70 i 394 break; Err bitreich.org 70 i 395 case 'E': Err bitreich.org 70 i 396 encryption = 1; Err bitreich.org 70 i 397 break; Err bitreich.org 70 i 398 case 'S': Err bitreich.org 70 i 399 secure = 1; Err bitreich.org 70 i 400 break; Err bitreich.org 70 i 401 case 'M': Err bitreich.org 70 i 402 master = 1; Err bitreich.org 70 i 403 break; Err bitreich.org 70 i 404 case 'L': Err bitreich.org 70 i 405 linger = atoi(EARGF(usage(argv0))); Err bitreich.org 70 i 406 break; Err bitreich.org 70 i 407 case 'h': Err bitreich.org 70 i 408 default: Err bitreich.org 70 i 409 usage(argv0); Err bitreich.org 70 i 410 } ARGEND; Err bitreich.org 70 i 411 Err bitreich.org 70 i 412 if (argc > 0) Err bitreich.org 70 i 413 defaultcmd = argv[0]; Err bitreich.org 70 i 414 if (defaultcmd == NULL && filtern < 0) Err bitreich.org 70 i 415 usage(argv[0]); Err bitreich.org 70 i 416 Err bitreich.org 70 i 417 for (filteri = 0; filteri < filtern; filteri++) { Err bitreich.org 70 i 418 ba2str(filterbds[filteri], dst); Err bitreich.org 70 i 419 debug("filter: %s (%s) -> %s\n", Err bitreich.org 70 i 420 filteraddrs[filteri], dst, cmds[filteri]); Err bitreich.org 70 i 421 } Err bitreich.org 70 i 422 debug("defaultcmd: %s\n", defaultcmd); Err bitreich.org 70 i 423 Err bitreich.org 70 i 424 setup_signals(); Err bitreich.org 70 i 425 Err bitreich.org 70 i 426 ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_RFCOMM); Err bitreich.org 70 i 427 if (ctl < 0) { Err bitreich.org 70 i 428 perror("Can't open RFCOMM control socket"); Err bitreich.org 70 i 429 return 1; Err bitreich.org 70 i 430 } Err bitreich.org 70 i 431 Err bitreich.org 70 i 432 laddr.rc_family = AF_BLUETOOTH; Err bitreich.org 70 i 433 bacpy(&laddr.rc_bdaddr, &bdaddr); Err bitreich.org 70 i 434 laddr.rc_channel = rc_channel; Err bitreich.org 70 i 435 Err bitreich.org 70 i 436 sk = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); Err bitreich.org 70 i 437 if (sk < 0) { Err bitreich.org 70 i 438 perror("Can't create RFCOMM socket"); Err bitreich.org 70 i 439 return 1; Err bitreich.org 70 i 440 } Err bitreich.org 70 i 441 Err bitreich.org 70 i 442 lm = 0; Err bitreich.org 70 i 443 if (master) Err bitreich.org 70 i 444 lm |= RFCOMM_LM_MASTER; Err bitreich.org 70 i 445 if (auth) Err bitreich.org 70 i 446 lm |= RFCOMM_LM_AUTH; Err bitreich.org 70 i 447 if (encryption) Err bitreich.org 70 i 448 lm |= RFCOMM_LM_ENCRYPT; Err bitreich.org 70 i 449 if (secure) Err bitreich.org 70 i 450 lm |= RFCOMM_LM_SECURE; Err bitreich.org 70 i 451 Err bitreich.org 70 i 452 if (lm && setsockopt(sk, SOL_RFCOMM, RFCOMM_LM, &lm, sizeof(lm)) < 0) { Err bitreich.org 70 i 453 perror("Can't set RFCOMM link mode"); Err bitreich.org 70 i 454 close(sk); Err bitreich.org 70 i 455 return 1; Err bitreich.org 70 i 456 } Err bitreich.org 70 i 457 Err bitreich.org 70 i 458 if (bind(sk, (struct sockaddr *)&laddr, sizeof(laddr)) < 0) { Err bitreich.org 70 i 459 perror("Can't bind RFCOMM socket"); Err bitreich.org 70 i 460 close(sk); Err bitreich.org 70 i 461 return 1; Err bitreich.org 70 i 462 } Err bitreich.org 70 i 463 Err bitreich.org 70 i 464 debug("Waiting for connection on channel %d\n", laddr.rc_channel); Err bitreich.org 70 i 465 Err bitreich.org 70 i 466 listen(sk, 10); Err bitreich.org 70 i 467 Err bitreich.org 70 i 468 sdp_advertise_service(sk, Err bitreich.org 70 i 469 "SPP Printer", Err bitreich.org 70 i 470 "00001101-0000-1000-8000-00805F9B34FB", Err bitreich.org 70 i 471 SERIAL_PORT_SVCLASS_ID, Err bitreich.org 70 i 472 SERIAL_PORT_PROFILE_ID, Err bitreich.org 70 i 473 "SPP Printer Emulation", Err bitreich.org 70 i 474 "rfcommd"); Err bitreich.org 70 i 475 Err bitreich.org 70 i 476 while (!__io_canceled) { Err bitreich.org 70 i 477 alen = sizeof(raddr); Err bitreich.org 70 i 478 nsk = accept(sk, (struct sockaddr *)&raddr, &alen); Err bitreich.org 70 i 479 Err bitreich.org 70 i 480 if (fork() != 0) Err bitreich.org 70 i 481 continue; Err bitreich.org 70 i 482 Err bitreich.org 70 i 483 ba2str(&raddr.rc_bdaddr, dst); Err bitreich.org 70 i 484 debug("Accept from %s\n", dst); Err bitreich.org 70 i 485 Err bitreich.org 70 i 486 for (filteri = 0; filteri < filtern; filteri++) { Err bitreich.org 70 i 487 if (!bacmp(filterbds[filteri], &raddr.rc_bdaddr)) { Err bitreich.org 70 i 488 runcmd = cmds[filteri]; Err bitreich.org 70 i 489 debug("filter found: %s -> %s\n", Err bitreich.org 70 i 490 filteraddrs[filteri], Err bitreich.org 70 i 491 runcmd); Err bitreich.org 70 i 492 break; Err bitreich.org 70 i 493 } Err bitreich.org 70 i 494 } Err bitreich.org 70 i 495 if (filteri >= filtern) { Err bitreich.org 70 i 496 if (defaultcmd != NULL) { Err bitreich.org 70 i 497 debug("running defaultcmd = %s\n", Err bitreich.org 70 i 498 defaultcmd); Err bitreich.org 70 i 499 runcmd = defaultcmd; Err bitreich.org 70 i 500 } else { Err bitreich.org 70 i 501 close(nsk); Err bitreich.org 70 i 502 continue; Err bitreich.org 70 i 503 } Err bitreich.org 70 i 504 } Err bitreich.org 70 i 505 Err bitreich.org 70 i 506 alen = sizeof(laddr); Err bitreich.org 70 i 507 if (getsockname(nsk, (struct sockaddr *)&laddr, &alen) < 0) { Err bitreich.org 70 i 508 perror("Can't get RFCOMM socket name"); Err bitreich.org 70 i 509 close(nsk); Err bitreich.org 70 i 510 continue; Err bitreich.org 70 i 511 } Err bitreich.org 70 i 512 Err bitreich.org 70 i 513 if (linger) { Err bitreich.org 70 i 514 l.l_onoff = 1; Err bitreich.org 70 i 515 l.l_linger = linger; Err bitreich.org 70 i 516 Err bitreich.org 70 i 517 if (setsockopt(nsk, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) { Err bitreich.org 70 i 518 perror("Can't set linger option"); Err bitreich.org 70 i 519 close(nsk); Err bitreich.org 70 i 520 continue; Err bitreich.org 70 i 521 } Err bitreich.org 70 i 522 } Err bitreich.org 70 i 523 Err bitreich.org 70 i 524 memset(&req, 0, sizeof(req)); Err bitreich.org 70 i 525 req.dev_id = -1; Err bitreich.org 70 i 526 req.flags = (1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP); Err bitreich.org 70 i 527 Err bitreich.org 70 i 528 bacpy(&req.src, &laddr.rc_bdaddr); Err bitreich.org 70 i 529 bacpy(&req.dst, &raddr.rc_bdaddr); Err bitreich.org 70 i 530 req.channel = raddr.rc_channel; Err bitreich.org 70 i 531 Err bitreich.org 70 i 532 dev = ioctl(nsk, RFCOMMCREATEDEV, &req); Err bitreich.org 70 i 533 if (dev < 0) { Err bitreich.org 70 i 534 perror("Can't create RFCOMM TTY"); Err bitreich.org 70 i 535 close(sk); Err bitreich.org 70 i 536 continue; Err bitreich.org 70 i 537 } Err bitreich.org 70 i 538 Err bitreich.org 70 i 539 snprintf(devname, MAXPATHLEN - 1, "/dev/rfcomm%d", dev); Err bitreich.org 70 i 540 while ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) { Err bitreich.org 70 i 541 if (errno == EACCES) { Err bitreich.org 70 i 542 perror("Can't open RFCOMM device"); Err bitreich.org 70 i 543 goto release; Err bitreich.org 70 i 544 } Err bitreich.org 70 i 545 Err bitreich.org 70 i 546 snprintf(devname, MAXPATHLEN - 1, "/dev/bluetooth/rfcomm/%d", dev); Err bitreich.org 70 i 547 if ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) { Err bitreich.org 70 i 548 if (try--) { Err bitreich.org 70 i 549 snprintf(devname, MAXPATHLEN - 1, "/dev/rfcomm%d", dev); Err bitreich.org 70 i 550 usleep(100 * 1000); Err bitreich.org 70 i 551 continue; Err bitreich.org 70 i 552 } Err bitreich.org 70 i 553 perror("Can't open RFCOMM device"); Err bitreich.org 70 i 554 goto release; Err bitreich.org 70 i 555 } Err bitreich.org 70 i 556 } Err bitreich.org 70 i 557 Err bitreich.org 70 i 558 if (rfcomm_raw_tty) { Err bitreich.org 70 i 559 tcflush(fd, TCIOFLUSH); Err bitreich.org 70 i 560 Err bitreich.org 70 i 561 cfmakeraw(&ti); Err bitreich.org 70 i 562 tcsetattr(fd, TCSANOW, &ti); Err bitreich.org 70 i 563 } Err bitreich.org 70 i 564 Err bitreich.org 70 i 565 ba2str(&req.dst, dst); Err bitreich.org 70 i 566 debug("Connection from %s to %s\n", dst, devname); Err bitreich.org 70 i 567 Err bitreich.org 70 i 568 /* Replace all occurences of '{}' with the rfcomm device path. */ Err bitreich.org 70 i 569 asprintf(&oldcmd, "%s", runcmd); Err bitreich.org 70 i 570 while ((replace = strstr(oldcmd, "{}"))) { Err bitreich.org 70 i 571 replace[0] = '%'; Err bitreich.org 70 i 572 replace[1] = 's'; Err bitreich.org 70 i 573 asprintf(&cmd, oldcmd, devname); Err bitreich.org 70 i 574 free(oldcmd); Err bitreich.org 70 i 575 oldcmd = cmd; Err bitreich.org 70 i 576 } Err bitreich.org 70 i 577 Err bitreich.org 70 i 578 debug("Executing %s\n", cmd); Err bitreich.org 70 i 579 Err bitreich.org 70 i 580 system(cmd); Err bitreich.org 70 i 581 free(cmd); Err bitreich.org 70 i 582 Err bitreich.org 70 i 583 close(fd); Err bitreich.org 70 i 584 close(nsk); Err bitreich.org 70 i 585 release: Err bitreich.org 70 i 586 memset(&req, 0, sizeof(req)); Err bitreich.org 70 i 587 req.dev_id = dev; Err bitreich.org 70 i 588 req.flags = (1 << RFCOMM_HANGUP_NOW); Err bitreich.org 70 i 589 ioctl(ctl, RFCOMMRELEASEDEV, &req); Err bitreich.org 70 i 590 } Err bitreich.org 70 i 591 Err bitreich.org 70 i 592 close(sk); Err bitreich.org 70 i 593 Err bitreich.org 70 i 594 return 0; Err bitreich.org 70 i 595 } Err bitreich.org 70 i 596 Err bitreich.org 70 .