1255e72915d4cbddceb435e13d81601755714e9fSE Android#include <stdlib.h> 2255e72915d4cbddceb435e13d81601755714e9fSE Android#include <string.h> 3255e72915d4cbddceb435e13d81601755714e9fSE Android 4255e72915d4cbddceb435e13d81601755714e9fSE Android#include "port_internal.h" 5255e72915d4cbddceb435e13d81601755714e9fSE Android#include "context_internal.h" 6255e72915d4cbddceb435e13d81601755714e9fSE Android#include "debug.h" 7255e72915d4cbddceb435e13d81601755714e9fSE Android 8255e72915d4cbddceb435e13d81601755714e9fSE Androidstruct sepol_port { 9255e72915d4cbddceb435e13d81601755714e9fSE Android /* Low - High range. Same for single ports. */ 10255e72915d4cbddceb435e13d81601755714e9fSE Android int low, high; 11255e72915d4cbddceb435e13d81601755714e9fSE Android 12255e72915d4cbddceb435e13d81601755714e9fSE Android /* Protocol */ 13255e72915d4cbddceb435e13d81601755714e9fSE Android int proto; 14255e72915d4cbddceb435e13d81601755714e9fSE Android 15255e72915d4cbddceb435e13d81601755714e9fSE Android /* Context */ 16255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_context_t *con; 17255e72915d4cbddceb435e13d81601755714e9fSE Android}; 18255e72915d4cbddceb435e13d81601755714e9fSE Android 19255e72915d4cbddceb435e13d81601755714e9fSE Androidstruct sepol_port_key { 20255e72915d4cbddceb435e13d81601755714e9fSE Android /* Low - High range. Same for single ports. */ 21255e72915d4cbddceb435e13d81601755714e9fSE Android int low, high; 22255e72915d4cbddceb435e13d81601755714e9fSE Android 23255e72915d4cbddceb435e13d81601755714e9fSE Android /* Protocol */ 24255e72915d4cbddceb435e13d81601755714e9fSE Android int proto; 25255e72915d4cbddceb435e13d81601755714e9fSE Android}; 26255e72915d4cbddceb435e13d81601755714e9fSE Android 27255e72915d4cbddceb435e13d81601755714e9fSE Android/* Key */ 28255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_port_key_create(sepol_handle_t * handle, 29255e72915d4cbddceb435e13d81601755714e9fSE Android int low, int high, int proto, 30255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_port_key_t ** key_ptr) 31255e72915d4cbddceb435e13d81601755714e9fSE Android{ 32255e72915d4cbddceb435e13d81601755714e9fSE Android 33255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_port_key_t *tmp_key = 34255e72915d4cbddceb435e13d81601755714e9fSE Android (sepol_port_key_t *) malloc(sizeof(sepol_port_key_t)); 35255e72915d4cbddceb435e13d81601755714e9fSE Android 36255e72915d4cbddceb435e13d81601755714e9fSE Android if (!tmp_key) { 37255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "out of memory, could not create " "port key"); 38255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_ERR; 39255e72915d4cbddceb435e13d81601755714e9fSE Android } 40255e72915d4cbddceb435e13d81601755714e9fSE Android 41255e72915d4cbddceb435e13d81601755714e9fSE Android tmp_key->low = low; 42255e72915d4cbddceb435e13d81601755714e9fSE Android tmp_key->high = high; 43255e72915d4cbddceb435e13d81601755714e9fSE Android tmp_key->proto = proto; 44255e72915d4cbddceb435e13d81601755714e9fSE Android 45255e72915d4cbddceb435e13d81601755714e9fSE Android *key_ptr = tmp_key; 46255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 47255e72915d4cbddceb435e13d81601755714e9fSE Android} 48255e72915d4cbddceb435e13d81601755714e9fSE Android 49255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_port_key_create) 50255e72915d4cbddceb435e13d81601755714e9fSE Android 51255e72915d4cbddceb435e13d81601755714e9fSE Androidvoid sepol_port_key_unpack(const sepol_port_key_t * key, 52255e72915d4cbddceb435e13d81601755714e9fSE Android int *low, int *high, int *proto) 53255e72915d4cbddceb435e13d81601755714e9fSE Android{ 54255e72915d4cbddceb435e13d81601755714e9fSE Android 55255e72915d4cbddceb435e13d81601755714e9fSE Android *low = key->low; 56255e72915d4cbddceb435e13d81601755714e9fSE Android *high = key->high; 57255e72915d4cbddceb435e13d81601755714e9fSE Android *proto = key->proto; 58255e72915d4cbddceb435e13d81601755714e9fSE Android} 59255e72915d4cbddceb435e13d81601755714e9fSE Android 60255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_port_key_unpack) 61255e72915d4cbddceb435e13d81601755714e9fSE Android 62255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_port_key_extract(sepol_handle_t * handle, 63255e72915d4cbddceb435e13d81601755714e9fSE Android const sepol_port_t * port, 64255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_port_key_t ** key_ptr) 65255e72915d4cbddceb435e13d81601755714e9fSE Android{ 66255e72915d4cbddceb435e13d81601755714e9fSE Android 67255e72915d4cbddceb435e13d81601755714e9fSE Android if (sepol_port_key_create 68255e72915d4cbddceb435e13d81601755714e9fSE Android (handle, port->low, port->high, port->proto, key_ptr) < 0) { 69255e72915d4cbddceb435e13d81601755714e9fSE Android 70255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "could not extract key from port %s %d:%d", 71255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_port_get_proto_str(port->proto), 72255e72915d4cbddceb435e13d81601755714e9fSE Android port->low, port->high); 73255e72915d4cbddceb435e13d81601755714e9fSE Android 74255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_ERR; 75255e72915d4cbddceb435e13d81601755714e9fSE Android } 76255e72915d4cbddceb435e13d81601755714e9fSE Android 77255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 78255e72915d4cbddceb435e13d81601755714e9fSE Android} 79255e72915d4cbddceb435e13d81601755714e9fSE Android 80255e72915d4cbddceb435e13d81601755714e9fSE Androidvoid sepol_port_key_free(sepol_port_key_t * key) 81255e72915d4cbddceb435e13d81601755714e9fSE Android{ 82255e72915d4cbddceb435e13d81601755714e9fSE Android free(key); 83255e72915d4cbddceb435e13d81601755714e9fSE Android} 84255e72915d4cbddceb435e13d81601755714e9fSE Android 85255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_port_compare(const sepol_port_t * port, const sepol_port_key_t * key) 86255e72915d4cbddceb435e13d81601755714e9fSE Android{ 87255e72915d4cbddceb435e13d81601755714e9fSE Android 88255e72915d4cbddceb435e13d81601755714e9fSE Android if ((port->low == key->low) && 89255e72915d4cbddceb435e13d81601755714e9fSE Android (port->high == key->high) && (port->proto == key->proto)) 90255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 91255e72915d4cbddceb435e13d81601755714e9fSE Android 92255e72915d4cbddceb435e13d81601755714e9fSE Android if (port->low < key->low) 93255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 94255e72915d4cbddceb435e13d81601755714e9fSE Android 95255e72915d4cbddceb435e13d81601755714e9fSE Android else if (key->low < port->low) 96255e72915d4cbddceb435e13d81601755714e9fSE Android return 1; 97255e72915d4cbddceb435e13d81601755714e9fSE Android 98255e72915d4cbddceb435e13d81601755714e9fSE Android else if (port->high < key->high) 99255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 100255e72915d4cbddceb435e13d81601755714e9fSE Android 101255e72915d4cbddceb435e13d81601755714e9fSE Android else if (key->high < port->high) 102255e72915d4cbddceb435e13d81601755714e9fSE Android return 1; 103255e72915d4cbddceb435e13d81601755714e9fSE Android 104255e72915d4cbddceb435e13d81601755714e9fSE Android else if (port->proto < key->proto) 105255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 106255e72915d4cbddceb435e13d81601755714e9fSE Android 107255e72915d4cbddceb435e13d81601755714e9fSE Android else 108255e72915d4cbddceb435e13d81601755714e9fSE Android return 1; 109255e72915d4cbddceb435e13d81601755714e9fSE Android} 110255e72915d4cbddceb435e13d81601755714e9fSE Android 111255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_port_compare2(const sepol_port_t * port, const sepol_port_t * port2) 112255e72915d4cbddceb435e13d81601755714e9fSE Android{ 113255e72915d4cbddceb435e13d81601755714e9fSE Android 114255e72915d4cbddceb435e13d81601755714e9fSE Android if ((port->low == port2->low) && 115255e72915d4cbddceb435e13d81601755714e9fSE Android (port->high == port2->high) && (port->proto == port2->proto)) 116255e72915d4cbddceb435e13d81601755714e9fSE Android return 0; 117255e72915d4cbddceb435e13d81601755714e9fSE Android 118255e72915d4cbddceb435e13d81601755714e9fSE Android if (port->low < port2->low) 119255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 120255e72915d4cbddceb435e13d81601755714e9fSE Android 121255e72915d4cbddceb435e13d81601755714e9fSE Android else if (port2->low < port->low) 122255e72915d4cbddceb435e13d81601755714e9fSE Android return 1; 123255e72915d4cbddceb435e13d81601755714e9fSE Android 124255e72915d4cbddceb435e13d81601755714e9fSE Android else if (port->high < port2->high) 125255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 126255e72915d4cbddceb435e13d81601755714e9fSE Android 127255e72915d4cbddceb435e13d81601755714e9fSE Android else if (port2->high < port->high) 128255e72915d4cbddceb435e13d81601755714e9fSE Android return 1; 129255e72915d4cbddceb435e13d81601755714e9fSE Android 130255e72915d4cbddceb435e13d81601755714e9fSE Android else if (port->proto < port2->proto) 131255e72915d4cbddceb435e13d81601755714e9fSE Android return -1; 132255e72915d4cbddceb435e13d81601755714e9fSE Android 133255e72915d4cbddceb435e13d81601755714e9fSE Android else 134255e72915d4cbddceb435e13d81601755714e9fSE Android return 1; 135255e72915d4cbddceb435e13d81601755714e9fSE Android} 136255e72915d4cbddceb435e13d81601755714e9fSE Android 137255e72915d4cbddceb435e13d81601755714e9fSE Android/* Port */ 138255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_port_get_low(const sepol_port_t * port) 139255e72915d4cbddceb435e13d81601755714e9fSE Android{ 140255e72915d4cbddceb435e13d81601755714e9fSE Android 141255e72915d4cbddceb435e13d81601755714e9fSE Android return port->low; 142255e72915d4cbddceb435e13d81601755714e9fSE Android} 143255e72915d4cbddceb435e13d81601755714e9fSE Android 144255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_port_get_low) 145255e72915d4cbddceb435e13d81601755714e9fSE Android 146255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_port_get_high(const sepol_port_t * port) 147255e72915d4cbddceb435e13d81601755714e9fSE Android{ 148255e72915d4cbddceb435e13d81601755714e9fSE Android 149255e72915d4cbddceb435e13d81601755714e9fSE Android return port->high; 150255e72915d4cbddceb435e13d81601755714e9fSE Android} 151255e72915d4cbddceb435e13d81601755714e9fSE Android 152255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_port_get_high) 153255e72915d4cbddceb435e13d81601755714e9fSE Android 154255e72915d4cbddceb435e13d81601755714e9fSE Androidvoid sepol_port_set_port(sepol_port_t * port, int port_num) 155255e72915d4cbddceb435e13d81601755714e9fSE Android{ 156255e72915d4cbddceb435e13d81601755714e9fSE Android 157255e72915d4cbddceb435e13d81601755714e9fSE Android port->low = port_num; 158255e72915d4cbddceb435e13d81601755714e9fSE Android port->high = port_num; 159255e72915d4cbddceb435e13d81601755714e9fSE Android} 160255e72915d4cbddceb435e13d81601755714e9fSE Android 161255e72915d4cbddceb435e13d81601755714e9fSE Androidvoid sepol_port_set_range(sepol_port_t * port, int low, int high) 162255e72915d4cbddceb435e13d81601755714e9fSE Android{ 163255e72915d4cbddceb435e13d81601755714e9fSE Android 164255e72915d4cbddceb435e13d81601755714e9fSE Android port->low = low; 165255e72915d4cbddceb435e13d81601755714e9fSE Android port->high = high; 166255e72915d4cbddceb435e13d81601755714e9fSE Android} 167255e72915d4cbddceb435e13d81601755714e9fSE Android 168255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_port_set_range) 169255e72915d4cbddceb435e13d81601755714e9fSE Android 170255e72915d4cbddceb435e13d81601755714e9fSE Android/* Protocol */ 171255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_port_get_proto(const sepol_port_t * port) 172255e72915d4cbddceb435e13d81601755714e9fSE Android{ 173255e72915d4cbddceb435e13d81601755714e9fSE Android 174255e72915d4cbddceb435e13d81601755714e9fSE Android return port->proto; 175255e72915d4cbddceb435e13d81601755714e9fSE Android} 176255e72915d4cbddceb435e13d81601755714e9fSE Android 177255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_port_get_proto) 178255e72915d4cbddceb435e13d81601755714e9fSE Android 179255e72915d4cbddceb435e13d81601755714e9fSE Androidconst char *sepol_port_get_proto_str(int proto) 180255e72915d4cbddceb435e13d81601755714e9fSE Android{ 181255e72915d4cbddceb435e13d81601755714e9fSE Android 182255e72915d4cbddceb435e13d81601755714e9fSE Android switch (proto) { 183255e72915d4cbddceb435e13d81601755714e9fSE Android case SEPOL_PROTO_UDP: 184255e72915d4cbddceb435e13d81601755714e9fSE Android return "udp"; 185255e72915d4cbddceb435e13d81601755714e9fSE Android case SEPOL_PROTO_TCP: 186255e72915d4cbddceb435e13d81601755714e9fSE Android return "tcp"; 187255e72915d4cbddceb435e13d81601755714e9fSE Android default: 188255e72915d4cbddceb435e13d81601755714e9fSE Android return "???"; 189255e72915d4cbddceb435e13d81601755714e9fSE Android } 190255e72915d4cbddceb435e13d81601755714e9fSE Android} 191255e72915d4cbddceb435e13d81601755714e9fSE Android 192255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_port_get_proto_str) 193255e72915d4cbddceb435e13d81601755714e9fSE Android 194255e72915d4cbddceb435e13d81601755714e9fSE Androidvoid sepol_port_set_proto(sepol_port_t * port, int proto) 195255e72915d4cbddceb435e13d81601755714e9fSE Android{ 196255e72915d4cbddceb435e13d81601755714e9fSE Android 197255e72915d4cbddceb435e13d81601755714e9fSE Android port->proto = proto; 198255e72915d4cbddceb435e13d81601755714e9fSE Android} 199255e72915d4cbddceb435e13d81601755714e9fSE Android 200255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_port_set_proto) 201255e72915d4cbddceb435e13d81601755714e9fSE Android 202255e72915d4cbddceb435e13d81601755714e9fSE Android/* Create */ 203255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_port_create(sepol_handle_t * handle, sepol_port_t ** port) 204255e72915d4cbddceb435e13d81601755714e9fSE Android{ 205255e72915d4cbddceb435e13d81601755714e9fSE Android 206255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_port_t *tmp_port = (sepol_port_t *) malloc(sizeof(sepol_port_t)); 207255e72915d4cbddceb435e13d81601755714e9fSE Android 208255e72915d4cbddceb435e13d81601755714e9fSE Android if (!tmp_port) { 209255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "out of memory, could not create " "port record"); 210255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_ERR; 211255e72915d4cbddceb435e13d81601755714e9fSE Android } 212255e72915d4cbddceb435e13d81601755714e9fSE Android 213255e72915d4cbddceb435e13d81601755714e9fSE Android tmp_port->low = 0; 214255e72915d4cbddceb435e13d81601755714e9fSE Android tmp_port->high = 0; 215255e72915d4cbddceb435e13d81601755714e9fSE Android tmp_port->proto = SEPOL_PROTO_UDP; 216255e72915d4cbddceb435e13d81601755714e9fSE Android tmp_port->con = NULL; 217255e72915d4cbddceb435e13d81601755714e9fSE Android *port = tmp_port; 218255e72915d4cbddceb435e13d81601755714e9fSE Android 219255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 220255e72915d4cbddceb435e13d81601755714e9fSE Android} 221255e72915d4cbddceb435e13d81601755714e9fSE Android 222255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_port_create) 223255e72915d4cbddceb435e13d81601755714e9fSE Android 224255e72915d4cbddceb435e13d81601755714e9fSE Android/* Deep copy clone */ 225255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_port_clone(sepol_handle_t * handle, 226255e72915d4cbddceb435e13d81601755714e9fSE Android const sepol_port_t * port, sepol_port_t ** port_ptr) 227255e72915d4cbddceb435e13d81601755714e9fSE Android{ 228255e72915d4cbddceb435e13d81601755714e9fSE Android 229255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_port_t *new_port = NULL; 230255e72915d4cbddceb435e13d81601755714e9fSE Android if (sepol_port_create(handle, &new_port) < 0) 231255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 232255e72915d4cbddceb435e13d81601755714e9fSE Android 233255e72915d4cbddceb435e13d81601755714e9fSE Android new_port->low = port->low; 234255e72915d4cbddceb435e13d81601755714e9fSE Android new_port->high = port->high; 235255e72915d4cbddceb435e13d81601755714e9fSE Android new_port->proto = port->proto; 236255e72915d4cbddceb435e13d81601755714e9fSE Android 237255e72915d4cbddceb435e13d81601755714e9fSE Android if (port->con && 238255e72915d4cbddceb435e13d81601755714e9fSE Android (sepol_context_clone(handle, port->con, &new_port->con) < 0)) 239255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 240255e72915d4cbddceb435e13d81601755714e9fSE Android 241255e72915d4cbddceb435e13d81601755714e9fSE Android *port_ptr = new_port; 242255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 243255e72915d4cbddceb435e13d81601755714e9fSE Android 244255e72915d4cbddceb435e13d81601755714e9fSE Android err: 245255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "could not clone port record"); 246255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_port_free(new_port); 247255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_ERR; 248255e72915d4cbddceb435e13d81601755714e9fSE Android} 249255e72915d4cbddceb435e13d81601755714e9fSE Android 250255e72915d4cbddceb435e13d81601755714e9fSE Android/* Destroy */ 251255e72915d4cbddceb435e13d81601755714e9fSE Androidvoid sepol_port_free(sepol_port_t * port) 252255e72915d4cbddceb435e13d81601755714e9fSE Android{ 253255e72915d4cbddceb435e13d81601755714e9fSE Android 254255e72915d4cbddceb435e13d81601755714e9fSE Android if (!port) 255255e72915d4cbddceb435e13d81601755714e9fSE Android return; 256255e72915d4cbddceb435e13d81601755714e9fSE Android 257255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_context_free(port->con); 258255e72915d4cbddceb435e13d81601755714e9fSE Android free(port); 259255e72915d4cbddceb435e13d81601755714e9fSE Android} 260255e72915d4cbddceb435e13d81601755714e9fSE Android 261255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_port_free) 262255e72915d4cbddceb435e13d81601755714e9fSE Android 263255e72915d4cbddceb435e13d81601755714e9fSE Android/* Context */ 264255e72915d4cbddceb435e13d81601755714e9fSE Androidsepol_context_t *sepol_port_get_con(const sepol_port_t * port) 265255e72915d4cbddceb435e13d81601755714e9fSE Android{ 266255e72915d4cbddceb435e13d81601755714e9fSE Android 267255e72915d4cbddceb435e13d81601755714e9fSE Android return port->con; 268255e72915d4cbddceb435e13d81601755714e9fSE Android} 269255e72915d4cbddceb435e13d81601755714e9fSE Android 270255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_port_get_con) 271255e72915d4cbddceb435e13d81601755714e9fSE Android 272255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_port_set_con(sepol_handle_t * handle, 273255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_port_t * port, sepol_context_t * con) 274255e72915d4cbddceb435e13d81601755714e9fSE Android{ 275255e72915d4cbddceb435e13d81601755714e9fSE Android 276255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_context_t *newcon; 277255e72915d4cbddceb435e13d81601755714e9fSE Android 278255e72915d4cbddceb435e13d81601755714e9fSE Android if (sepol_context_clone(handle, con, &newcon) < 0) { 279255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "out of memory, could not set port context"); 280255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_ERR; 281255e72915d4cbddceb435e13d81601755714e9fSE Android } 282255e72915d4cbddceb435e13d81601755714e9fSE Android 283255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_context_free(port->con); 284255e72915d4cbddceb435e13d81601755714e9fSE Android port->con = newcon; 285255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 286255e72915d4cbddceb435e13d81601755714e9fSE Android} 287255e72915d4cbddceb435e13d81601755714e9fSE Android 288255e72915d4cbddceb435e13d81601755714e9fSE Androidhidden_def(sepol_port_set_con) 289