static void atr_fn(const char *token, char *value, void *setting, FILE *f) { struct s_reader *rdr = setting; if(value) { memset(rdr->atr, 0, sizeof(rdr->atr)); rdr->atrlen = strlen(value); if(rdr->atrlen) { if(rdr->atrlen > (int32_t)sizeof(rdr->atr) * 2) { rdr->atrlen = (int32_t)sizeof(rdr->atr) * 2; } key_atob_l(value, rdr->atr, rdr->atrlen); } return; } if(rdr->atr[0] || cfg.http_full_cfg) { int j; fprintf_conf(f, token, "%s", ""); // it should not have \n at the end if(rdr->atr[0]) { for(j = 0; j < rdr->atrlen / 2; j++) { fprintf(f, "%02X", rdr->atr[j]); } } fprintf(f, "\n"); } }
static void boxkey_fn(const char *token, char *value, void *setting, FILE *f) { struct s_reader *rdr = setting; if(value) { int32_t len = strlen(value); if(len != 16 && len != 32) { memset(rdr->boxkey, 0, sizeof(rdr->boxkey)); } else { if(key_atob_l(value, rdr->boxkey, len)) { fprintf(stderr, "reader boxkey parse error, %s=%s\n", token, value); memset(rdr->boxkey, 0, sizeof(rdr->boxkey)); } } return; } int32_t len = check_filled(rdr->boxkey, sizeof(rdr->boxkey)); if(len > 0) { if(len > 8) { len = 16; } else { len = 8; } char tmp[len * 2 + 1]; fprintf_conf(f, "boxkey", "%s\n", cs_hexdump(0, rdr->boxkey, len, tmp, sizeof(tmp))); } else if(cfg.http_full_cfg) { fprintf_conf(f, "boxkey", "\n"); } }
static void ins7E_fn(const char *token, char *value, void *setting, long var_size, FILE *f) { uint8_t *var = setting; var_size -= 1; // var_size contains sizeof(var) which is [X + 1] if(value) { int32_t len = strlen(value); if(len != var_size * 2 || key_atob_l(value, var, len)) { if(len > 0) { fprintf(stderr, "reader %s parse error, %s=%s\n", token, token, value); } memset(var, 0, var_size + 1); } else { var[var_size] = 1; // found and correct } return; } if(var[var_size]) { char tmp[var_size * 2 + 1]; fprintf_conf(f, token, "%s\n", cs_hexdump(0, var, var_size, tmp, sizeof(tmp))); } else if(cfg.http_full_cfg) { fprintf_conf(f, token, "\n"); } }
static void rsakey_fn(const char *token, char *value, void *setting, FILE *f) { struct s_reader *rdr = setting; if(value) { int32_t len = strlen(value); if(len != 128 && len != 240) { rdr->rsa_mod_length = 0; memset(rdr->rsa_mod, 0, 120); } else { if(key_atob_l(value, rdr->rsa_mod, len)) { fprintf(stderr, "reader rsakey parse error, %s=%s\n", token, value); rdr->rsa_mod_length = 0; memset(rdr->rsa_mod, 0, sizeof(rdr->rsa_mod)); } else { rdr->rsa_mod_length = len/2; } } return; } int32_t len = rdr->rsa_mod_length; if(len > 0) { char tmp[len * 2 + 1]; fprintf_conf(f, "rsakey", "%s\n", cs_hexdump(0, rdr->rsa_mod, len, tmp, sizeof(tmp))); } else if(cfg.http_full_cfg) { fprintf_conf(f, "rsakey", "\n"); } }
static void boxkey_fn(const char *token, char *value, void *setting, FILE *f) { struct s_reader *rdr = setting; if(value) { int32_t len = strlen(value); if(((len % 8) != 0) || len == 0 || len > 32) { rdr->boxkey_length = 0; memset(rdr->boxkey, 0, sizeof(rdr->boxkey)); } else { if(key_atob_l(value, rdr->boxkey, len)) { fprintf(stderr, "reader boxkey parse error, %s=%s\n", token, value); rdr->boxkey_length = 0; memset(rdr->boxkey, 0, sizeof(rdr->boxkey)); } else { rdr->boxkey_length = len/2; } } return; } int32_t len = rdr->boxkey_length; if(len > 0) { char tmp[len * 2 + 1]; fprintf_conf(f, "boxkey", "%s\n", cs_hexdump(0, rdr->boxkey, len, tmp, sizeof(tmp))); } else if(cfg.http_full_cfg) { fprintf_conf(f, "boxkey", "\n"); } }
void chk_port_tab(char *portasc, PTAB *ptab) { int32_t i, j, nfilts, ifilt, iport; PTAB *newptab; char *ptr1, *ptr2, *ptr3, *saveptr1 = NULL; char *ptr[CS_MAXPORTS] = {0}; int32_t port[CS_MAXPORTS] = {0}; if (!cs_malloc(&newptab, sizeof(PTAB))) return; for (nfilts = i = 0, ptr1 = strtok_r(portasc, ";", &saveptr1); (i < CS_MAXPORTS) && (ptr1); ptr1 = strtok_r(NULL, ";", &saveptr1), i++) { ptr[i] = ptr1; if( (ptr2=strchr(trim(ptr1), '@')) ) { *ptr2++ ='\0'; newptab->ports[i].s_port = atoi(ptr1); //checking for des key for port newptab->ports[i].ncd_key_is_set = 0; //default to 0 if( (ptr3=strchr(trim(ptr1), '{')) ) { *ptr3++='\0'; if (key_atob_l(ptr3, newptab->ports[i].ncd_key, 28)) fprintf(stderr, "newcamd: error in DES Key for port %s -> ignored\n", ptr1); else newptab->ports[i].ncd_key_is_set = 1; } ptr[i] = ptr2; port[i] = newptab->ports[i].s_port; newptab->nports++; } nfilts++; } if( nfilts == 1 && strlen(portasc) < 6 && newptab->ports[0].s_port == 0 ) { newptab->ports[0].s_port = atoi(portasc); newptab->nports = 1; } iport = ifilt = 0; for (i=0; i<nfilts; i++) { if( port[i] != 0 ) iport = i; for (j = 0, ptr3 = strtok_r(ptr[i], ",", &saveptr1); (j < CS_MAXPROV) && (ptr3); ptr3 = strtok_r(NULL, ",", &saveptr1), j++) { if( (ptr2=strchr(trim(ptr3), ':')) ) { *ptr2++='\0'; newptab->ports[iport].ftab.nfilts++; ifilt = newptab->ports[iport].ftab.nfilts-1; newptab->ports[iport].ftab.filts[ifilt].caid = (uint16_t)a2i(ptr3, 4); newptab->ports[iport].ftab.filts[ifilt].prids[j] = a2i(ptr2, 6); } else { newptab->ports[iport].ftab.filts[ifilt].prids[j] = a2i(ptr3, 6); } newptab->ports[iport].ftab.filts[ifilt].nprids++; } } memcpy(ptab, newptab, sizeof(PTAB)); free(newptab); }
static void newcamd_key_fn(const char *token, char *value, void *UNUSED(setting), FILE *f) { if (value) { if (strlen(value) == 0) { memset(cfg.ncd_key, 0, sizeof(cfg.ncd_key)); } else if (key_atob_l(value, cfg.ncd_key, 28)) { fprintf(stderr, "Configuration newcamd: Error in Key\n"); memset(cfg.ncd_key, 0, sizeof(cfg.ncd_key)); } return; } fprintf_conf(f, token, "%s", ""); // it should not have \n at the end unsigned int i; for (i = 0; i < 14; i++) { fprintf(f,"%02X", cfg.ncd_key[i]); } fprintf(f,"\n"); }
void chk_ecm_hdr_whitelist(char *value, ECM_HDR_WHITELIST *ecm_hdr_whitelist) { ecm_hdr_whitelist_clear(ecm_hdr_whitelist); char *ptr, *saveptr = NULL; for(ptr = strtok_r(value, ";", &saveptr); ptr; ptr = strtok_r(NULL, ";", &saveptr)) { ECM_HDR_WHITELIST_DATA d; memset(&d, 0, sizeof(d)); char *caid_end_ptr = strchr(ptr, ':'); // caid_end_ptr + 1 -> headers char *provid_ptr = strchr(ptr, '@'); // provid_ptr + 1 -> provid char *headers = ptr; if(caid_end_ptr) { caid_end_ptr[0] = '\0'; if (provid_ptr) { provid_ptr[0] = '\0'; provid_ptr++; d.provid = a2i(provid_ptr, 6); } d.caid = dyn_word_atob(ptr); headers = caid_end_ptr + 1; // -> headers } else if(provid_ptr) { provid_ptr[0] = '\0'; d.provid = a2i(provid_ptr, 6); } if (d.caid == 0xffff) d.caid = 0; if (d.provid == 0xffff) d.provid = 0; char *hdr_ptr, *savehdr_ptr = NULL; for(hdr_ptr = strtok_r(headers, ",", &savehdr_ptr); hdr_ptr; hdr_ptr = strtok_r(NULL, ",", &savehdr_ptr)) { hdr_ptr = trim(hdr_ptr); d.len = strlen(hdr_ptr); if (d.len / 2 > sizeof(d.header)) d.len = sizeof(d.header) * 2; if (d.len > 1) { key_atob_l(hdr_ptr, d.header, d.len); ecm_hdr_whitelist_add(ecm_hdr_whitelist, &d); } } } }
static void camd33_key_fn(const char *token, char *value, void *UNUSED(setting), FILE *f) { if (value) { cfg.c33_crypted = 1; if (!strlen(value)) cfg.c33_crypted = 0; else if (key_atob_l(value, cfg.c33_key, 32)) { cfg.c33_crypted = 0; memset(cfg.c33_key, 0, sizeof(cfg.c33_key)); fprintf(stderr, "ERROR: camd3.3 config error in 'key'.\n"); } return; } unsigned int i; fprintf_conf(f, token, "%s", ""); // it should not have \n at the end for (i = 0; i < sizeof(cfg.c33_key); i++) { fprintf(f, "%02X", cfg.c33_key[i]); } fprintf(f, "\n"); }
int config_list_parse(const struct config_list *clist, const char *token, char *value, void *config_data) { const struct config_list *c; for(c = clist; c->opt_type != OPT_UNKNOWN; c++) { if(c->opt_type == OPT_SAVE_FUNC || c->opt_type == OPT_FIXUP_FUNC) { continue; } if(strcasecmp(token, c->config_name) != 0) { continue; } void *var = config_data + c->var_offset; switch(c->opt_type) { case OPT_INT8: { *(int8_t *)var = (int8_t)strToIntVal(value, c->def.d_int8); return 1; } case OPT_UINT8: { uint32_t tmp = strToUIntVal(value, c->def.d_uint8); *(uint8_t *)var = (uint8_t)(tmp <= 0xff ? tmp : 0xff); return 1; } case OPT_INT32: { int32_t tmp = strToIntVal(value, c->def.d_int32); memcpy(var, &tmp, sizeof(int32_t)); return 1; } case OPT_UINT32: { uint32_t tmp = strToUIntVal(value, c->def.d_uint32); memcpy(var, &tmp, sizeof(uint32_t)); return 1; } case OPT_STRING: { char **scfg = var; if(c->def.d_char && strlen(value) == 0) // Set default { value = c->def.d_char; } NULLFREE(*scfg); if(strlen(value)) { *scfg = cs_strdup(value); } return 1; } case OPT_SSTRING: { char *scfg = var; if(c->def.d_char && strlen(value) == 0) // Set default { value = c->def.d_char; } scfg[0] = '\0'; unsigned int len = strlen(value); if(len) { strncpy(scfg, value, c->str_size - 1); if(len > c->str_size) { fprintf(stderr, "WARNING: Config value for '%s' (%s, len=%u) exceeds max length: %d (%s)\n", token, value, len, c->str_size - 1, scfg); } } return 1; } case OPT_HEX_ARRAY: { uint8_t *hex_array = var; if(!strlen(value)) { memset(hex_array, 0, c->def.array_size); } else if(key_atob_l(value, hex_array, c->def.array_size * 2)) { memset(hex_array, 0, c->def.array_size); fprintf(stderr, "WARNING: Config value for '%s' (%s, len=%zu) requires %d chars.\n", token, value, strlen(value), c->def.array_size * 2); } return 1; } case OPT_FUNC: { c->ops.process_fn(token, value, var, NULL); return 1; } case OPT_FUNC_EXTRA: { c->ops.process_fn_extra(token, value, var, c->def.d_extra, NULL); return 1; } case OPT_FIXUP_FUNC: case OPT_SAVE_FUNC: return 1; case OPT_UNKNOWN: { fprintf(stderr, "Unknown config type (%s = %s).", token, value); break; } } } return 0; }
/* Parses a single AES_KEYS entry and assigns it to the given list. The expected format for value is caid1@ident1:key0,key1 */ void parse_aes_entry(AES_ENTRY **list, char *label, char *value) { uint16_t caid, dummy; uint32_t ident; int32_t len; char *tmp; int32_t nb_keys, key_id; uchar aes_key[16]; char *save = NULL; tmp = strtok_r(value, "@", &save); //if we got error caid len = strlen(tmp); if(len == 0 || len > 4) { return; } //if there is not value after @ len = strlen(save); if(len == 0) { return; } caid = a2i(tmp, 2); tmp = strtok_r(NULL, ":", &save); //if we got error ident len = strlen(tmp); if(len == 0 || len > 6) { return; } ident = a2i(tmp, 3); // now we need to split the key and add the entry to the reader. nb_keys = 0; key_id = 0; while((tmp = strtok_r(NULL, ",", &save))) { dummy = 0; len = strlen(tmp); if(len != 32) { dummy = a2i(tmp, 1); // FF means the card will do the AES decrypt // 00 means we don't have the aes. if((dummy != 0xFF && dummy != 0x00) || len > 2) { key_id++; cs_log("AES key length error .. not adding"); continue; } if(dummy == 0x00) { key_id++; continue; } } nb_keys++; if(dummy) { memset(aes_key, 0xFF, 16); } else { key_atob_l(tmp, aes_key, 32); } // now add the key to the reader... TBD add_aes_entry(list, caid, ident, key_id, aes_key); key_id++; } cs_log("%d AES key(s) added on reader %s for %04x:%06x", nb_keys, label, caid, ident); }
static void ecmheaderwhitelist_fn(const char *token, char *value, void *setting, FILE *f) { struct s_reader *rdr = setting; if (value) { char *ptr, *ptr2, *ptr3; struct s_ecmHeaderwhitelist *tmp, *last = NULL; if (strlen(value) == 0) { for (tmp = rdr->ecmHeaderwhitelist; tmp; tmp=tmp->next) add_garbage(tmp); rdr->ecmHeaderwhitelist = NULL; } else { char *ptr4, *ptr5, *ptr6, *saveptr = NULL, *saveptr4 = NULL, *saveptr5 = NULL, *saveptr6 = NULL; uint16_t caid = 0; uint32_t provid = 0; int16_t len = 0; for (ptr = strtok_r(value, ";", &saveptr); ptr; ptr = strtok_r(NULL, ";", &saveptr)) { caid = 0; provid = 0; ptr2 = strchr(ptr, '@'); ptr3 = strchr(ptr, ':'); if (ptr2 == NULL && ptr3 == NULL) { //no Caid no Provid for (ptr4 = strtok_r(ptr, ",", &saveptr4); ptr4; ptr4 = strtok_r(NULL, ",", &saveptr4)) { if (cs_malloc(&tmp, sizeof(struct s_ecmHeaderwhitelist))) { ptr4 = trim(ptr4); len = strlen(ptr4); key_atob_l(ptr4, tmp->header, len); tmp->len = len; tmp->caid = 0; tmp->provid = 0; tmp->next = NULL; if (last == NULL) { rdr->ecmHeaderwhitelist = tmp; } else { last->next = tmp; } last = tmp; } } } if (ptr3 != NULL && ptr2 == NULL) { // only with Caid ptr3[0] = '\0'; ++ptr3; caid = (int16_t)dyn_word_atob(ptr); for (ptr5 = strtok_r(ptr3, ",", &saveptr5); ptr5; ptr5 = strtok_r(NULL, ",", &saveptr5)) { if (cs_malloc(&tmp, sizeof(struct s_ecmHeaderwhitelist))) { tmp->caid = caid; tmp->provid = 0; ptr5 = trim(ptr5); len = strlen(ptr5); key_atob_l(ptr5, tmp->header, len); tmp->len = len; tmp->next = NULL; if (last == NULL) { rdr->ecmHeaderwhitelist = tmp; } else { last->next = tmp; } last = tmp; } } } if (ptr3 != NULL && ptr2 != NULL) { // with Caid & Provid ptr2[0] = '\0'; ++ptr2; // -> provid ptr3[0] = '\0'; ++ptr3; // -> headers caid = (int16_t)dyn_word_atob(ptr); provid = (uint32_t)a2i(ptr2, 6); for (ptr6 = strtok_r(ptr3, ",", &saveptr6); ptr6; ptr6 = strtok_r(NULL, ",", &saveptr6)) { if (cs_malloc(&tmp, sizeof(struct s_ecmHeaderwhitelist))) { tmp->caid = caid; tmp->provid = provid; ptr6 = trim(ptr6); len = strlen(ptr6); key_atob_l(ptr6, tmp->header, len); tmp->len = len; tmp->next = NULL; if (last == NULL) { rdr->ecmHeaderwhitelist = tmp; } else { last->next = tmp; } last = tmp; } } } } } /* if (rdr->ecmHeaderwhitelist != NULL) { // debug cs_log("**********Begin ECM Header List for Reader: %s **************", rdr->label); struct s_ecmHeaderwhitelist *tmp; for(tmp = rdr->ecmHeaderwhitelist; tmp; tmp=tmp->next){ cs_log("Caid: %i Provid: %i Header: %02X Len: %i", tmp->caid, tmp->provid, tmp->header[0], tmp->len); } cs_log("***********End ECM Header List for Reader: %s ***************", rdr->label); } */ return; } value = mk_t_ecmheaderwhitelist(rdr->ecmHeaderwhitelist); if (strlen(value) > 0 || cfg.http_full_cfg) fprintf_conf(f, token, "%s\n", value); free_mk_t(value); }
static void mgencrypted_fn(const char *UNUSED(token), char *value, void *setting, FILE *UNUSED(f)) { struct s_reader *rdr = setting; if (value) { uchar key[16]; uchar mac[6]; char tmp_dbg[13]; uchar *buf = NULL; int32_t i, len = 0; char *ptr, *saveptr1 = NULL; memset(&key, 0, 16); memset(&mac, 0, 6); for (i = 0, ptr = strtok_r(value, ",", &saveptr1); (i < 2) && (ptr); ptr = strtok_r(NULL, ",", &saveptr1), i++) { trim(ptr); switch(i) { case 0: len = strlen(ptr) / 2 + (16 - (strlen(ptr) / 2) % 16); if (!cs_malloc(&buf, len)) return; key_atob_l(ptr, buf, strlen(ptr)); cs_log("enc %d: %s", len, ptr); break; case 1: key_atob_l(ptr, mac, 12); cs_log("mac: %s", ptr); break; } } if (!memcmp(mac, "\x00\x00\x00\x00\x00\x00", 6)) { #if defined(__APPLE__) || defined(__FreeBSD__) // no mac address specified so use mac of en0 on local box struct ifaddrs *ifs, *current; if (getifaddrs(&ifs) == 0) { for (current = ifs; current != 0; current = current->ifa_next) { if (current->ifa_addr->sa_family == AF_LINK && strcmp(current->ifa_name, "en0") == 0) { struct sockaddr_dl *sdl = (struct sockaddr_dl *)current->ifa_addr; memcpy(mac, LLADDR(sdl), sdl->sdl_alen); break; } } freeifaddrs(ifs); } #elif defined(__SOLARIS__) // no mac address specified so use first filled mac int32_t j, sock, niccount; struct ifreq nicnumber[16]; struct ifconf ifconf; struct arpreq arpreq; if ((sock=socket(AF_INET,SOCK_DGRAM,0)) > -1){ ifconf.ifc_buf = (caddr_t)nicnumber; ifconf.ifc_len = sizeof(nicnumber); if (!ioctl(sock,SIOCGIFCONF,(char*)&ifconf)){ niccount = ifconf.ifc_len/(sizeof(struct ifreq)); for(i = 0; i < niccount, ++i){ memset(&arpreq, 0, sizeof(arpreq)); ((struct sockaddr_in*)&arpreq.arp_pa)->sin_addr.s_addr = ((struct sockaddr_in*)&nicnumber[i].ifr_addr)->sin_addr.s_addr; if (!(ioctl(sock,SIOCGARP,(char*)&arpreq))){ for (j = 0; j < 6; ++j) mac[j] = (unsigned char)arpreq.arp_ha.sa_data[j]; if(check_filled(mac, 6) > 0) break; } } } close(sock); } #else // no mac address specified so use mac of eth0 on local box int32_t fd = socket(PF_INET, SOCK_STREAM, 0); struct ifreq ifreq; memset(&ifreq, 0, sizeof(ifreq)); snprintf(ifreq.ifr_name, sizeof(ifreq.ifr_name), "eth0"); ioctl(fd, SIOCGIFHWADDR, &ifreq); memcpy(mac, ifreq.ifr_ifru.ifru_hwaddr.sa_data, 6); close(fd); #endif cs_debug_mask(D_TRACE, "Determined local mac address for mg-encrypted as %s", cs_hexdump(1, mac, 6, tmp_dbg, sizeof(tmp_dbg))); }
void chk_reader(char *token, char *value, struct s_reader *rdr) { int32_t i; char *ptr, *ptr2, *ptr3, *saveptr1 = NULL; /* * case sensitive first */ if (!strcmp(token, "device")) { for (i = 0, ptr = strtok_r(value, ",", &saveptr1); (i < 3) && (ptr); ptr = strtok_r(NULL, ",", &saveptr1), i++) { trim(ptr); switch(i) { case 0: cs_strncpy(rdr->device, ptr, sizeof(rdr->device)); break; case 1: rdr->r_port = atoi(ptr); break; case 2: rdr->l_port = atoi(ptr); break; } } return; } #ifdef WITH_LIBUSB if (!strcmp(token, "device_out_endpoint")) { if (strlen(value) > 0) { sscanf(value, "0x%2X", &i); rdr->device_endpoint = i; } else { rdr->device_endpoint = 0; } return; } #endif if (!strcmp(token, "key")) { if (strlen(value) == 0){ return; } else if (key_atob_l(value, rdr->ncd_key, 28)) { fprintf(stderr, "Configuration newcamd: Error in Key\n"); memset(rdr->ncd_key, 0, sizeof(rdr->ncd_key)); } return; } if (!strcmp(token, "password")) { cs_strncpy(rdr->r_pwd, value, sizeof(rdr->r_pwd)); return; } if (!strcmp(token, "user")) { cs_strncpy(rdr->r_usr, value, sizeof(rdr->r_usr)); return; } #ifdef WEBIF if (!strcmp(token, "description")) { NULLFREE(rdr->description); if(strlen(value) > 0 && cs_malloc(&rdr->description, strlen(value)+1, -1)){ cs_strncpy(rdr->description, value, strlen(value)+1); } return; } #endif if (!strcmp(token, "mg-encrypted")) { uchar key[16]; uchar mac[6]; char tmp_dbg[13]; uchar *buf = NULL; int32_t len = 0; memset(&key, 0, 16); memset(&mac, 0, 6); for (i = 0, ptr = strtok_r(value, ",", &saveptr1); (i < 2) && (ptr); ptr = strtok_r(NULL, ",", &saveptr1), i++) { trim(ptr); switch(i) { case 0: len = strlen(ptr) / 2 + (16 - (strlen(ptr) / 2) % 16); if(!cs_malloc(&buf,len, -1)) return; key_atob_l(ptr, buf, strlen(ptr)); cs_log("enc %d: %s", len, ptr); break; case 1: key_atob_l(ptr, mac, 12); cs_log("mac: %s", ptr); break; } } if (!memcmp(mac, "\x00\x00\x00\x00\x00\x00", 6)) { #if defined(__APPLE__) || defined(__FreeBSD__) // no mac address specified so use mac of en0 on local box struct ifaddrs *ifs, *current; if (getifaddrs(&ifs) == 0) { for (current = ifs; current != 0; current = current->ifa_next) { if (current->ifa_addr->sa_family == AF_LINK && strcmp(current->ifa_name, "en0") == 0) { struct sockaddr_dl *sdl = (struct sockaddr_dl *)current->ifa_addr; memcpy(mac, LLADDR(sdl), sdl->sdl_alen); break; } } freeifaddrs(ifs); } #elif defined(__SOLARIS__) // no mac address specified so use first filled mac int32_t j, sock, niccount; struct ifreq nicnumber[16]; struct ifconf ifconf; struct arpreq arpreq; if ((sock=socket(AF_INET,SOCK_DGRAM,0)) > -1){ ifconf.ifc_buf = (caddr_t)nicnumber; ifconf.ifc_len = sizeof(nicnumber); if (!ioctl(sock,SIOCGIFCONF,(char*)&ifconf)){ niccount = ifconf.ifc_len/(sizeof(struct ifreq)); for(i = 0; i < niccount, ++i){ memset(&arpreq, 0, sizeof(arpreq)); ((struct sockaddr_in*)&arpreq.arp_pa)->sin_addr.s_addr = ((struct sockaddr_in*)&nicnumber[i].ifr_addr)->sin_addr.s_addr; if (!(ioctl(sock,SIOCGARP,(char*)&arpreq))){ for (j = 0; j < 6; ++j) mac[j] = (unsigned char)arpreq.arp_ha.sa_data[j]; if(check_filled(mac, 6) > 0) break; } } } close(sock); }