X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=chiark-tcl.git;a=blobdiff_plain;f=tuntap%2Ftuntap.c;h=9486a9add8b871ca4665099322b4ce19c886973c;hp=7a1d2682e79ccfbba9a507c327809429b80e1830;hb=403ef0f3eb85708789afeec1048ad1b6a7b667f6;hpb=f437e443f5381d84f686d1b01ace6ae4bf19650f diff --git a/tuntap/tuntap.c b/tuntap/tuntap.c index 7a1d268..9486a9a 100644 --- a/tuntap/tuntap.c +++ b/tuntap/tuntap.c @@ -10,12 +10,7 @@ * if script not supplied, cancel */ -#include "tables.h" -#include "hbytes.h" - -#include -#include -#include +#include "chiark_tcl_tuntap.h" typedef struct TunSocket { int ix, fd, script_llength; @@ -26,9 +21,7 @@ typedef struct TunSocket { char *ifname; } TuntapSocket; -IdDataTable tuntap_socks= { "tuntap" }; - -int do_tuntap_socket_raw_create(ClientData cd, Tcl_Interp *ip, +int cht_do_tuntapsocket_create_tun(ClientData cd, Tcl_Interp *ip, const char *ifname, void **sock_r) { int fd, r; struct ifreq ifr; @@ -39,18 +32,18 @@ int do_tuntap_socket_raw_create(ClientData cd, Tcl_Interp *ip, if (ifname) { if (strlen(ifname) > IFNAMSIZ-1) return - staticerr(ip,"tun interface name too long","TUNTAP IFNAME LENGTH"); + cht_staticerr(ip,"tun interface name too long","TUNTAP IFNAME LENGTH"); strcpy(ifr.ifr_name, ifname); } fd= open("/dev/net/tun", O_RDWR); - if (fd<0) return posixerr(ip,errno,"open /dev/net/tun"); + if (fd<0) return cht_posixerr(ip,errno,"open /dev/net/tun"); - r= setnonblock(fd,1); - if (r) return posixerr(ip,errno,"setnonblock tun"); + r= cht_setnonblock(fd,1); + if (r) return cht_posixerr(ip,errno,"setnonblock tun"); r= ioctl(fd, TUNSETIFF, (void*)&ifr); - if (r) return newfdposixerr(ip,fd,"ioctl TUNSETIFF"); + if (r) return cht_newfdposixerr(ip,fd,"ioctl TUNSETIFF"); sock= TALLOC(sizeof(TuntapSocket)); sock->ix= -1; @@ -59,25 +52,25 @@ int do_tuntap_socket_raw_create(ClientData cd, Tcl_Interp *ip, sock->msg_buf= 0; sock->ifname= TALLOC(strlen(ifr.ifr_name)+1); strcpy(sock->ifname, ifr.ifr_name); - scriptinv_init(&sock->script); + cht_scriptinv_init(&sock->script); *sock_r= sock; return TCL_OK; } -int do_tuntap_socket_raw_receive(ClientData cd, Tcl_Interp *ip, +int cht_do_tuntapsocket_receive(ClientData cd, Tcl_Interp *ip, void *sock_v, HBytes_Value data) { TuntapSocket *sock= sock_v; int l, r; r= write(sock->fd, - hbytes_data(&data), l=hbytes_len(&data)); - if (r==-1) return posixerr(ip,errno,"write tuntap"); - else if (r!=l) return staticerr(ip,"write tuntap gave wrong answer",0); + cht_hb_data(&data), l=cht_hb_len(&data)); + if (r==-1) return cht_posixerr(ip,errno,"write tuntap"); + else if (r!=l) return cht_staticerr(ip,"write tuntap gave wrong answer",0); return TCL_OK; } -int do_tuntap_socket_raw_ifname(ClientData cd, Tcl_Interp *ip, +int cht_do_tuntapsocket_ifname(ClientData cd, Tcl_Interp *ip, void *sock_v, const char **result) { TuntapSocket *sock= sock_v; *result= sock->ifname; @@ -85,8 +78,8 @@ int do_tuntap_socket_raw_ifname(ClientData cd, Tcl_Interp *ip, } static void cancel(TuntapSocket *sock) { - if (sock->script.obj) { - scriptinv_cancel(&sock->script); + if (sock->script.script) { + cht_scriptinv_cancel(&sock->script); Tcl_DeleteFileHandler(sock->fd); TFREE(sock->msg_buf); sock->msg_buf= 0; @@ -104,35 +97,35 @@ static void read_call(ClientData sock_cd, int mask) { sz= read(sock->fd, sock->msg_buf, sock->mtu); if (sz == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK) rc=0; - else rc= posixerr(ip,errno,"read tuntap"); + else rc= cht_posixerr(ip,errno,"read tuntap"); goto x_rc; } assert(sz <= sock->mtu); - hbytes_array(&message_val, sock->msg_buf, sz); - args[0]= ret_hb(ip, message_val); hbytes_empty(&message_val); - args[1]= ret_iddata(ip, sock, &tuntap_socks); - scriptinv_invoke(&sock->script, 2, args); + cht_hb_array(&message_val, sock->msg_buf, sz); + args[0]= cht_ret_hb(ip, message_val); cht_hb_empty(&message_val); + args[1]= cht_ret_iddata(ip, sock, &cht_tuntap_socks); + cht_scriptinv_invoke(&sock->script, 2, args); } x_rc: if (rc) Tcl_BackgroundError(ip); } -int do_tuntap_socket_raw_on_transmit(ClientData cd, Tcl_Interp *ip, +int cht_do_tuntapsocket_on_transmit(ClientData cd, Tcl_Interp *ip, void *sock_v, long mtu, Tcl_Obj *newscript) { TuntapSocket *sock= sock_v; int rc; if (mtu > 65536) - return staticerr(ip,"tuntap mtu >2^16","TUNTAP MTU OVERRUN"); + return cht_staticerr(ip,"tuntap mtu >2^16","TUNTAP MTU OVERRUN"); cancel(sock); if (newscript) { - rc= scriptinv_set(&sock->script,ip,newscript); + rc= cht_scriptinv_set(&sock->script,ip,newscript,0); if (rc) return rc; sock->mtu= mtu; @@ -142,15 +135,26 @@ int do_tuntap_socket_raw_on_transmit(ClientData cd, Tcl_Interp *ip, return TCL_OK; } -int do_tuntap_socket_raw_close(ClientData cd, Tcl_Interp *ip, void *sock_v) { +static void destroy(void *sock_v) { TuntapSocket *sock= sock_v; - - int sockix; cancel(sock); close(sock->fd); /* nothing useful to be done with errors */ - sockix= sock->ix; TFREE(sock->msg_buf); TFREE(sock); - tuntap_socks.a[sockix]= 0; +} + +static void destroy_idtabcb(Tcl_Interp *ip, void *sock_v) { + destroy(sock_v); +} + +int cht_do_tuntapsocket_close(ClientData cd, Tcl_Interp *ip, void *sock) { + cht_tabledataid_disposing(ip,sock,&cht_tuntap_socks); + destroy(sock); return TCL_OK; } + +const IdDataSpec cht_tuntap_socks= { + "tuntap", "tuntap-table", destroy_idtabcb +}; + +CHT_INIT(tuntap, { }, CHTI_COMMANDS(cht_tuntaptoplevel_entries))