HelenOS sources
This source file includes following definitions.
- portrng_create
- portrng_destroy
- portrng_alloc
- portrng_find_port
- portrng_free_port
- portrng_empty
#include <adt/list.h>
#include <errno.h>
#include <inet/endpoint.h>
#include <nettl/portrng.h>
#include <stdint.h>
#include <stdlib.h>
#include <io/log.h>
errno_t portrng_create(portrng_t **rpr)
{
portrng_t *pr;
log_msg(LOG_DEFAULT, LVL_DEBUG2, "portrng_create() - begin");
pr = calloc(1, sizeof(portrng_t));
if (pr == NULL)
return ENOMEM;
list_initialize(&pr->used);
*rpr = pr;
log_msg(LOG_DEFAULT, LVL_DEBUG2, "portrng_create() - end");
return EOK;
}
void portrng_destroy(portrng_t *pr)
{
log_msg(LOG_DEFAULT, LVL_DEBUG2, "portrng_destroy()");
assert(list_empty(&pr->used));
free(pr);
}
errno_t portrng_alloc(portrng_t *pr, uint16_t pnum, void *arg,
portrng_flags_t flags, uint16_t *apnum)
{
portrng_port_t *p;
uint32_t i;
bool found;
log_msg(LOG_DEFAULT, LVL_DEBUG2, "portrng_alloc() - begin");
if (pnum == inet_port_any) {
for (i = inet_port_dyn_lo; i <= inet_port_dyn_hi; i++) {
log_msg(LOG_DEFAULT, LVL_DEBUG2, "trying %" PRIu32, i);
found = false;
list_foreach(pr->used, lprng, portrng_port_t, port) {
if (port->pn == pnum) {
found = true;
break;
}
}
if (!found) {
pnum = i;
break;
}
}
if (pnum == inet_port_any) {
return ENOENT;
}
log_msg(LOG_DEFAULT, LVL_DEBUG2, "selected %" PRIu16, pnum);
} else {
log_msg(LOG_DEFAULT, LVL_DEBUG2, "user asked for %" PRIu16, pnum);
if ((flags & pf_allow_system) == 0 &&
pnum < inet_port_user_lo) {
log_msg(LOG_DEFAULT, LVL_DEBUG2, "system port not allowed");
return EINVAL;
}
list_foreach(pr->used, lprng, portrng_port_t, port) {
if (port->pn == pnum) {
log_msg(LOG_DEFAULT, LVL_DEBUG2, "port already used");
return EEXIST;
}
}
}
p = calloc(1, sizeof(portrng_port_t));
if (p == NULL)
return ENOMEM;
p->pn = pnum;
p->arg = arg;
list_append(&p->lprng, &pr->used);
*apnum = pnum;
log_msg(LOG_DEFAULT, LVL_DEBUG2, "portrng_alloc() - end OK pn=%" PRIu16,
pnum);
return EOK;
}
errno_t portrng_find_port(portrng_t *pr, uint16_t pnum, void **rarg)
{
list_foreach(pr->used, lprng, portrng_port_t, port) {
if (port->pn == pnum) {
*rarg = port->arg;
return EOK;
}
}
return ENOENT;
}
void portrng_free_port(portrng_t *pr, uint16_t pnum)
{
log_msg(LOG_DEFAULT, LVL_DEBUG2, "portrng_free_port(%u)", pnum);
log_msg(LOG_DEFAULT, LVL_DEBUG2, "portrng_free_port() - begin");
list_foreach(pr->used, lprng, portrng_port_t, port) {
log_msg(LOG_DEFAULT, LVL_DEBUG2, "portrng_free_port - check port %u", port->pn);
if (port->pn == pnum) {
log_msg(LOG_DEFAULT, LVL_DEBUG2, "portrng_free_port - OK");
list_remove(&port->lprng);
free(port);
log_msg(LOG_DEFAULT, LVL_DEBUG2, "portrng_free_port() - end");
return;
}
}
log_msg(LOG_DEFAULT, LVL_DEBUG2, "portrng_free_port - FAIL");
assert(false);
}
bool portrng_empty(portrng_t *pr)
{
log_msg(LOG_DEFAULT, LVL_DEBUG2, "portrng_empty()");
return list_empty(&pr->used);
}
HelenOS homepage, sources at GitHub