--- libaitio/inc/aitio.h 2013/06/04 12:19:54 1.30.2.1 +++ libaitio/inc/aitio.h 2014/02/08 22:06:16 1.40 @@ -3,7 +3,7 @@ * by Michael Pounov * * $Author: misho $ -* $Id: aitio.h,v 1.30.2.1 2013/06/04 12:19:54 misho Exp $ +* $Id: aitio.h,v 1.40 2014/02/08 22:06:16 misho Exp $ * ************************************************************************** The ELWIX and AITNET software is distributed under the following @@ -12,7 +12,7 @@ terms: All of the documentation and software included in the ELWIX and AITNET Releases is copyrighted by ELWIX - Sofia/Bulgaria -Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 +Copyright 2004 - 2014 by Michael Pounov . All rights reserved. Redistribution and use in source and binary forms, with or without @@ -59,14 +59,75 @@ SUCH DAMAGE. #include #include #include +#include #include +#include +#include #ifndef STRSIZ -#define STRSIZ 256 +#define STRSIZ 256 #endif +#define IO_SOCK_ROLE_CLIENT 0 +#define IO_SOCK_ROLE_SERVER 1 +#define IO_ETHER_FILTER_PROMISC 0 +#define IO_ETHER_FILTER_NOTREAD -1 +#define IO_ETHER_FILTER_READ 1 +#define IO_ETHER_FILTER_WRITE 2 + + +typedef struct { + unsigned int prog_inin; /* init progs */ + unsigned int prog_maxn; /* max progs */ + unsigned int prog_cnum; /* current progs */ + char prog_name[PATH_MAX]; + + pthread_mutex_t prog_mtx; + array_t *prog_fds; + unsigned int *prog_used; +} prog_t; + +typedef struct tagCliSock sock_cli_t; +typedef void *(*sock_cb_t)(sock_cli_t*); +struct tagCliSock { + void *cli_parent; + int cli_fd; + intptr_t cli_pty; + sockaddr_t cli_addr; + char cli_name[64]; + char cli_cmdline[PATH_MAX]; + pid_t cli_pid; + + sched_task_func_t cli_func; + + ait_val_t cli_buf[2]; + + TAILQ_ENTRY(tagCliSock) cli_node; +}; + +typedef struct { + int sock_role; + int sock_backq; + int sock_type; + int sock_proto; + int sock_fd; + struct timespec sock_timeout; + sockaddr_t sock_addr; + sockaddr_t sock_peer; + + ait_val_t sock_buf; + prog_t *sock_prog; + + volatile intptr_t sock_kill; + sched_root_task_t *sock_root; + + pthread_mutex_t sock_mtx; + TAILQ_HEAD(, tagCliSock) sock_cli; +} sock_t; + + // io_GetErrno() Get error code of last operation int io_GetErrno(); // io_GetError() Get error text of last operation @@ -74,6 +135,189 @@ const char *io_GetError(); /* + * io_progInit() - Init program pool + * + * @progName = program name for execution + * @initNum = initial started programs + * @maxNum = maximum started programs + * return: NULL error or !=NULL allocated pool (must destroied with io_progDestroy()) + */ +prog_t *io_progInit(const char *progName, + unsigned int initNum, unsigned int maxNum); +/* + * io_progOpen() - Execute number of program(s) + * + * @prg = program pool + * @execNum = execute program(s) (0 max) + * return: -1 error, >0 executed programs + */ +int io_progOpen(prog_t * __restrict prg, unsigned int execNum); +/* + * io_progOpen2() - Start program from pool on first unused slot + * + * @prg = program pool + * return: -1 error, >-1 reside at slot + */ +int io_progOpen2(prog_t * __restrict prg); +/* + * io_progGrow() - Execute to number of programs in pool + * + * @prg = program pool + * @toNum = execute to number of programs (0 max) + * return: 0 error or nothing to do, + * >0 executed programs and abs(<0) executed programs with logged error + */ +int io_progGrow(prog_t * __restrict prg, unsigned int toNum); +/* + * io_progVacuum() - Vacuum pool to running number of programs + * + * @prg = program pool + * @toNum = vacuum to number of programs (0 to init number) + * return: 0 error or >0 closed programs + */ +int io_progVacuum(prog_t * __restrict prg, unsigned int toNum); +/* + * io_progCloseAt() - Close program at pool of certain position + * + * @prg = program pool + * @idx = index at pool + * return: 0 error or !=0 closed program + */ +int io_progCloseAt(prog_t * __restrict prg, unsigned int idx); +/* + * io_progCloseOf() - Close program at pool with certain handle + * + * @prg = program pool + * @h = handle of program + * return: 0 error, >0 closed programs + */ +#ifdef POPEN_STREAM +int io_progCloseOf(prog_t * __restrict prg, FILE *h); +#else +int io_progCloseOf(prog_t * __restrict prg, int h); +#endif +/* + * io_progClose() - Close all programs in pool + * + * @prg = program pool + * @closeNum = close program(s) (0 all) + * return: 0 error, >0 closed programs + */ +int io_progClose(prog_t * __restrict prg, unsigned int closeNum); +/* + * io_progDestroy() - Destroy entire program pool + * + * @pprg = program pool + * return: none + */ +void io_progDestroy(prog_t ** __restrict pprg); + +/* + * io_progCheck() - Check exit status of program pool + * + * @prg = program pool + * @re = resurrect program to init number + * return: -1 error or >-1 exited programs + */ +int io_progCheck(prog_t * __restrict prg, int re); + +/* + * io_progAttach() - Attach to open program + * + * @prg = program pool + * @newOne = Execute new one program after attach + * return: NULL error or !=NULL attached program handle + */ +#ifdef POPEN_STREAM +FILE *io_progAttach(prog_t * __restrict prg, int newOne); +#else +int io_progAttach(prog_t * __restrict prg, int newOne); +#endif +/* + * io_progDetach() - Detch from open program + * + * @prg= program pool + * @pfd = attached program handle + * return: none + */ +#ifdef POPEN_STREAM +void io_progDetach(prog_t * __restrict prg, FILE *pfd); +#else +void io_progDetach(prog_t * __restrict prg, int pfd); +#endif + + +/* + * ioInitSocket() - Init socket and allocate resources + * + * @role = Socket role + * @type = Socket type + * @proto = Socket protocol + * @addr = Bind to address + * @port = Bind to port + * @buflen = Socket buffer, optional if =0 == BUFSIZ + * return: NULL error or !=NULL created socket + */ +sock_t *ioInitSocket(int role, int type, int proto, + const char *addr, unsigned short port, size_t buflen); +/* + * ioCloseSocket() - Close socket and free resources + * + * @s = Socket + * return: none + */ +void ioCloseSocket(sock_t ** __restrict s); +#define ioKillSocket(x) (assert((x)), (x)->sock_kill = 1) +/* + * ioCloseClient() - Close client socket + * + * @c = Client socket + * return: 0 ok or !=0 error + */ +int ioCloseClient(sock_cli_t * __restrict c); +/* + * ioSetupProg2Socket() - Setup program pool to socket server + * + * @s = Socket + * @p = Program pool + * return: -1 error or 0 ok + */ +int ioSetupProg2Socket(sock_t * __restrict s, prog_t * __restrict p); +/* + * ioUpSocket() - Setup socket for use + * + * @s = Socket + * @arg = Server role = listen backlog queue and Client role = peer address + * @timeout = Socket timeout in ms (default -1 infinit) + * return: -1 error or 0 ok + */ +int ioUpSocket(sock_t * __restrict s, void *arg, int timeout); +/* + * ioUpdTimerSocket() - Update timeout of socket + * + * @c = Client socket + * return: none + */ +void ioUpdTimerSocket(sock_cli_t * __restrict c); +/* + * ioLoopSocket() - Start socket scheduler + * + * @s = Socket + * @rcb = Read callback + * return: -1 error or return result from scheduler + */ +int ioLoopSocket(sock_t * __restrict s, sched_task_func_t rcb); +/* + * ioBridgeProg2Socket() - Start socket scheduler and bridge program to socket + * + * @s = Socket + * @prgname = Program name + * return: 0 ok or !=0 error + */ +int ioBridgeProg2Socket(sock_t * __restrict s, const char *prgname); + + +/* * ioPromptRead() - Read data from input h[0] with prompt to output h[1] * * @h = file handles h[0] = input, h[1] = output, if NULL use stdin, stdout @@ -82,7 +326,8 @@ const char *io_GetError(); * @dataLen = Length of data * return: 0 EOF; -1 error:: can`t read; >0 count of readed chars */ -int ioPromptRead(int *h, const char *csPrompt, char * __restrict psData, int dataLen); +int ioPromptRead(int *h, const char *csPrompt, + char * __restrict psData, int dataLen); /* * ioPromptPassword() - Read password from input h[0] with prompt to output h[1] * @@ -93,7 +338,8 @@ int ioPromptRead(int *h, const char *csPrompt, char * * @confirm = Confirm password, 0 - get password, !=0 Ask for confirmation * return: 0 EOF; -1 error:: can`t read; >0 count of readed chars */ -int ioPromptPassword(int *h, const char *csPrompt, char * __restrict psPass, int passLen, int confirm); +int ioPromptPassword(int *h, const char *csPrompt, + char * __restrict psPass, int passLen, int confirm); /* @@ -385,6 +631,78 @@ FILE *io_fd2buf(int fd, const char *mode); * return: -1 error or open file handle */ int io_dumbFile(const char *csFile, int mode, off_t size); + + +/* + * io_get1stiface() - Get first interface of host + * + * @szIface = interface string buffer + * @iflen = size of interface buffer + * return: -1 error or 0 ok + */ +int io_get1stiface(char *szIface, int iflen); +/* + * io_getmaciface() - Get MAC address from interface name + * + * @csIface = interface name + * @ea = ethernet address + * return: -1 error, 0 ok or 1 not found + */ +int io_getmaciface(const char *csIface, ether_addr_t * __restrict ea); +/* + * io_etherOpen() - Open BPF interface to device + * + * @csIface = interface name + * @flags = open flags + * @whdr = with complete headers + * @wdlt = with data link type + * @buflen = buffer length + * @zcbuf = zero copy buffer, if BPF supports it and isn't NULL + * return: -1 error or >-1 bpf handle + */ +int io_etherOpen(const char *csIface, int flags, unsigned int whdr, + unsigned int wdlt, unsigned int *buflen, void **zcbuf); +/* + * io_etherClose() - Close BPF interface + * + * @eth = bpf handle + * @zcbuf = zero copy buffer, if BPF supports it and isn't NULL + * return: none + */ +void io_etherClose(int eth, void **zcbuf); + +/* + * io_etherFilter() - BPF filter routine + * + * @eth = bpf handle + * @io = filter direction + * (IO_ETHER_FILTER_PROMISC|IO_ETHER_FILTER_NOTREAD|IO_ETHER_FILTER_READ|IO_ETHER_FILTER_WRITE) + * @insn = BPF filter instruction array + * @insnlen = Length of BPF filter instruction array + * return: -1 error or 0 ok + */ +int io_etherFilter(int eth, int io, struct bpf_insn * __restrict insn, size_t insnlen); + +/* + * io_etherSend() - Send packet to bpf + * + * @eth = bpf handle + * @buf = buffer + * @buflen = buffer length + * return: -1 error or !=-1 written bytes + */ +ssize_t io_etherSend(int eth, const void *buf, size_t buflen); +/* + * io_etherRecv() - Receive packet from bpf + * + * @eth = bpf handle + * @buf = buffer + * @buflen = buffer length + * @zcbuf = zero copy buffer, if BPF supports it and isn't NULL + * return: -1 error or !=-1 readed bytes + */ +ssize_t io_etherRecv(int eth, void * __restrict buf, + size_t buflen, void * __restrict zcbuf); #endif