int scamper_if_getmac(const int ifindex, uint8_t *mac) { scamper_fd_t *fd = NULL; struct ifreq ifr; if(if_indextoname(ifindex, ifr.ifr_name) == NULL) { printerror(errno, strerror, __func__, "could not if_indextoname"); goto err; } if((fd = scamper_fd_ifsock()) == NULL) { printerror(errno, strerror, __func__, "could not get ifsock"); goto err; } if(ioctl(scamper_fd_fd_get(fd), SIOCGIFHWADDR, &ifr) == -1) { printerror(errno, strerror, __func__, "could not SIOCGIFHWADDR"); goto err; } memcpy(mac, ifr.ifr_hwaddr.sa_data, 6); scamper_fd_free(fd); return 0; err: if(fd != NULL) scamper_fd_free(fd); return -1; }
int scamper_if_getmtu(const int ifindex, uint16_t *ifmtu) { scamper_fd_t *fd; struct ifreq ifr; int mtu; assert(ifindex >= 0); /* given the index, return the interface name to query */ if(if_indextoname((unsigned int)ifindex, ifr.ifr_name) == NULL) { printerror(errno, strerror, __func__, "could not if_indextoname"); return -1; } if((fd = scamper_fd_ifsock()) == NULL) { printerror(errno, strerror, __func__, "could not get ifsock"); return -1; } if(ioctl(scamper_fd_fd_get(fd), SIOCGIFMTU, &ifr) == -1) { printerror(errno, strerror, __func__, "could not SIOCGIFMTU"); scamper_fd_free(fd); return -1; } scamper_fd_free(fd); #if defined(__sun__) mtu = ifr.ifr_metric; #else mtu = ifr.ifr_mtu; #endif if(mtu >= 0 && mtu <= 65535) { *ifmtu = mtu; return 0; } return -1; }
/* * task_fd * * make sure the task has a hold on this fd. */ static scamper_fd_t *task_fd(scamper_task_t *t, scamper_fd_t *fd) { if(fd == NULL) return NULL; if(array_find((void **)t->fds, t->fdc, fd, (array_cmp_t)task_fd_cmp) == NULL) { if(array_insert((void ***)&t->fds, &t->fdc, fd, (array_cmp_t)task_fd_cmp) != 0) { scamper_fd_free(fd); return NULL; } } else { /* already have a hold of the fd */ scamper_fd_free(fd); } return fd; }
/* * scamper_fd_free * * this function reduces the reference count for a given file descriptor. * * if zero is reached, the fd will be dealt with when scamper_fd_poll is next * called. the fd cannot be summarily removed here without the potential * to screw up any current call to scamper_fd_poll as that function assumes * the list remains intact for the duration of any events found with select. * */ void scamper_fd_free(scamper_fd_t *fdn) { assert(fdn != NULL); assert(fdn->refcnt > 0); if(--fdn->refcnt == 0) { if(fdn->pl != NULL) { scamper_fd_free(fdn->pl); fdn->pl = NULL; } fd_refcnt_0(fdn); } return; }
scamper_fd_t *scamper_fd_udp4(void *addr, uint16_t sport) { scamper_fd_t *fd; if(planetlab == 0) return fd_udp(SCAMPER_FD_TYPE_UDP4, addr, sport); if((fd = fd_udp(SCAMPER_FD_TYPE_UDP4DG, addr, sport)) == NULL) return NULL; if(fd->pl == NULL) { if((fd->pl = fd_udp(SCAMPER_FD_TYPE_UDP4, addr, sport)) == NULL) { scamper_fd_free(fd); return NULL; } } return fd; }
/* * scamper_task_free * * free a task structure. * this involves freeing the task using the free pointer provided, * freeing the queue data structure, unholding any tasks blocked, and * finally freeing the task structure itself. */ void scamper_task_free(scamper_task_t *task) { scamper_task_anc_t *anc; task_onhold_t *toh; int i; if(task->funcs != NULL) task->funcs->task_free(task); if(task->queue != NULL) { scamper_queue_free(task->queue); task->queue = NULL; } if(task->onhold != NULL) { while((toh = dlist_head_pop(task->onhold)) != NULL) { toh->unhold(toh->param); free(toh); } dlist_free(task->onhold); } if(task->cyclemon != NULL) { scamper_cyclemon_unuse(task->cyclemon); task->cyclemon = NULL; } if(task->sourcetask != NULL) { scamper_sourcetask_free(task->sourcetask); task->sourcetask = NULL; } if(task->siglist != NULL) { scamper_task_sig_deinstall(task); slist_free(task->siglist); } if(task->ancillary != NULL) { while((anc = dlist_head_pop(task->ancillary)) != NULL) { anc->node = NULL; anc->freedata(anc->data); free(anc); } dlist_free(task->ancillary); } if(task->fds != NULL) { for(i=0; i<task->fdc; i++) scamper_fd_free(task->fds[i]); free(task->fds); } free(task); return; }