mirror of
https://github.com/adulau/ssldump.git
synced 2024-11-21 17:07:04 +00:00
Lint ALL the things !
This commit is contained in:
parent
26a3816051
commit
ecacee7c36
58 changed files with 8234 additions and 9935 deletions
230
base/network.c
230
base/network.c
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: network.c,v 1.10 2002/09/09 21:02:58 ekr Exp $
|
$Id: network.c,v 1.10 2002/09/09 21:02:58 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,8 +44,6 @@
|
||||||
ekr@rtfm.com Tue Dec 29 09:52:54 1998
|
ekr@rtfm.com Tue Dec 29 09:52:54 1998
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <r_common.h>
|
#include <r_common.h>
|
||||||
#include "network.h"
|
#include "network.h"
|
||||||
|
@ -68,46 +67,44 @@ struct network_handler_ {
|
||||||
proto_ctx *ctx;
|
proto_ctx *ctx;
|
||||||
};
|
};
|
||||||
|
|
||||||
int
|
int network_handler_create(proto_mod *mod, n_handler **handlerp) {
|
||||||
network_handler_create (proto_mod *mod, n_handler **handlerp)
|
int r, _status;
|
||||||
{
|
n_handler *handler = 0;
|
||||||
int r,_status;
|
|
||||||
n_handler *handler=0;
|
|
||||||
|
|
||||||
if(!(handler=(n_handler *)malloc(sizeof(n_handler))))
|
if(!(handler = (n_handler *)malloc(sizeof(n_handler))))
|
||||||
ABORT(R_NO_MEMORY);
|
ABORT(R_NO_MEMORY);
|
||||||
if(mod->vtbl->create_ctx){
|
if(mod->vtbl->create_ctx) {
|
||||||
if((r=mod->vtbl->create_ctx(mod->handle,&handler->ctx)))
|
if((r = mod->vtbl->create_ctx(mod->handle, &handler->ctx)))
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
}
|
}
|
||||||
handler->mod=mod;
|
handler->mod = mod;
|
||||||
*handlerp=handler;
|
*handlerp = handler;
|
||||||
_status=0;
|
_status = 0;
|
||||||
abort:
|
abort:
|
||||||
if(_status){
|
if(_status) {
|
||||||
network_handler_destroy(mod, &handler);
|
network_handler_destroy(mod, &handler);
|
||||||
}
|
}
|
||||||
return(_status);
|
return (_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int network_handler_destroy(proto_mod *mod, n_handler **handlerp) {
|
||||||
network_handler_destroy (proto_mod *mod, n_handler **handlerp)
|
n_handler *handler = 0;
|
||||||
{
|
|
||||||
n_handler *handler=0;
|
|
||||||
if(!handlerp || !*handlerp)
|
if(!handlerp || !*handlerp)
|
||||||
return(0);
|
return (0);
|
||||||
|
|
||||||
handler = *handlerp;
|
handler = *handlerp;
|
||||||
|
|
||||||
mod->vtbl->destroy_ctx(mod->handle,&handler->ctx);
|
mod->vtbl->destroy_ctx(mod->handle, &handler->ctx);
|
||||||
free(*handlerp);
|
free(*handlerp);
|
||||||
*handlerp=0;
|
*handlerp = 0;
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int network_process_packet(n_handler *handler,
|
||||||
network_process_packet (n_handler *handler, struct timeval *timestamp, UCHAR *data, int length, int af)
|
struct timeval *timestamp,
|
||||||
{
|
UCHAR *data,
|
||||||
|
int length,
|
||||||
|
int af) {
|
||||||
int r;
|
int r;
|
||||||
int hlen;
|
int hlen;
|
||||||
packet p;
|
packet p;
|
||||||
|
@ -115,197 +112,202 @@ network_process_packet (n_handler *handler, struct timeval *timestamp, UCHAR *da
|
||||||
int proto;
|
int proto;
|
||||||
|
|
||||||
/*We can pretty much ignore all the options*/
|
/*We can pretty much ignore all the options*/
|
||||||
memcpy(&p.ts,timestamp,sizeof(struct timeval));
|
memcpy(&p.ts, timestamp, sizeof(struct timeval));
|
||||||
p.base=data;
|
p.base = data;
|
||||||
p._len=length;
|
p._len = length;
|
||||||
p.data=data;
|
p.data = data;
|
||||||
p.len=length;
|
p.len = length;
|
||||||
p.af=af;
|
p.af = af;
|
||||||
|
|
||||||
if(p.len < 20) {
|
if(p.len < 20) {
|
||||||
if(!(NET_print_flags & NET_PRINT_JSON))
|
if(!(NET_print_flags & NET_PRINT_JSON))
|
||||||
printf("Malformed packet, packet too small to contain IP header, skipping ...\n");
|
printf(
|
||||||
return(0);
|
"Malformed packet, packet too small to contain IP header, skipping "
|
||||||
|
"...\n");
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&p.i_addr.so_st, 0x0, sizeof(struct sockaddr_storage));
|
memset(&p.i_addr.so_st, 0x0, sizeof(struct sockaddr_storage));
|
||||||
memset(&p.r_addr.so_st, 0x0, sizeof(struct sockaddr_storage));
|
memset(&p.r_addr.so_st, 0x0, sizeof(struct sockaddr_storage));
|
||||||
|
|
||||||
if(af == AF_INET) {
|
if(af == AF_INET) {
|
||||||
p.l3_hdr.ip=(struct ip *)data;
|
p.l3_hdr.ip = (struct ip *)data;
|
||||||
memcpy(&p.i_addr.so_in.sin_addr, &p.l3_hdr.ip->ip_src, sizeof(struct in_addr));
|
memcpy(&p.i_addr.so_in.sin_addr, &p.l3_hdr.ip->ip_src,
|
||||||
|
sizeof(struct in_addr));
|
||||||
p.i_addr.so_in.sin_family = AF_INET;
|
p.i_addr.so_in.sin_family = AF_INET;
|
||||||
memcpy(&p.r_addr.so_in.sin_addr, &p.l3_hdr.ip->ip_dst, sizeof(struct in_addr));
|
memcpy(&p.r_addr.so_in.sin_addr, &p.l3_hdr.ip->ip_dst,
|
||||||
|
sizeof(struct in_addr));
|
||||||
p.r_addr.so_in.sin_family = AF_INET;
|
p.r_addr.so_in.sin_family = AF_INET;
|
||||||
|
|
||||||
/*Handle, or rather mishandle, fragmentation*/
|
/*Handle, or rather mishandle, fragmentation*/
|
||||||
off=ntohs(p.l3_hdr.ip->ip_off);
|
off = ntohs(p.l3_hdr.ip->ip_off);
|
||||||
|
|
||||||
if((off & 0x1fff) || /*Later fragment*/
|
if((off & 0x1fff) || /*Later fragment*/
|
||||||
(off & 0x2000)){ /*More fragments*/
|
(off & 0x2000)) { /*More fragments*/
|
||||||
/* fprintf(stderr,"Fragmented packet! rejecting\n"); */
|
/* fprintf(stderr,"Fragmented packet! rejecting\n"); */
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
hlen=p.l3_hdr.ip->ip_hl * 4;
|
hlen = p.l3_hdr.ip->ip_hl * 4;
|
||||||
p.data += hlen;
|
p.data += hlen;
|
||||||
p.len = ntohs(p.l3_hdr.ip->ip_len);
|
p.len = ntohs(p.l3_hdr.ip->ip_len);
|
||||||
|
|
||||||
if(p.len > length) {
|
if(p.len > length) {
|
||||||
if(!(NET_print_flags & NET_PRINT_JSON))
|
if(!(NET_print_flags & NET_PRINT_JSON))
|
||||||
printf("Malformed packet, size from IP header is larger than size reported by libpcap, skipping ...\n");
|
printf(
|
||||||
return(0);
|
"Malformed packet, size from IP header is larger than size "
|
||||||
|
"reported by libpcap, skipping ...\n");
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p.len == 0) {
|
if(p.len == 0) {
|
||||||
DBG((0,"ip length reported as 0, presumed to be because of 'TCP segmentation offload' (TSO)\n"));
|
DBG((0,
|
||||||
|
"ip length reported as 0, presumed to be because of 'TCP "
|
||||||
|
"segmentation offload' (TSO)\n"));
|
||||||
p.len = p._len;
|
p.len = p._len;
|
||||||
}
|
}
|
||||||
p.len -= hlen;
|
p.len -= hlen;
|
||||||
|
|
||||||
proto = p.l3_hdr.ip->ip_p;
|
proto = p.l3_hdr.ip->ip_p;
|
||||||
} else {
|
} else {
|
||||||
p.l3_hdr.ip6=(struct ip6_hdr *)data;
|
p.l3_hdr.ip6 = (struct ip6_hdr *)data;
|
||||||
memcpy(&p.i_addr.so_in6.sin6_addr, &p.l3_hdr.ip6->ip6_src, sizeof(struct in6_addr));
|
memcpy(&p.i_addr.so_in6.sin6_addr, &p.l3_hdr.ip6->ip6_src,
|
||||||
|
sizeof(struct in6_addr));
|
||||||
p.i_addr.so_in6.sin6_family = AF_INET6;
|
p.i_addr.so_in6.sin6_family = AF_INET6;
|
||||||
memcpy(&p.r_addr.so_in6.sin6_addr, &p.l3_hdr.ip6->ip6_dst, sizeof(struct in6_addr));
|
memcpy(&p.r_addr.so_in6.sin6_addr, &p.l3_hdr.ip6->ip6_dst,
|
||||||
|
sizeof(struct in6_addr));
|
||||||
p.r_addr.so_in6.sin6_family = AF_INET6;
|
p.r_addr.so_in6.sin6_family = AF_INET6;
|
||||||
// Skip packets with header extensions
|
// Skip packets with header extensions
|
||||||
if(p.l3_hdr.ip6->ip6_ctlun.ip6_un1.ip6_un1_nxt != IPPROTO_TCP) {
|
if(p.l3_hdr.ip6->ip6_ctlun.ip6_un1.ip6_un1_nxt != IPPROTO_TCP) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
hlen=40; // Fixed header size with no extension
|
hlen = 40; // Fixed header size with no extension
|
||||||
p.data += hlen;
|
p.data += hlen;
|
||||||
p.len = ntohs(p.l3_hdr.ip6->ip6_ctlun.ip6_un1.ip6_un1_plen);
|
p.len = ntohs(p.l3_hdr.ip6->ip6_ctlun.ip6_un1.ip6_un1_plen);
|
||||||
if(p.len > length) {
|
if(p.len > length) {
|
||||||
if(!(NET_print_flags & NET_PRINT_JSON))
|
if(!(NET_print_flags & NET_PRINT_JSON))
|
||||||
printf("Malformed packet, size from IP header is larger than size reported by libpcap, skipping ...\n");
|
printf(
|
||||||
return(0);
|
"Malformed packet, size from IP header is larger than size "
|
||||||
|
"reported by libpcap, skipping ...\n");
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p.len == 0) {
|
if(p.len == 0) {
|
||||||
DBG((0,"ip length reported as 0, presumed to be because of 'TCP segmentation offload' (TSO)\n"));
|
DBG((0,
|
||||||
|
"ip length reported as 0, presumed to be because of 'TCP "
|
||||||
|
"segmentation offload' (TSO)\n"));
|
||||||
p.len = p._len;
|
p.len = p._len;
|
||||||
}
|
}
|
||||||
|
|
||||||
proto = p.l3_hdr.ip6->ip6_ctlun.ip6_un1.ip6_un1_nxt;
|
proto = p.l3_hdr.ip6->ip6_ctlun.ip6_un1.ip6_un1_nxt;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(proto){
|
switch(proto) {
|
||||||
case IPPROTO_TCP:
|
case IPPROTO_TCP:
|
||||||
if((r=process_tcp_packet(handler->mod,handler->ctx,&p)))
|
if((r = process_tcp_packet(handler->mod, handler->ctx, &p)))
|
||||||
ERETURN(r);
|
ERETURN(r);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int packet_copy(packet *in, packet **out) {
|
||||||
packet_copy (packet *in, packet **out)
|
|
||||||
{
|
|
||||||
int _status;
|
int _status;
|
||||||
|
|
||||||
packet *p=0;
|
packet *p = 0;
|
||||||
|
|
||||||
if(!(p=(packet *)calloc(1,sizeof(packet))))
|
if(!(p = (packet *)calloc(1, sizeof(packet))))
|
||||||
ABORT(R_NO_MEMORY);
|
ABORT(R_NO_MEMORY);
|
||||||
|
|
||||||
memcpy(&p->ts,&in->ts,sizeof(struct timeval));
|
memcpy(&p->ts, &in->ts, sizeof(struct timeval));
|
||||||
if(!(p->base=(UCHAR *)malloc(in->_len)))
|
if(!(p->base = (UCHAR *)malloc(in->_len)))
|
||||||
ABORT(R_NO_MEMORY);
|
ABORT(R_NO_MEMORY);
|
||||||
memcpy(p->base,in->base,p->_len=in->_len);
|
memcpy(p->base, in->base, p->_len = in->_len);
|
||||||
|
|
||||||
p->data=p->base + (in->data - in->base);
|
p->data = p->base + (in->data - in->base);
|
||||||
p->len=in->len;
|
p->len = in->len;
|
||||||
|
|
||||||
p->ip=(struct ip *)(p->base + ((UCHAR *)in->ip - in->base));
|
p->ip = (struct ip *)(p->base + ((UCHAR *)in->ip - in->base));
|
||||||
p->tcp=(struct tcphdr *)(p->base + ((UCHAR *)in->tcp - in->base));
|
p->tcp = (struct tcphdr *)(p->base + ((UCHAR *)in->tcp - in->base));
|
||||||
|
|
||||||
*out=p;
|
*out = p;
|
||||||
|
|
||||||
_status=0;
|
_status = 0;
|
||||||
abort:
|
abort:
|
||||||
if(_status){
|
if(_status) {
|
||||||
packet_destroy(p);
|
packet_destroy(p);
|
||||||
}
|
}
|
||||||
return(_status);
|
return (_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int packet_destroy(packet *p) {
|
||||||
packet_destroy (packet *p)
|
|
||||||
{
|
|
||||||
if(!p)
|
if(!p)
|
||||||
return(0);
|
return (0);
|
||||||
|
|
||||||
FREE(p->base);
|
FREE(p->base);
|
||||||
FREE(p);
|
FREE(p);
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int timestamp_diff(struct timeval *t1,
|
||||||
timestamp_diff (struct timeval *t1, struct timeval *t0, struct timeval *diff)
|
struct timeval *t0,
|
||||||
{
|
struct timeval *diff) {
|
||||||
long d;
|
long d;
|
||||||
|
|
||||||
if(t0->tv_sec > t1->tv_sec)
|
if(t0->tv_sec > t1->tv_sec)
|
||||||
ERETURN(R_BAD_ARGS);
|
ERETURN(R_BAD_ARGS);
|
||||||
|
|
||||||
/*Easy case*/
|
/*Easy case*/
|
||||||
if(t0->tv_usec <= t1->tv_usec){
|
if(t0->tv_usec <= t1->tv_usec) {
|
||||||
diff->tv_sec=t1->tv_sec - t0->tv_sec;
|
diff->tv_sec = t1->tv_sec - t0->tv_sec;
|
||||||
diff->tv_usec=t1->tv_usec - t0->tv_usec;
|
diff->tv_usec = t1->tv_usec - t0->tv_usec;
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Hard case*/
|
/*Hard case*/
|
||||||
d=t0->tv_usec - t1->tv_usec;
|
d = t0->tv_usec - t1->tv_usec;
|
||||||
if(t1->tv_sec < (t0->tv_sec + 1))
|
if(t1->tv_sec < (t0->tv_sec + 1))
|
||||||
ERETURN(R_BAD_ARGS);
|
ERETURN(R_BAD_ARGS);
|
||||||
diff->tv_sec=t1->tv_sec - (t0->tv_sec + 1);
|
diff->tv_sec = t1->tv_sec - (t0->tv_sec + 1);
|
||||||
diff->tv_usec=1000000 - d;
|
diff->tv_usec = 1000000 - d;
|
||||||
|
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int lookuphostname(struct sockaddr_storage *so_st, char **namep) {
|
||||||
|
|
||||||
int
|
|
||||||
lookuphostname (struct sockaddr_storage *so_st, char **namep)
|
|
||||||
{
|
|
||||||
int r = 1;
|
int r = 1;
|
||||||
*namep = calloc(1, NI_MAXHOST);
|
*namep = calloc(1, NI_MAXHOST);
|
||||||
void *addr = NULL;
|
void *addr = NULL;
|
||||||
|
|
||||||
if(!(NET_print_flags & NET_PRINT_NO_RESOLVE)) {
|
if(!(NET_print_flags & NET_PRINT_NO_RESOLVE)) {
|
||||||
r = getnameinfo((struct sockaddr *) so_st, sizeof(struct sockaddr_storage), *namep, NI_MAXHOST, NULL, 0, 0);
|
r = getnameinfo((struct sockaddr *)so_st, sizeof(struct sockaddr_storage),
|
||||||
|
*namep, NI_MAXHOST, NULL, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(r) {
|
if(r) {
|
||||||
if(so_st->ss_family == AF_INET) {
|
if(so_st->ss_family == AF_INET) {
|
||||||
addr = &((struct sockaddr_in *) so_st)->sin_addr;
|
addr = &((struct sockaddr_in *)so_st)->sin_addr;
|
||||||
} else {
|
} else {
|
||||||
addr = &((struct sockaddr_in6 *) so_st)->sin6_addr;
|
addr = &((struct sockaddr_in6 *)so_st)->sin6_addr;
|
||||||
}
|
}
|
||||||
inet_ntop(so_st->ss_family, addr, *namep, INET6_ADDRSTRLEN);
|
inet_ntop(so_st->ss_family, addr, *namep, INET6_ADDRSTRLEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int addrtotext(struct sockaddr_storage *so_st, char **namep) {
|
||||||
addrtotext (struct sockaddr_storage *so_st, char **namep)
|
|
||||||
{
|
|
||||||
*namep = calloc(1, NI_MAXHOST);
|
*namep = calloc(1, NI_MAXHOST);
|
||||||
void *addr = NULL;
|
void *addr = NULL;
|
||||||
|
|
||||||
if(so_st->ss_family == AF_INET) {
|
if(so_st->ss_family == AF_INET) {
|
||||||
addr = &((struct sockaddr_in *) so_st)->sin_addr;
|
addr = &((struct sockaddr_in *)so_st)->sin_addr;
|
||||||
} else {
|
} else {
|
||||||
addr = &((struct sockaddr_in6 *) so_st)->sin6_addr;
|
addr = &((struct sockaddr_in6 *)so_st)->sin6_addr;
|
||||||
}
|
}
|
||||||
inet_ntop(so_st->ss_family, addr, *namep, INET6_ADDRSTRLEN);
|
inet_ntop(so_st->ss_family, addr, *namep, INET6_ADDRSTRLEN);
|
||||||
|
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: network.h,v 1.3 2001/09/14 22:29:14 ekr Exp $
|
$Id: network.h,v 1.3 2001/09/14 22:29:14 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,7 +44,6 @@
|
||||||
ekr@rtfm.com Tue Dec 29 09:53:50 1998
|
ekr@rtfm.com Tue Dec 29 09:53:50 1998
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _network_h
|
#ifndef _network_h
|
||||||
#define _network_h
|
#define _network_h
|
||||||
|
|
||||||
|
@ -74,17 +74,20 @@ typedef struct proto_mod_ proto_mod;
|
||||||
typedef struct proto_handler_ proto_handler;
|
typedef struct proto_handler_ proto_handler;
|
||||||
typedef struct packet_ packet;
|
typedef struct packet_ packet;
|
||||||
|
|
||||||
int network_handler_create PROTO_LIST((proto_mod *mod,
|
int network_handler_create PROTO_LIST((proto_mod * mod, n_handler **handlerp));
|
||||||
n_handler **handlerp));
|
int network_handler_destroy PROTO_LIST((proto_mod * mod, n_handler **handlerp));
|
||||||
int network_handler_destroy PROTO_LIST((proto_mod *mod,n_handler **handlerp));
|
int network_process_packet PROTO_LIST((n_handler * handler,
|
||||||
int network_process_packet PROTO_LIST((n_handler *handler,
|
struct timeval *timestamp,
|
||||||
struct timeval *timestamp,UCHAR *data,int length,int af));
|
UCHAR *data,
|
||||||
int packet_copy PROTO_LIST((packet *in,packet **out));
|
int length,
|
||||||
int packet_destroy PROTO_LIST((packet *p));
|
int af));
|
||||||
int timestamp_diff PROTO_LIST(( struct timeval *t1,struct timeval *t0,
|
int packet_copy PROTO_LIST((packet * in, packet **out));
|
||||||
|
int packet_destroy PROTO_LIST((packet * p));
|
||||||
|
int timestamp_diff PROTO_LIST((struct timeval * t1,
|
||||||
|
struct timeval *t0,
|
||||||
struct timeval *diff));
|
struct timeval *diff));
|
||||||
int lookuphostname PROTO_LIST((struct sockaddr_storage *addr,char **name));
|
int lookuphostname PROTO_LIST((struct sockaddr_storage * addr, char **name));
|
||||||
int addrtotext PROTO_LIST((struct sockaddr_storage *addr,char **name));
|
int addrtotext PROTO_LIST((struct sockaddr_storage * addr, char **name));
|
||||||
|
|
||||||
struct packet_ {
|
struct packet_ {
|
||||||
struct timeval ts;
|
struct timeval ts;
|
||||||
|
@ -126,4 +129,3 @@ extern UINT4 NET_print_flags;
|
||||||
#define NET_PRINT_JSON 16
|
#define NET_PRINT_JSON 16
|
||||||
#define NET_PRINT_TS 32
|
#define NET_PRINT_TS 32
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -46,9 +46,6 @@
|
||||||
ekr@rtfm.com Tue Dec 29 10:17:41 1998
|
ekr@rtfm.com Tue Dec 29 10:17:41 1998
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <pcap.h>
|
#include <pcap.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#ifndef __OpenBSD__
|
#ifndef __OpenBSD__
|
||||||
|
@ -80,49 +77,50 @@
|
||||||
#include "pcap_logger.h"
|
#include "pcap_logger.h"
|
||||||
|
|
||||||
#ifndef ETHERTYPE_8021Q
|
#ifndef ETHERTYPE_8021Q
|
||||||
# define ETHERTYPE_8021Q 0x8100
|
#define ETHERTYPE_8021Q 0x8100
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
char *collapse_args PROTO_LIST((int argc,char **argv));
|
char *collapse_args PROTO_LIST((int argc, char **argv));
|
||||||
static int pcap_if_type=DLT_NULL;
|
static int pcap_if_type = DLT_NULL;
|
||||||
int err_exit PROTO_LIST((char *str,int num));
|
int err_exit PROTO_LIST((char *str, int num));
|
||||||
int usage PROTO_LIST((void));
|
int usage PROTO_LIST((void));
|
||||||
int print_version PROTO_LIST((void));
|
int print_version PROTO_LIST((void));
|
||||||
void sig_handler PROTO_LIST((int sig));
|
void sig_handler PROTO_LIST((int sig));
|
||||||
void pcap_cb PROTO_LIST((u_char *ptr,const struct pcap_pkthdr *hdr,const u_char *data));
|
void pcap_cb PROTO_LIST((u_char * ptr,
|
||||||
int main PROTO_LIST((int argc,char **argv));
|
const struct pcap_pkthdr *hdr,
|
||||||
|
const u_char *data));
|
||||||
|
int main PROTO_LIST((int argc, char **argv));
|
||||||
|
|
||||||
int packet_cnt = 0; // Packet counter used for connection pool cleaning
|
int packet_cnt = 0; // Packet counter used for connection pool cleaning
|
||||||
int conn_freq = 100; // Number of packets after which a connection pool
|
int conn_freq = 100; // Number of packets after which a connection pool
|
||||||
// cleaning is performed
|
// cleaning is performed
|
||||||
int conn_ttl = 100; // TTL of inactive connections in connection pool
|
int conn_ttl = 100; // TTL of inactive connections in connection pool
|
||||||
struct timeval last_packet_seen_time = // Timestamp of the last packet of the
|
struct timeval last_packet_seen_time = // Timestamp of the last packet of the
|
||||||
(struct timeval) {0}; // last block of conn_freq packets seen
|
(struct timeval){0}; // last block of conn_freq packets seen
|
||||||
|
|
||||||
logger_mod *logger=NULL;
|
logger_mod *logger = NULL;
|
||||||
|
|
||||||
int
|
int err_exit(char *str, int num) {
|
||||||
err_exit (char *str, int num)
|
fprintf(stderr, "ERROR: %s\n", str);
|
||||||
{
|
|
||||||
fprintf(stderr,"ERROR: %s\n",str);
|
|
||||||
sig_handler(SIGQUIT);
|
sig_handler(SIGQUIT);
|
||||||
exit(num);
|
exit(num);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int usage(void) {
|
||||||
usage (void)
|
fprintf(stderr,
|
||||||
{
|
"Usage: ssldump [-r dumpfile] [-i interface] [-l sslkeylogfile] [-w "
|
||||||
fprintf(stderr,"Usage: ssldump [-r dumpfile] [-i interface] [-l sslkeylogfile] [-w outpcapfile]\n");
|
"outpcapfile]\n");
|
||||||
fprintf(stderr," [-k keyfile] [-p password] [-vtaTznsAxVNde]\n");
|
fprintf(stderr,
|
||||||
fprintf(stderr," [filter]\n");
|
" [-k keyfile] [-p password] [-vtaTznsAxVNde]\n");
|
||||||
|
fprintf(stderr, " [filter]\n");
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int print_version(void) {
|
||||||
print_version (void)
|
|
||||||
{
|
|
||||||
printf("Version: @ssldump_VERSION@ (@ssldump_DESCRIPTION@)\n");
|
printf("Version: @ssldump_VERSION@ (@ssldump_DESCRIPTION@)\n");
|
||||||
printf("Maintained by a bunch of volunteers, see https://github.com/adulau/ssldump/blob/master/CREDITS\n");
|
printf(
|
||||||
|
"Maintained by a bunch of volunteers, see "
|
||||||
|
"https://github.com/adulau/ssldump/blob/master/CREDITS\n");
|
||||||
printf("Copyright (C) 2015-2023 the aforementioned volunteers\n");
|
printf("Copyright (C) 2015-2023 the aforementioned volunteers\n");
|
||||||
printf("Copyright (C) 1998-2001 RTFM, Inc.\n");
|
printf("Copyright (C) 1998-2001 RTFM, Inc.\n");
|
||||||
printf("All rights reserved.\n");
|
printf("All rights reserved.\n");
|
||||||
|
@ -130,24 +128,24 @@ print_version (void)
|
||||||
printf("Compiled with OpenSSL: decryption enabled\n");
|
printf("Compiled with OpenSSL: decryption enabled\n");
|
||||||
#endif
|
#endif
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
pcap_t *p;
|
pcap_t *p;
|
||||||
proto_mod *mod=&ssl_mod;
|
proto_mod *mod = &ssl_mod;
|
||||||
n_handler *n;
|
n_handler *n;
|
||||||
char *interface_name=0;
|
char *interface_name = 0;
|
||||||
char *file=0;
|
char *file = 0;
|
||||||
char *filter=0;
|
char *filter = 0;
|
||||||
void sig_handler(int sig)
|
void sig_handler(int sig) {
|
||||||
{
|
|
||||||
int freed_conn = 0;
|
int freed_conn = 0;
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
if (logger)
|
if(logger)
|
||||||
logger->vtbl->deinit();
|
logger->vtbl->deinit();
|
||||||
|
|
||||||
freed_conn = destroy_all_conn();
|
freed_conn = destroy_all_conn();
|
||||||
if(freed_conn && !(NET_print_flags & NET_PRINT_JSON))
|
if(freed_conn && !(NET_print_flags & NET_PRINT_JSON))
|
||||||
printf("Cleaned %d remaining connection(s) from connection pool\n", freed_conn);
|
printf("Cleaned %d remaining connection(s) from connection pool\n",
|
||||||
|
freed_conn);
|
||||||
|
|
||||||
network_handler_destroy(mod, &n);
|
network_handler_destroy(mod, &n);
|
||||||
|
|
||||||
|
@ -161,77 +159,80 @@ void sig_handler(int sig)
|
||||||
free(file);
|
free(file);
|
||||||
|
|
||||||
exit(sig);
|
exit(sig);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pcap_cb(u_char *ptr, const struct pcap_pkthdr *hdr, const u_char *data)
|
void pcap_cb(u_char *ptr, const struct pcap_pkthdr *hdr, const u_char *data) {
|
||||||
{
|
|
||||||
n_handler *n;
|
n_handler *n;
|
||||||
int len;
|
int len;
|
||||||
struct ether_header *e_hdr=(struct ether_header *)data;
|
struct ether_header *e_hdr = (struct ether_header *)data;
|
||||||
int type, cleaned_conn;
|
int type, cleaned_conn;
|
||||||
|
|
||||||
n=(n_handler *)ptr;
|
n = (n_handler *)ptr;
|
||||||
if(hdr->caplen!=hdr->len) err_exit("Length mismatch",-1);
|
if(hdr->caplen != hdr->len)
|
||||||
|
err_exit("Length mismatch", -1);
|
||||||
|
|
||||||
len=hdr->len;
|
len = hdr->len;
|
||||||
|
|
||||||
switch(pcap_if_type){
|
switch(pcap_if_type) {
|
||||||
case DLT_RAW:
|
case DLT_RAW:
|
||||||
#ifdef DLT_LOOP
|
#ifdef DLT_LOOP
|
||||||
case DLT_LOOP:
|
case DLT_LOOP:
|
||||||
#endif
|
#endif
|
||||||
case DLT_NULL:
|
case DLT_NULL:
|
||||||
data+=4;
|
data += 4;
|
||||||
len-=4;
|
len -= 4;
|
||||||
break;
|
break;
|
||||||
case DLT_EN10MB:
|
case DLT_EN10MB:
|
||||||
if(len < sizeof(struct ether_header)) {
|
if(len < sizeof(struct ether_header)) {
|
||||||
if(!(NET_print_flags & NET_PRINT_JSON))
|
if(!(NET_print_flags & NET_PRINT_JSON))
|
||||||
printf("Frame size too small to contain Ethernet header, skipping ...\n");
|
printf(
|
||||||
|
"Frame size too small to contain Ethernet header, skipping "
|
||||||
|
"...\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
type=ntohs(e_hdr->ether_type);
|
type = ntohs(e_hdr->ether_type);
|
||||||
|
|
||||||
data+=sizeof(struct ether_header);
|
data += sizeof(struct ether_header);
|
||||||
len-=sizeof(struct ether_header);
|
len -= sizeof(struct ether_header);
|
||||||
|
|
||||||
/* if vlans, push past VLAN header (4 bytes) */
|
/* if vlans, push past VLAN header (4 bytes) */
|
||||||
if(type==ETHERTYPE_8021Q) {
|
if(type == ETHERTYPE_8021Q) {
|
||||||
type=ntohs(*(u_int16_t *)(data + 2));
|
type = ntohs(*(u_int16_t *)(data + 2));
|
||||||
|
|
||||||
data+=4;
|
data += 4;
|
||||||
len+=4;
|
len += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(type!=ETHERTYPE_IP && type!=ETHERTYPE_IPV6)
|
if(type != ETHERTYPE_IP && type != ETHERTYPE_IPV6)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case DLT_IEEE802:
|
case DLT_IEEE802:
|
||||||
data+=22;
|
data += 22;
|
||||||
len-=22;
|
len -= 22;
|
||||||
break;
|
break;
|
||||||
case DLT_FDDI:
|
case DLT_FDDI:
|
||||||
data+=21;
|
data += 21;
|
||||||
len-=21;
|
len -= 21;
|
||||||
break;
|
break;
|
||||||
#ifdef __amigaos__
|
#ifdef __amigaos__
|
||||||
case DLT_MIAMI:
|
case DLT_MIAMI:
|
||||||
data+=16;
|
data += 16;
|
||||||
len-=16;
|
len -= 16;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case DLT_SLIP:
|
case DLT_SLIP:
|
||||||
#ifdef DLT_SLIP_BSDOS
|
#ifdef DLT_SLIP_BSDOS
|
||||||
case DLT_SLIP_BSDOS:
|
case DLT_SLIP_BSDOS:
|
||||||
#endif
|
#endif
|
||||||
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__bsdi__) || defined(__APPLE__)
|
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || \
|
||||||
data+=16;
|
defined(__bsdi__) || defined(__APPLE__)
|
||||||
len-=16;
|
data += 16;
|
||||||
|
len -= 16;
|
||||||
#else
|
#else
|
||||||
data+=24;
|
data += 24;
|
||||||
len-=24;
|
len -= 24;
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case DLT_PPP:
|
case DLT_PPP:
|
||||||
|
@ -244,74 +245,73 @@ void pcap_cb(u_char *ptr, const struct pcap_pkthdr *hdr, const u_char *data)
|
||||||
#ifdef DLT_PPP_ETHER
|
#ifdef DLT_PPP_ETHER
|
||||||
case DLT_PPP_ETHER:
|
case DLT_PPP_ETHER:
|
||||||
#endif
|
#endif
|
||||||
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__bsdi__) || defined(__APPLE__)
|
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || \
|
||||||
data+=4;
|
defined(__bsdi__) || defined(__APPLE__)
|
||||||
len-=4;
|
data += 4;
|
||||||
|
len -= 4;
|
||||||
#else
|
#else
|
||||||
#if defined(sun) || defined(__sun)
|
#if defined(sun) || defined(__sun)
|
||||||
data+=8;
|
data += 8;
|
||||||
len-=8;
|
len -= 8;
|
||||||
#else
|
#else
|
||||||
data+=24;
|
data += 24;
|
||||||
len-=24;
|
len -= 24;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
#ifdef DLT_ENC
|
#ifdef DLT_ENC
|
||||||
case DLT_ENC:
|
case DLT_ENC:
|
||||||
data+=12;
|
data += 12;
|
||||||
len-=12;
|
len -= 12;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef DLT_LINUX_SLL
|
#ifdef DLT_LINUX_SLL
|
||||||
case DLT_LINUX_SLL:
|
case DLT_LINUX_SLL:
|
||||||
data+=16;
|
data += 16;
|
||||||
len-=16;
|
len -= 16;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef DLT_IPNET
|
#ifdef DLT_IPNET
|
||||||
case DLT_IPNET:
|
case DLT_IPNET:
|
||||||
data+=24;
|
data += 24;
|
||||||
len-=24;
|
len -= 24;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if(type == ETHERTYPE_IPV6)
|
if(type == ETHERTYPE_IPV6)
|
||||||
network_process_packet(n,(struct timeval *) &hdr->ts,(u_char *)data,len, AF_INET6);
|
network_process_packet(n, (struct timeval *)&hdr->ts, (u_char *)data, len,
|
||||||
|
AF_INET6);
|
||||||
else
|
else
|
||||||
network_process_packet(n,(struct timeval *) &hdr->ts,(u_char *)data,len, AF_INET);
|
network_process_packet(n, (struct timeval *)&hdr->ts, (u_char *)data, len,
|
||||||
|
AF_INET);
|
||||||
|
|
||||||
if(packet_cnt == conn_freq) {
|
if(packet_cnt == conn_freq) {
|
||||||
packet_cnt = 0;
|
packet_cnt = 0;
|
||||||
memcpy(&last_packet_seen_time,&hdr->ts,sizeof(struct timeval));
|
memcpy(&last_packet_seen_time, &hdr->ts, sizeof(struct timeval));
|
||||||
if((cleaned_conn = clean_old_conn()) && !(NET_print_flags & NET_PRINT_JSON))
|
if((cleaned_conn = clean_old_conn()) && !(NET_print_flags & NET_PRINT_JSON))
|
||||||
printf("%d inactive connection(s) cleaned from connection pool\n", cleaned_conn);
|
printf("%d inactive connection(s) cleaned from connection pool\n",
|
||||||
|
cleaned_conn);
|
||||||
} else {
|
} else {
|
||||||
packet_cnt++;
|
packet_cnt++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct module_def_ {
|
typedef struct module_def_ {
|
||||||
char *name;
|
char *name;
|
||||||
proto_mod *mod;
|
proto_mod *mod;
|
||||||
} module_def;
|
} module_def;
|
||||||
|
|
||||||
static module_def modules[]={
|
static module_def modules[] = {{"SSL", &ssl_mod},
|
||||||
{"SSL",&ssl_mod},
|
{"NULL", &null_mod},
|
||||||
{"NULL",&null_mod},
|
|
||||||
#ifdef ENABLE_RECORD
|
#ifdef ENABLE_RECORD
|
||||||
{"RECORD",&record_mod},
|
{"RECORD", &record_mod},
|
||||||
#endif
|
#endif
|
||||||
{0,0}
|
{0, 0}};
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
int parse_ssl_flag PROTO_LIST((int c));
|
int parse_ssl_flag PROTO_LIST((int c));
|
||||||
|
|
||||||
int
|
int main(int argc, char **argv) {
|
||||||
main (int argc, char **argv)
|
|
||||||
{
|
|
||||||
int r;
|
int r;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
__declspec(dllimport) char *optarg;
|
__declspec(dllimport) char *optarg;
|
||||||
|
@ -321,31 +321,32 @@ main (int argc, char **argv)
|
||||||
extern int optind;
|
extern int optind;
|
||||||
#endif
|
#endif
|
||||||
pcap_if_t *interfaces;
|
pcap_if_t *interfaces;
|
||||||
bpf_u_int32 localnet,netmask;
|
bpf_u_int32 localnet, netmask;
|
||||||
int c;
|
int c;
|
||||||
module_def *m=0;
|
module_def *m = 0;
|
||||||
int no_promiscuous=0;
|
int no_promiscuous = 0;
|
||||||
int freed_conn=0;
|
int freed_conn = 0;
|
||||||
|
|
||||||
char errbuf[PCAP_ERRBUF_SIZE];
|
char errbuf[PCAP_ERRBUF_SIZE];
|
||||||
|
|
||||||
signal(SIGINT,sig_handler);
|
signal(SIGINT, sig_handler);
|
||||||
|
|
||||||
while((c=getopt(argc,argv,"vr:F:f:S:jyTt:ai:k:l:w:p:znsAxXhHVNdqem:P"))!=EOF){
|
while((c = getopt(argc, argv, "vr:F:f:S:jyTt:ai:k:l:w:p:znsAxXhHVNdqem:P")) !=
|
||||||
switch(c){
|
EOF) {
|
||||||
|
switch(c) {
|
||||||
case 'v':
|
case 'v':
|
||||||
print_version();
|
print_version();
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
fprintf(stderr,"-f option replaced by -r. Use that in the future\n");
|
fprintf(stderr, "-f option replaced by -r. Use that in the future\n");
|
||||||
case 'r':
|
case 'r':
|
||||||
file=strdup(optarg);
|
file = strdup(optarg);
|
||||||
break;
|
break;
|
||||||
case 'S':
|
case 'S':
|
||||||
ssl_mod.vtbl->parse_flags(optarg);
|
ssl_mod.vtbl->parse_flags(optarg);
|
||||||
break;
|
break;
|
||||||
case 'y':
|
case 'y':
|
||||||
NET_print_flags|=NET_PRINT_TYPESET;
|
NET_print_flags |= NET_PRINT_TYPESET;
|
||||||
/*Kludge*/
|
/*Kludge*/
|
||||||
SSL_print_flags |= SSL_PRINT_NROFF;
|
SSL_print_flags |= SSL_PRINT_NROFF;
|
||||||
break;
|
break;
|
||||||
|
@ -366,24 +367,23 @@ main (int argc, char **argv)
|
||||||
NET_print_flags |= NET_PRINT_TCP_HDR;
|
NET_print_flags |= NET_PRINT_TCP_HDR;
|
||||||
break;
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
interface_name=strdup(optarg);
|
interface_name = strdup(optarg);
|
||||||
break;
|
break;
|
||||||
case 'k':
|
case 'k':
|
||||||
SSL_keyfile=strdup(optarg);
|
SSL_keyfile = strdup(optarg);
|
||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
SSL_keylogfile=strdup(optarg);
|
SSL_keylogfile = strdup(optarg);
|
||||||
break;
|
break;
|
||||||
case 'w':
|
case 'w':
|
||||||
logger=&pcap_mod;
|
logger = &pcap_mod;
|
||||||
if(logger->vtbl->init(optarg)!=0){
|
if(logger->vtbl->init(optarg) != 0) {
|
||||||
fprintf(stderr,"Can not open/create out pcap %s\n",
|
fprintf(stderr, "Can not open/create out pcap %s\n", optarg);
|
||||||
optarg);
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
SSL_password=strdup(optarg);
|
SSL_password = strdup(optarg);
|
||||||
break;
|
break;
|
||||||
case 'P':
|
case 'P':
|
||||||
++no_promiscuous;
|
++no_promiscuous;
|
||||||
|
@ -392,21 +392,20 @@ main (int argc, char **argv)
|
||||||
NET_print_flags |= NET_PRINT_NO_RESOLVE;
|
NET_print_flags |= NET_PRINT_NO_RESOLVE;
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
conn_ttl=atoi(optarg);
|
conn_ttl = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
case 'F':
|
case 'F':
|
||||||
conn_freq=atoi(optarg);
|
conn_freq = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
for(m=modules;m->name!=0;m++){
|
for(m = modules; m->name != 0; m++) {
|
||||||
if(!strcmp(m->name,optarg)){
|
if(!strcmp(m->name, optarg)) {
|
||||||
mod=m->mod;
|
mod = m->mod;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!m->name){
|
if(!m->name) {
|
||||||
fprintf(stderr,"Request analysis module %s not found\n",
|
fprintf(stderr, "Request analysis module %s not found\n", optarg);
|
||||||
optarg);
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -427,43 +426,43 @@ main (int argc, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
argv+=optind;
|
argv += optind;
|
||||||
argc-=optind;
|
argc -= optind;
|
||||||
|
|
||||||
if(!file){
|
if(!file) {
|
||||||
if(!interface_name){
|
if(!interface_name) {
|
||||||
if(pcap_findalldevs(&interfaces,errbuf)==-1) {
|
if(pcap_findalldevs(&interfaces, errbuf) == -1) {
|
||||||
fprintf(stderr,"PCAP: %s\n",errbuf);
|
fprintf(stderr, "PCAP: %s\n", errbuf);
|
||||||
err_exit("Aborting",-1);
|
err_exit("Aborting", -1);
|
||||||
}
|
}
|
||||||
interface_name=interfaces->name;
|
interface_name = interfaces->name;
|
||||||
if(!interface_name){
|
if(!interface_name) {
|
||||||
fprintf(stderr,"PCAP: %s\n",errbuf);
|
fprintf(stderr, "PCAP: %s\n", errbuf);
|
||||||
err_exit("Aborting",-1);
|
err_exit("Aborting", -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!(p=pcap_open_live(interface_name,65535,!no_promiscuous,1000,errbuf))){
|
if(!(p = pcap_open_live(interface_name, 65535, !no_promiscuous, 1000,
|
||||||
fprintf(stderr,"PCAP: %s\n",errbuf);
|
errbuf))) {
|
||||||
err_exit("Aborting",-1);
|
fprintf(stderr, "PCAP: %s\n", errbuf);
|
||||||
|
err_exit("Aborting", -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pcap_lookupnet(interface_name, &localnet, &netmask, errbuf) < 0)
|
if(pcap_lookupnet(interface_name, &localnet, &netmask, errbuf) < 0)
|
||||||
fprintf(stderr,"PCAP: %s\n", errbuf);
|
fprintf(stderr, "PCAP: %s\n", errbuf);
|
||||||
}
|
} else {
|
||||||
else{
|
if(!(p = pcap_open_offline(file, errbuf))) {
|
||||||
if(!(p=pcap_open_offline(file,errbuf))){
|
fprintf(stderr, "PCAP: %s\n", errbuf);
|
||||||
fprintf(stderr,"PCAP: %s\n",errbuf);
|
err_exit("Aborting", -1);
|
||||||
err_exit("Aborting",-1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
netmask=0;
|
netmask = 0;
|
||||||
localnet=0;
|
localnet = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(argc!=0)
|
if(argc != 0)
|
||||||
filter=collapse_args(argc,argv);
|
filter = collapse_args(argc, argv);
|
||||||
|
|
||||||
if(filter){
|
if(filter) {
|
||||||
struct bpf_program fp;
|
struct bpf_program fp;
|
||||||
|
|
||||||
/* (F5 patch)
|
/* (F5 patch)
|
||||||
|
@ -474,40 +473,39 @@ main (int argc, char **argv)
|
||||||
* untagged, then it is assumed that the user knows what she is
|
* untagged, then it is assumed that the user knows what she is
|
||||||
* doing, and the filter is not reformatted.
|
* doing, and the filter is not reformatted.
|
||||||
*/
|
*/
|
||||||
if ((pcap_datalink(p) == DLT_EN10MB) &&
|
if((pcap_datalink(p) == DLT_EN10MB) && (filter != NULL) &&
|
||||||
(filter != NULL) &&
|
(strstr(filter, "vlan") == NULL)) {
|
||||||
(strstr(filter,"vlan") == NULL)) {
|
|
||||||
char *tmp_filter;
|
char *tmp_filter;
|
||||||
char *fmt = "( (not ether proto 0x8100) and (%s) ) or ( vlan and (%s) )";
|
char *fmt = "( (not ether proto 0x8100) and (%s) ) or ( vlan and (%s) )";
|
||||||
|
|
||||||
tmp_filter = (char *)malloc((strlen(filter) * 2) + strlen(fmt) + 1);
|
tmp_filter = (char *)malloc((strlen(filter) * 2) + strlen(fmt) + 1);
|
||||||
if (tmp_filter == NULL) {
|
if(tmp_filter == NULL) {
|
||||||
fprintf(stderr,"PCAP: malloc failed\n");
|
fprintf(stderr, "PCAP: malloc failed\n");
|
||||||
err_exit("Aborting",-1);
|
err_exit("Aborting", -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(tmp_filter,fmt,filter,filter);
|
sprintf(tmp_filter, fmt, filter, filter);
|
||||||
free(filter);
|
free(filter);
|
||||||
filter = tmp_filter;
|
filter = tmp_filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pcap_compile(p,&fp,filter,0,netmask)<0)
|
if(pcap_compile(p, &fp, filter, 0, netmask) < 0)
|
||||||
verr_exit("PCAP: %s\n",pcap_geterr(p));
|
verr_exit("PCAP: %s\n", pcap_geterr(p));
|
||||||
|
|
||||||
if(pcap_setfilter(p,&fp)<0)
|
if(pcap_setfilter(p, &fp) < 0)
|
||||||
verr_exit("PCAP: %s\n",pcap_geterr(p));
|
verr_exit("PCAP: %s\n", pcap_geterr(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
pcap_if_type=pcap_datalink(p);
|
pcap_if_type = pcap_datalink(p);
|
||||||
|
|
||||||
if(!(NET_print_flags & NET_PRINT_JSON))
|
if(!(NET_print_flags & NET_PRINT_JSON))
|
||||||
if(NET_print_flags & NET_PRINT_TYPESET)
|
if(NET_print_flags & NET_PRINT_TYPESET)
|
||||||
printf("\n.nf\n.ps -2\n");
|
printf("\n.nf\n.ps -2\n");
|
||||||
|
|
||||||
if((r=network_handler_create(mod,&n)))
|
if((r = network_handler_create(mod, &n)))
|
||||||
err_exit("Couldn't create network handler",r);
|
err_exit("Couldn't create network handler", r);
|
||||||
|
|
||||||
pcap_loop(p,-1,pcap_cb,(u_char *)n);
|
pcap_loop(p, -1, pcap_cb, (u_char *)n);
|
||||||
|
|
||||||
if(!(NET_print_flags & NET_PRINT_JSON))
|
if(!(NET_print_flags & NET_PRINT_JSON))
|
||||||
if(NET_print_flags & NET_PRINT_TYPESET)
|
if(NET_print_flags & NET_PRINT_TYPESET)
|
||||||
|
@ -515,7 +513,8 @@ main (int argc, char **argv)
|
||||||
|
|
||||||
freed_conn = destroy_all_conn();
|
freed_conn = destroy_all_conn();
|
||||||
if(freed_conn && !(NET_print_flags & NET_PRINT_JSON))
|
if(freed_conn && !(NET_print_flags & NET_PRINT_JSON))
|
||||||
printf("Cleaned %d remaining connection(s) from connection pool\n", freed_conn);
|
printf("Cleaned %d remaining connection(s) from connection pool\n",
|
||||||
|
freed_conn);
|
||||||
|
|
||||||
network_handler_destroy(mod, &n);
|
network_handler_destroy(mod, &n);
|
||||||
pcap_close(p);
|
pcap_close(p);
|
||||||
|
@ -534,39 +533,35 @@ main (int argc, char **argv)
|
||||||
free(SSL_keylogfile);
|
free(SSL_keylogfile);
|
||||||
if(SSL_password)
|
if(SSL_password)
|
||||||
free(SSL_password);
|
free(SSL_password);
|
||||||
if (logger)
|
if(logger) {
|
||||||
{
|
|
||||||
logger->vtbl->deinit();
|
logger->vtbl->deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *collapse_args(int argc, char **argv) {
|
||||||
char *
|
int i, len = 0;
|
||||||
collapse_args (int argc, char **argv)
|
|
||||||
{
|
|
||||||
int i,len=0;
|
|
||||||
char *ret;
|
char *ret;
|
||||||
|
|
||||||
if(!argc)
|
if(!argc)
|
||||||
return(0);
|
return (0);
|
||||||
|
|
||||||
for(i=0;i<argc;i++){
|
for(i = 0; i < argc; i++) {
|
||||||
len+=strlen(argv[i])+1;
|
len += strlen(argv[i]) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!(ret=(char *)malloc(len)))
|
if(!(ret = (char *)malloc(len)))
|
||||||
err_exit("Out of memory",1);
|
err_exit("Out of memory", 1);
|
||||||
|
|
||||||
len=0;
|
len = 0;
|
||||||
for(i=0;i<argc;i++){
|
for(i = 0; i < argc; i++) {
|
||||||
strcpy(ret+len,argv[i]);
|
strcpy(ret + len, argv[i]);
|
||||||
len+=strlen(argv[i]);
|
len += strlen(argv[i]);
|
||||||
|
|
||||||
if(i!=(argc-1))
|
if(i != (argc - 1))
|
||||||
ret[len++]=' ';
|
ret[len++] = ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
return(ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: print_utils.c,v 1.2 2000/10/17 16:09:58 ekr Exp $
|
$Id: print_utils.c,v 1.2 2000/10/17 16:09:58 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,45 +44,43 @@
|
||||||
ekr@rtfm.com Mon Feb 15 17:23:36 1999
|
ekr@rtfm.com Mon Feb 15 17:23:36 1999
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
int explain(char *format, ...) {
|
||||||
int explain(char *format,...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap,format);
|
va_start(ap, format);
|
||||||
|
|
||||||
INDENT;
|
INDENT;
|
||||||
|
|
||||||
vprintf(format,ap);
|
vprintf(format, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int exdump(name,data)
|
int exdump(name, data) char *name;
|
||||||
char *name;
|
Data *data;
|
||||||
Data *data;
|
{
|
||||||
{
|
int i, j;
|
||||||
int i,j;
|
|
||||||
char prefix[100];
|
char prefix[100];
|
||||||
|
|
||||||
INDENT;
|
INDENT;
|
||||||
|
|
||||||
if(name){
|
if(name) {
|
||||||
sprintf(prefix,"%s[%d]=\n",name,data->len);
|
sprintf(prefix, "%s[%d]=\n", name, data->len);
|
||||||
printf("%s",prefix);
|
printf("%s", prefix);
|
||||||
INDENT_INCR;
|
INDENT_INCR;
|
||||||
}
|
}
|
||||||
for(i=0;i<data->len;i++){
|
for(i = 0; i < data->len; i++) {
|
||||||
if(!i && (data->len>8)) INDENT;
|
if(!i && (data->len > 8))
|
||||||
if((data->len>8) && i && !(i%12)){
|
INDENT;
|
||||||
LF;INDENT;
|
if((data->len > 8) && i && !(i % 12)) {
|
||||||
}
|
|
||||||
printf("%.2x ",data->data[i]&255);
|
|
||||||
}
|
|
||||||
if(name) INDENT_POP;
|
|
||||||
if(data->len>8 && i%12)
|
|
||||||
LF;
|
LF;
|
||||||
return(0);
|
INDENT;
|
||||||
}
|
}
|
||||||
|
printf("%.2x ", data->data[i] & 255);
|
||||||
|
}
|
||||||
|
if(name)
|
||||||
|
INDENT_POP;
|
||||||
|
if(data->len > 8 && i % 12)
|
||||||
|
LF;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: print_utils.h,v 1.2 2000/10/17 16:09:58 ekr Exp $
|
$Id: print_utils.h,v 1.2 2000/10/17 16:09:58 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,14 +44,10 @@
|
||||||
ekr@rtfm.com Mon Feb 15 17:23:56 1999
|
ekr@rtfm.com Mon Feb 15 17:23:56 1999
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _print_utils_h
|
#ifndef _print_utils_h
|
||||||
#define _print_utils_h
|
#define _print_utils_h
|
||||||
|
|
||||||
int explain PROTO_LIST((char *format,...));
|
int explain PROTO_LIST((char *format, ...));
|
||||||
int exdump PROTO_LIST((char *name,
|
int exdump PROTO_LIST((char *name, Data *data));
|
||||||
Data *data));
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: proto_mod.c,v 1.3 2001/07/20 23:33:14 ekr Exp $
|
$Id: proto_mod.c,v 1.3 2001/07/20 23:33:14 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,41 +44,40 @@
|
||||||
ekr@rtfm.com Thu Jan 7 22:35:23 1999
|
ekr@rtfm.com Thu Jan 7 22:35:23 1999
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "network.h"
|
#include "network.h"
|
||||||
|
|
||||||
int
|
int create_proto_handler(proto_mod *mod,
|
||||||
create_proto_handler (proto_mod *mod, proto_ctx *ctx, proto_handler **handlerp, tcp_conn *conn, struct timeval *first_packet)
|
proto_ctx *ctx,
|
||||||
{
|
proto_handler **handlerp,
|
||||||
int r,_status;
|
tcp_conn *conn,
|
||||||
proto_handler *handler=0;
|
struct timeval *first_packet) {
|
||||||
|
int r, _status;
|
||||||
|
proto_handler *handler = 0;
|
||||||
|
|
||||||
if(!(handler=(proto_handler *)calloc(1,sizeof(proto_handler))))
|
if(!(handler = (proto_handler *)calloc(1, sizeof(proto_handler))))
|
||||||
ABORT(R_NO_MEMORY);
|
ABORT(R_NO_MEMORY);
|
||||||
handler->vtbl=mod->vtbl;
|
handler->vtbl = mod->vtbl;
|
||||||
if((r=mod->vtbl->create(mod->handle,ctx,conn,&handler->obj,
|
if((r = mod->vtbl->create(mod->handle, ctx, conn, &handler->obj,
|
||||||
&conn->i_addr,conn->i_port,&conn->r_addr,conn->r_port,first_packet)))
|
&conn->i_addr, conn->i_port, &conn->r_addr,
|
||||||
|
conn->r_port, first_packet)))
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
|
|
||||||
*handlerp=handler;
|
*handlerp = handler;
|
||||||
|
|
||||||
_status=0;
|
_status = 0;
|
||||||
abort:
|
abort:
|
||||||
if(_status){
|
if(_status) {
|
||||||
destroy_proto_handler(&handler);
|
destroy_proto_handler(&handler);
|
||||||
}
|
}
|
||||||
return(_status);
|
return (_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int destroy_proto_handler(proto_handler **handlerp) {
|
||||||
destroy_proto_handler (proto_handler **handlerp)
|
|
||||||
{
|
|
||||||
if(!handlerp || !*handlerp)
|
if(!handlerp || !*handlerp)
|
||||||
return(0);
|
return (0);
|
||||||
|
|
||||||
(*handlerp)->vtbl->destroy(&(*handlerp)->obj);
|
(*handlerp)->vtbl->destroy(&(*handlerp)->obj);
|
||||||
free(*handlerp);
|
free(*handlerp);
|
||||||
*handlerp=0;
|
*handlerp = 0;
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: proto_mod.h,v 1.4 2001/11/26 22:28:16 ekr Exp $
|
$Id: proto_mod.h,v 1.4 2001/11/26 22:28:16 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,7 +44,6 @@
|
||||||
ekr@rtfm.com Thu Dec 24 21:10:05 1998
|
ekr@rtfm.com Thu Dec 24 21:10:05 1998
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _proto_mod_h
|
#ifndef _proto_mod_h
|
||||||
#define _proto_mod_h
|
#define _proto_mod_h
|
||||||
|
|
||||||
|
@ -54,18 +54,22 @@ typedef struct proto_ctx_ proto_ctx;
|
||||||
#define DIR_R2I 2
|
#define DIR_R2I 2
|
||||||
|
|
||||||
struct proto_mod_vtbl_ {
|
struct proto_mod_vtbl_ {
|
||||||
int (*parse_flags) PROTO_LIST((char *str));
|
int(*parse_flags) PROTO_LIST((char *str));
|
||||||
int (*parse_flag) PROTO_LIST((int flag));
|
int(*parse_flag) PROTO_LIST((int flag));
|
||||||
int (*create_ctx) PROTO_LIST((void *handle,proto_ctx **ctxp));
|
int(*create_ctx) PROTO_LIST((void *handle, proto_ctx **ctxp));
|
||||||
int (*create) PROTO_LIST((void *handle,proto_ctx *ctx,
|
int(*create) PROTO_LIST((void *handle,
|
||||||
|
proto_ctx *ctx,
|
||||||
tcp_conn *conn,
|
tcp_conn *conn,
|
||||||
proto_obj **objp,
|
proto_obj **objp,
|
||||||
struct sockaddr_storage *i_addr,u_short i_port,
|
struct sockaddr_storage *i_addr,
|
||||||
struct sockaddr_storage *r_addr,u_short r_port,struct timeval *time_base));
|
u_short i_port,
|
||||||
int (*destroy_ctx) PROTO_LIST((void *handle,proto_ctx **ctxp));
|
struct sockaddr_storage *r_addr,
|
||||||
int (*destroy) PROTO_LIST((proto_obj **objp));
|
u_short r_port,
|
||||||
int (*data) PROTO_LIST((proto_obj *obj,segment *data,int direction));
|
struct timeval *time_base));
|
||||||
int (*close) PROTO_LIST((proto_obj *obj,packet *p,int direction));
|
int(*destroy_ctx) PROTO_LIST((void *handle, proto_ctx **ctxp));
|
||||||
|
int(*destroy) PROTO_LIST((proto_obj * *objp));
|
||||||
|
int(*data) PROTO_LIST((proto_obj * obj, segment *data, int direction));
|
||||||
|
int(*close) PROTO_LIST((proto_obj * obj, packet *p, int direction));
|
||||||
};
|
};
|
||||||
|
|
||||||
struct proto_mod_ {
|
struct proto_mod_ {
|
||||||
|
@ -78,22 +82,29 @@ struct proto_handler_ {
|
||||||
struct proto_mod_vtbl_ *vtbl;
|
struct proto_mod_vtbl_ *vtbl;
|
||||||
};
|
};
|
||||||
|
|
||||||
int create_proto_handler PROTO_LIST((proto_mod *mod,proto_ctx *ctx,
|
int create_proto_handler PROTO_LIST((proto_mod * mod,
|
||||||
|
proto_ctx *ctx,
|
||||||
proto_handler **handlerp,
|
proto_handler **handlerp,
|
||||||
tcp_conn *conn,struct timeval *first_packet));
|
tcp_conn *conn,
|
||||||
int destroy_proto_handler PROTO_LIST((proto_handler **handlerp));
|
struct timeval *first_packet));
|
||||||
|
int destroy_proto_handler PROTO_LIST((proto_handler * *handlerp));
|
||||||
|
|
||||||
|
// add logger
|
||||||
//add logger
|
|
||||||
struct logger_mod_vtbl_ {
|
struct logger_mod_vtbl_ {
|
||||||
int (*init) PROTO_LIST((void *data));
|
int(*init) PROTO_LIST((void *data));
|
||||||
//deinit must be async signal safe(!!!)
|
// deinit must be async signal safe(!!!)
|
||||||
int (*deinit) PROTO_LIST(());
|
int(*deinit) PROTO_LIST(());
|
||||||
int (*create) PROTO_LIST((proto_obj **objp, struct sockaddr_storage *i_addr,u_short i_port,
|
int(*create) PROTO_LIST((proto_obj * *objp,
|
||||||
struct sockaddr_storage *r_addr,u_short r_port,struct timeval *time_base));
|
struct sockaddr_storage *i_addr,
|
||||||
int (*destroy) PROTO_LIST((proto_obj **objp));
|
u_short i_port,
|
||||||
int (*data) PROTO_LIST((proto_obj *obj,unsigned char *data,unsigned int len,int direction));
|
struct sockaddr_storage *r_addr,
|
||||||
int (*close) PROTO_LIST((proto_obj *obj,unsigned char *data,unsigned int len,int direction));
|
u_short r_port,
|
||||||
|
struct timeval *time_base));
|
||||||
|
int(*destroy) PROTO_LIST((proto_obj * *objp));
|
||||||
|
int(*data) PROTO_LIST(
|
||||||
|
(proto_obj * obj, unsigned char *data, unsigned int len, int direction));
|
||||||
|
int(*close) PROTO_LIST(
|
||||||
|
(proto_obj * obj, unsigned char *data, unsigned int len, int direction));
|
||||||
};
|
};
|
||||||
|
|
||||||
struct logger_mod_ {
|
struct logger_mod_ {
|
||||||
|
@ -106,4 +117,3 @@ typedef struct logger_mod_ logger_mod;
|
||||||
extern logger_mod *logger;
|
extern logger_mod *logger;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
178
base/tcpconn.c
178
base/tcpconn.c
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: tcpconn.c,v 1.7 2002/08/17 01:33:16 ekr Exp $
|
$Id: tcpconn.c,v 1.7 2002/08/17 01:33:16 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,108 +44,102 @@
|
||||||
ekr@rtfm.com Tue Dec 29 15:13:03 1998
|
ekr@rtfm.com Tue Dec 29 15:13:03 1998
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "network.h"
|
#include "network.h"
|
||||||
#include "tcpconn.h"
|
#include "tcpconn.h"
|
||||||
|
|
||||||
|
|
||||||
typedef struct conn_struct_ {
|
typedef struct conn_struct_ {
|
||||||
tcp_conn conn;
|
tcp_conn conn;
|
||||||
struct conn_struct_ *next;
|
struct conn_struct_ *next;
|
||||||
struct conn_struct_ *prev;
|
struct conn_struct_ *prev;
|
||||||
} conn_struct;
|
} conn_struct;
|
||||||
|
|
||||||
int conn_number=1;
|
int conn_number = 1;
|
||||||
|
|
||||||
static conn_struct *first_conn=0;
|
static conn_struct *first_conn = 0;
|
||||||
|
|
||||||
extern struct timeval last_packet_seen_time;
|
extern struct timeval last_packet_seen_time;
|
||||||
extern int conn_ttl;
|
extern int conn_ttl;
|
||||||
|
|
||||||
static int zero_conn PROTO_LIST((tcp_conn *conn));
|
static int zero_conn PROTO_LIST((tcp_conn * conn));
|
||||||
|
|
||||||
static int
|
static int zero_conn(tcp_conn *conn) {
|
||||||
zero_conn (tcp_conn *conn)
|
memset(conn, 0, sizeof(tcp_conn));
|
||||||
{
|
return (0);
|
||||||
memset(conn,0,sizeof(tcp_conn));
|
}
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int tcp_find_conn(tcp_conn **connp, int *directionp,struct sockaddr_storage *saddr,
|
int tcp_find_conn(tcp_conn **connp,
|
||||||
u_short sport, struct sockaddr_storage *daddr, u_short dport)
|
int *directionp,
|
||||||
{
|
struct sockaddr_storage *saddr,
|
||||||
|
u_short sport,
|
||||||
|
struct sockaddr_storage *daddr,
|
||||||
|
u_short dport) {
|
||||||
conn_struct *conn;
|
conn_struct *conn;
|
||||||
|
|
||||||
for(conn=first_conn;conn;conn=conn->next){
|
for(conn = first_conn; conn; conn = conn->next) {
|
||||||
|
if(sport == conn->conn.i_port && dport == conn->conn.r_port) {
|
||||||
if(sport == conn->conn.i_port && dport==conn->conn.r_port){
|
if(!memcmp(saddr, &conn->conn.i_addr, sizeof(struct sockaddr_storage)) &&
|
||||||
if(!memcmp(saddr,&conn->conn.i_addr,sizeof(struct sockaddr_storage))
|
!memcmp(daddr, &conn->conn.r_addr, sizeof(struct sockaddr_storage))) {
|
||||||
&& !memcmp(daddr,&conn->conn.r_addr,sizeof(struct sockaddr_storage)))
|
*directionp = DIR_I2R;
|
||||||
{
|
*connp = &(conn->conn);
|
||||||
*directionp=DIR_I2R;
|
return (0);
|
||||||
*connp=&(conn->conn);
|
|
||||||
return(0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(dport == conn->conn.i_port && sport==conn->conn.r_port){
|
if(dport == conn->conn.i_port && sport == conn->conn.r_port) {
|
||||||
if(!memcmp(saddr,&conn->conn.r_addr,sizeof(struct sockaddr_storage))
|
if(!memcmp(saddr, &conn->conn.r_addr, sizeof(struct sockaddr_storage)) &&
|
||||||
&& !memcmp(daddr,&conn->conn.i_addr,sizeof(struct sockaddr_storage)))
|
!memcmp(daddr, &conn->conn.i_addr, sizeof(struct sockaddr_storage))) {
|
||||||
{
|
*directionp = DIR_R2I;
|
||||||
*directionp=DIR_R2I;
|
*connp = &(conn->conn);
|
||||||
*connp=&(conn->conn);
|
return (0);
|
||||||
return(0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return(R_NOT_FOUND);
|
return (R_NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
int tcp_create_conn(tcp_conn **connp,struct sockaddr_storage *i_addr,
|
int tcp_create_conn(tcp_conn **connp,
|
||||||
u_short i_port, struct sockaddr_storage *r_addr, u_short r_port)
|
struct sockaddr_storage *i_addr,
|
||||||
{
|
u_short i_port,
|
||||||
conn_struct *conn=0;
|
struct sockaddr_storage *r_addr,
|
||||||
|
u_short r_port) {
|
||||||
|
conn_struct *conn = 0;
|
||||||
|
|
||||||
if(!(conn=(conn_struct *)malloc(sizeof(conn_struct))))
|
if(!(conn = (conn_struct *)malloc(sizeof(conn_struct))))
|
||||||
return(R_NO_MEMORY);
|
return (R_NO_MEMORY);
|
||||||
|
|
||||||
conn->prev=0;
|
conn->prev = 0;
|
||||||
|
|
||||||
zero_conn(&conn->conn);
|
zero_conn(&conn->conn);
|
||||||
conn->conn.backptr=conn;
|
conn->conn.backptr = conn;
|
||||||
conn->conn.conn_number=conn_number++;
|
conn->conn.conn_number = conn_number++;
|
||||||
|
|
||||||
memcpy(&conn->conn.i_addr,i_addr,sizeof(struct sockaddr_storage));
|
memcpy(&conn->conn.i_addr, i_addr, sizeof(struct sockaddr_storage));
|
||||||
conn->conn.i_port=i_port;
|
conn->conn.i_port = i_port;
|
||||||
memcpy(&conn->conn.r_addr,r_addr,sizeof(struct sockaddr_storage));
|
memcpy(&conn->conn.r_addr, r_addr, sizeof(struct sockaddr_storage));
|
||||||
conn->conn.r_port=r_port;
|
conn->conn.r_port = r_port;
|
||||||
*connp=&(conn->conn);
|
*connp = &(conn->conn);
|
||||||
|
|
||||||
/* Insert at the head of the list */
|
/* Insert at the head of the list */
|
||||||
conn->next=first_conn;
|
conn->next = first_conn;
|
||||||
if(first_conn)
|
if(first_conn)
|
||||||
first_conn->prev=conn;
|
first_conn->prev = conn;
|
||||||
first_conn=conn;
|
first_conn = conn;
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
return(0);
|
int tcp_destroy_conn(tcp_conn *conn) {
|
||||||
}
|
conn_struct *c = conn->backptr;
|
||||||
|
|
||||||
int
|
|
||||||
tcp_destroy_conn (tcp_conn *conn)
|
|
||||||
{
|
|
||||||
conn_struct *c=conn->backptr;
|
|
||||||
|
|
||||||
/* Detach from the list */
|
/* Detach from the list */
|
||||||
if(c->next){
|
if(c->next) {
|
||||||
c->next->prev=c->prev;
|
c->next->prev = c->prev;
|
||||||
}
|
}
|
||||||
if(c->prev){
|
if(c->prev) {
|
||||||
c->prev->next=c->next;
|
c->prev->next = c->next;
|
||||||
}
|
} else {
|
||||||
else {
|
first_conn = c->next;
|
||||||
first_conn=c->next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy_proto_handler(&conn->analyzer);
|
destroy_proto_handler(&conn->analyzer);
|
||||||
|
@ -158,11 +153,10 @@ tcp_destroy_conn (tcp_conn *conn)
|
||||||
free(conn->backptr);
|
free(conn->backptr);
|
||||||
free(conn);
|
free(conn);
|
||||||
|
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int clean_old_conn(void) {
|
||||||
clean_old_conn (void) {
|
|
||||||
conn_struct *conn;
|
conn_struct *conn;
|
||||||
tcp_conn *tcpconn;
|
tcp_conn *tcpconn;
|
||||||
struct timeval dt;
|
struct timeval dt;
|
||||||
|
@ -174,7 +168,7 @@ clean_old_conn (void) {
|
||||||
conn = first_conn;
|
conn = first_conn;
|
||||||
while(conn) {
|
while(conn) {
|
||||||
tcpconn = &conn->conn;
|
tcpconn = &conn->conn;
|
||||||
conn=conn->next;
|
conn = conn->next;
|
||||||
if(timestamp_diff(&last_packet_seen_time, &tcpconn->last_seen_time, &dt))
|
if(timestamp_diff(&last_packet_seen_time, &tcpconn->last_seen_time, &dt))
|
||||||
continue;
|
continue;
|
||||||
if(dt.tv_sec > conn_ttl) {
|
if(dt.tv_sec > conn_ttl) {
|
||||||
|
@ -185,8 +179,7 @@ clean_old_conn (void) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int destroy_all_conn(void) {
|
||||||
destroy_all_conn (void) {
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while(first_conn) {
|
while(first_conn) {
|
||||||
i++;
|
i++;
|
||||||
|
@ -195,41 +188,38 @@ destroy_all_conn (void) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int free_tcp_segment_queue(segment *seg) {
|
||||||
free_tcp_segment_queue (segment *seg)
|
|
||||||
{
|
|
||||||
segment *tmp;
|
segment *tmp;
|
||||||
|
|
||||||
while(seg){
|
while(seg) {
|
||||||
tmp=seg->next;
|
tmp = seg->next;
|
||||||
packet_destroy(seg->p);
|
packet_destroy(seg->p);
|
||||||
free(seg);
|
free(seg);
|
||||||
seg=tmp;
|
seg = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int copy_tcp_segment_queue(segment **out, segment *in) {
|
||||||
copy_tcp_segment_queue (segment **out, segment *in)
|
int r, _status;
|
||||||
{
|
segment *base = 0;
|
||||||
int r,_status;
|
|
||||||
segment *base=0;
|
|
||||||
|
|
||||||
for(;in;in=in->next){
|
for(; in; in = in->next) {
|
||||||
if(!(*out=(segment *)calloc(1,sizeof(segment))))
|
if(!(*out = (segment *)calloc(1, sizeof(segment))))
|
||||||
ABORT(R_NO_MEMORY);
|
ABORT(R_NO_MEMORY);
|
||||||
if(!base) base=*out;
|
if(!base)
|
||||||
|
base = *out;
|
||||||
|
|
||||||
if((r=packet_copy(in->p,&(*out)->p)))
|
if((r = packet_copy(in->p, &(*out)->p)))
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
out=&(*out)->next; /* Move the pointer we're assigning to */
|
out = &(*out)->next; /* Move the pointer we're assigning to */
|
||||||
}
|
}
|
||||||
|
|
||||||
_status=0;
|
_status = 0;
|
||||||
abort:
|
abort:
|
||||||
if(_status){
|
if(_status) {
|
||||||
free_tcp_segment_queue(base);
|
free_tcp_segment_queue(base);
|
||||||
}
|
}
|
||||||
return(_status);
|
return (_status);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: tcpconn.h,v 1.4 2001/07/20 23:33:15 ekr Exp $
|
$Id: tcpconn.h,v 1.4 2001/07/20 23:33:15 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,7 +44,6 @@
|
||||||
ekr@rtfm.com Tue Dec 29 13:00:52 1998
|
ekr@rtfm.com Tue Dec 29 13:00:52 1998
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _tcpconn_h
|
#ifndef _tcpconn_h
|
||||||
#define _tcpconn_h
|
#define _tcpconn_h
|
||||||
|
|
||||||
|
@ -92,21 +92,24 @@ typedef struct tcp_conn_ {
|
||||||
struct conn_struct_ *backptr;
|
struct conn_struct_ *backptr;
|
||||||
} tcp_conn;
|
} tcp_conn;
|
||||||
|
|
||||||
int tcp_find_conn PROTO_LIST((tcp_conn **connp,
|
int tcp_find_conn PROTO_LIST((tcp_conn * *connp,
|
||||||
int *directionp,
|
int *directionp,
|
||||||
struct sockaddr_storage *src_addr, u_short src_port,
|
struct sockaddr_storage *src_addr,
|
||||||
struct sockaddr_storage *dst_addr, u_short dst_port));
|
u_short src_port,
|
||||||
|
struct sockaddr_storage *dst_addr,
|
||||||
|
u_short dst_port));
|
||||||
|
|
||||||
int tcp_create_conn PROTO_LIST((tcp_conn **connp,
|
int tcp_create_conn PROTO_LIST((tcp_conn * *connp,
|
||||||
struct sockaddr_storage *initiator_addr, u_short initiator_port,
|
struct sockaddr_storage *initiator_addr,
|
||||||
struct sockaddr_storage *responder_addr, u_short responder_port));
|
u_short initiator_port,
|
||||||
|
struct sockaddr_storage *responder_addr,
|
||||||
|
u_short responder_port));
|
||||||
|
|
||||||
int tcp_destroy_conn PROTO_LIST((tcp_conn *conn));
|
int tcp_destroy_conn PROTO_LIST((tcp_conn * conn));
|
||||||
int free_tcp_segment_queue PROTO_LIST((segment *seg));
|
int free_tcp_segment_queue PROTO_LIST((segment * seg));
|
||||||
int copy_tcp_segment_queue PROTO_LIST((segment **out,segment *in));
|
int copy_tcp_segment_queue PROTO_LIST((segment * *out, segment *in));
|
||||||
|
|
||||||
int clean_old_conn(void);
|
int clean_old_conn(void);
|
||||||
int destroy_all_conn(void);
|
int destroy_all_conn(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
395
base/tcppack.c
395
base/tcppack.c
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: tcppack.c,v 1.11 2002/09/09 21:02:58 ekr Exp $
|
$Id: tcppack.c,v 1.11 2002/09/09 21:02:58 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,38 +44,36 @@
|
||||||
ekr@rtfm.com Tue Dec 29 12:43:39 1998
|
ekr@rtfm.com Tue Dec 29 12:43:39 1998
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "network.h"
|
#include "network.h"
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
# include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
# include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
# ifndef LINUX
|
#ifndef LINUX
|
||||||
# include <netinet/tcp_seq.h>
|
#include <netinet/tcp_seq.h>
|
||||||
# else
|
|
||||||
# define SEQ_LT(x,y) ((int)((x)-(y))<0)
|
|
||||||
# endif
|
|
||||||
#else
|
#else
|
||||||
# include <winsock2.h>
|
#define SEQ_LT(x, y) ((int)((x) - (y)) < 0)
|
||||||
# define SEQ_LT(x,y) ((int)((x)-(y))<0)
|
#endif
|
||||||
|
#else
|
||||||
|
#include <winsock2.h>
|
||||||
|
#define SEQ_LT(x, y) ((int)((x) - (y)) < 0)
|
||||||
#endif
|
#endif
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "tcpconn.h"
|
#include "tcpconn.h"
|
||||||
#include "tcppack.h"
|
#include "tcppack.h"
|
||||||
|
|
||||||
|
static int process_data_segment PROTO_LIST((tcp_conn * conn,
|
||||||
|
proto_mod *handler,
|
||||||
|
packet *p,
|
||||||
|
stream_data *stream,
|
||||||
|
int direction));
|
||||||
|
static int new_connection PROTO_LIST(
|
||||||
|
(proto_mod * handler, proto_ctx *ctx, packet *p, tcp_conn **connp));
|
||||||
|
static int print_tcp_packet PROTO_LIST((packet * p));
|
||||||
|
int STRIM PROTO_LIST((UINT4 _seq, segment *s));
|
||||||
|
|
||||||
static int process_data_segment PROTO_LIST((tcp_conn *conn,
|
int process_tcp_packet(proto_mod *handler, proto_ctx *ctx, packet *p) {
|
||||||
proto_mod *handler,packet *p,stream_data *stream,int direction));
|
int r, _status;
|
||||||
static int new_connection PROTO_LIST((proto_mod *handler,proto_ctx *ctx,
|
|
||||||
packet *p,tcp_conn **connp));
|
|
||||||
static int print_tcp_packet PROTO_LIST((packet *p));
|
|
||||||
int STRIM PROTO_LIST((UINT4 _seq,segment *s));
|
|
||||||
|
|
||||||
int
|
|
||||||
process_tcp_packet (proto_mod *handler, proto_ctx *ctx, packet *p)
|
|
||||||
{
|
|
||||||
int r,_status;
|
|
||||||
int direction;
|
int direction;
|
||||||
stream_data *stream;
|
stream_data *stream;
|
||||||
tcp_conn *conn;
|
tcp_conn *conn;
|
||||||
|
@ -82,124 +81,121 @@ process_tcp_packet (proto_mod *handler, proto_ctx *ctx, packet *p)
|
||||||
if(p->len < 20)
|
if(p->len < 20)
|
||||||
ABORT(1);
|
ABORT(1);
|
||||||
|
|
||||||
p->tcp=(struct tcphdr *)p->data;
|
p->tcp = (struct tcphdr *)p->data;
|
||||||
|
|
||||||
print_tcp_packet(p);
|
print_tcp_packet(p);
|
||||||
|
|
||||||
if((r=tcp_find_conn(&conn,&direction,&p->i_addr.so_st,
|
if((r = tcp_find_conn(&conn, &direction, &p->i_addr.so_st,
|
||||||
ntohs(p->tcp->th_sport),&p->r_addr.so_st,ntohs(p->tcp->th_dport)))){
|
ntohs(p->tcp->th_sport), &p->r_addr.so_st,
|
||||||
if(r!=R_NOT_FOUND)
|
ntohs(p->tcp->th_dport)))) {
|
||||||
|
if(r != R_NOT_FOUND)
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
|
|
||||||
if((p->tcp->th_flags & TH_SYN)!=TH_SYN){
|
if((p->tcp->th_flags & TH_SYN) != TH_SYN) {
|
||||||
DBG((0,"TCP: rejecting packet from unknown connection, seq: %u\n",ntohl(p->tcp->th_seq)));
|
DBG((0, "TCP: rejecting packet from unknown connection, seq: %u\n",
|
||||||
return(0);
|
ntohl(p->tcp->th_seq)));
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if((r=new_connection(handler,ctx,p,&conn)))
|
if((r = new_connection(handler, ctx, p, &conn)))
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
stream=direction==DIR_R2I?&conn->r2i:&conn->i2r;
|
stream = direction == DIR_R2I ? &conn->r2i : &conn->i2r;
|
||||||
|
|
||||||
memcpy(&conn->last_seen_time,&p->ts,sizeof(struct timeval));
|
memcpy(&conn->last_seen_time, &p->ts, sizeof(struct timeval));
|
||||||
|
|
||||||
switch(conn->state){
|
switch(conn->state) {
|
||||||
case TCP_STATE_SYN1:
|
case TCP_STATE_SYN1:
|
||||||
if(direction == DIR_R2I && (p->tcp->th_flags & TH_SYN)) {
|
if(direction == DIR_R2I && (p->tcp->th_flags & TH_SYN)) {
|
||||||
DBG((0,"SYN2 seq: %u",ntohl(p->tcp->th_seq)));
|
DBG((0, "SYN2 seq: %u", ntohl(p->tcp->th_seq)));
|
||||||
conn->r2i.seq=ntohl(p->tcp->th_seq)+1;
|
conn->r2i.seq = ntohl(p->tcp->th_seq) + 1;
|
||||||
conn->r2i.ack=ntohl(p->tcp->th_ack)+1;
|
conn->r2i.ack = ntohl(p->tcp->th_ack) + 1;
|
||||||
conn->state=TCP_STATE_ACK;
|
conn->state = TCP_STATE_ACK;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TCP_STATE_SYN2:
|
case TCP_STATE_SYN2:
|
||||||
if(direction == DIR_I2R && (p->tcp->th_flags & TH_SYN)) {
|
if(direction == DIR_I2R && (p->tcp->th_flags & TH_SYN)) {
|
||||||
DBG((0,"SYN1 seq: %u",ntohl(p->tcp->th_seq)));
|
DBG((0, "SYN1 seq: %u", ntohl(p->tcp->th_seq)));
|
||||||
conn->i2r.seq=ntohl(p->tcp->th_seq)+1;
|
conn->i2r.seq = ntohl(p->tcp->th_seq) + 1;
|
||||||
conn->i2r.ack=ntohl(p->tcp->th_ack)+1;
|
conn->i2r.ack = ntohl(p->tcp->th_ack) + 1;
|
||||||
conn->state=TCP_STATE_ACK;
|
conn->state = TCP_STATE_ACK;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TCP_STATE_ACK:
|
case TCP_STATE_ACK: {
|
||||||
{
|
|
||||||
if(direction != DIR_I2R)
|
if(direction != DIR_I2R)
|
||||||
break;
|
break;
|
||||||
DBG((0,"ACK seq: %u",ntohl(p->tcp->th_seq)));
|
DBG((0, "ACK seq: %u", ntohl(p->tcp->th_seq)));
|
||||||
conn->i2r.ack=ntohl(p->tcp->th_ack)+1;
|
conn->i2r.ack = ntohl(p->tcp->th_ack) + 1;
|
||||||
if(!(NET_print_flags & NET_PRINT_JSON)) {
|
if(!(NET_print_flags & NET_PRINT_JSON)) {
|
||||||
if(NET_print_flags & NET_PRINT_TYPESET)
|
if(NET_print_flags & NET_PRINT_TYPESET)
|
||||||
printf("\\fC");
|
printf("\\fC");
|
||||||
printf("New TCP connection #%d: %s(%d) <-> %s(%d)\n",
|
printf("New TCP connection #%d: %s(%d) <-> %s(%d)\n", conn->conn_number,
|
||||||
conn->conn_number,
|
conn->i_name, conn->i_port, conn->r_name, conn->r_port);
|
||||||
conn->i_name,conn->i_port,
|
|
||||||
conn->r_name,conn->r_port);
|
|
||||||
if(NET_print_flags & NET_PRINT_TYPESET)
|
if(NET_print_flags & NET_PRINT_TYPESET)
|
||||||
printf("\\fR");
|
printf("\\fR");
|
||||||
}
|
}
|
||||||
conn->state=TCP_STATE_ESTABLISHED;
|
conn->state = TCP_STATE_ESTABLISHED;
|
||||||
}
|
}
|
||||||
case TCP_STATE_ESTABLISHED:
|
case TCP_STATE_ESTABLISHED:
|
||||||
case TCP_STATE_FIN1:
|
case TCP_STATE_FIN1: {
|
||||||
{
|
|
||||||
if(p->tcp->th_flags & TH_SYN)
|
if(p->tcp->th_flags & TH_SYN)
|
||||||
break;
|
break;
|
||||||
if((r=process_data_segment(conn,handler,p,stream,direction)))
|
if((r = process_data_segment(conn, handler, p, stream, direction)))
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(conn->state==TCP_STATE_CLOSED)
|
if(conn->state == TCP_STATE_CLOSED)
|
||||||
tcp_destroy_conn(conn);
|
tcp_destroy_conn(conn);
|
||||||
|
|
||||||
|
_status = 0;
|
||||||
|
abort:
|
||||||
|
|
||||||
_status=0;
|
return (_status);
|
||||||
abort:
|
}
|
||||||
|
|
||||||
return(_status);
|
static int new_connection(proto_mod *handler,
|
||||||
}
|
proto_ctx *ctx,
|
||||||
|
packet *p,
|
||||||
|
tcp_conn **connp) {
|
||||||
|
int r, _status;
|
||||||
|
tcp_conn *conn = 0;
|
||||||
|
|
||||||
static int
|
if((p->tcp->th_flags & (TH_SYN | TH_ACK)) == TH_SYN) {
|
||||||
new_connection (proto_mod *handler, proto_ctx *ctx, packet *p, tcp_conn **connp)
|
if((r = tcp_create_conn(&conn, &p->i_addr.so_st, ntohs(p->tcp->th_sport),
|
||||||
{
|
&p->r_addr.so_st, ntohs(p->tcp->th_dport))))
|
||||||
int r,_status;
|
|
||||||
tcp_conn *conn=0;
|
|
||||||
|
|
||||||
if ((p->tcp->th_flags & (TH_SYN|TH_ACK))==TH_SYN) {
|
|
||||||
if((r=tcp_create_conn(&conn,&p->i_addr.so_st,ntohs(p->tcp->th_sport),
|
|
||||||
&p->r_addr.so_st,ntohs(p->tcp->th_dport))))
|
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
DBG((0,"SYN1 seq: %u",ntohl(p->tcp->th_seq)));
|
DBG((0, "SYN1 seq: %u", ntohl(p->tcp->th_seq)));
|
||||||
conn->i2r.seq=ntohl(p->tcp->th_seq)+1;
|
conn->i2r.seq = ntohl(p->tcp->th_seq) + 1;
|
||||||
conn->i2r.ack=ntohl(p->tcp->th_ack)+1;
|
conn->i2r.ack = ntohl(p->tcp->th_ack) + 1;
|
||||||
conn->state=TCP_STATE_SYN1;
|
conn->state = TCP_STATE_SYN1;
|
||||||
} else { // SYN&ACK comes first somehow
|
} else { // SYN&ACK comes first somehow
|
||||||
if((r=tcp_create_conn(&conn,&p->r_addr.so_st,ntohs(p->tcp->th_dport),
|
if((r = tcp_create_conn(&conn, &p->r_addr.so_st, ntohs(p->tcp->th_dport),
|
||||||
&p->i_addr.so_st,ntohs(p->tcp->th_sport))))
|
&p->i_addr.so_st, ntohs(p->tcp->th_sport))))
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
DBG((0,"SYN2 seq: %u",ntohl(p->tcp->th_seq)));
|
DBG((0, "SYN2 seq: %u", ntohl(p->tcp->th_seq)));
|
||||||
conn->r2i.seq=ntohl(p->tcp->th_seq)+1;
|
conn->r2i.seq = ntohl(p->tcp->th_seq) + 1;
|
||||||
conn->r2i.ack=ntohl(p->tcp->th_ack)+1;
|
conn->r2i.ack = ntohl(p->tcp->th_ack) + 1;
|
||||||
conn->state=TCP_STATE_SYN2;
|
conn->state = TCP_STATE_SYN2;
|
||||||
}
|
}
|
||||||
memcpy(&conn->start_time,&p->ts,sizeof(struct timeval));
|
memcpy(&conn->start_time, &p->ts, sizeof(struct timeval));
|
||||||
memcpy(&conn->last_seen_time,&p->ts,sizeof(struct timeval));
|
memcpy(&conn->last_seen_time, &p->ts, sizeof(struct timeval));
|
||||||
lookuphostname(&conn->i_addr,&conn->i_name);
|
lookuphostname(&conn->i_addr, &conn->i_name);
|
||||||
lookuphostname(&conn->r_addr,&conn->r_name);
|
lookuphostname(&conn->r_addr, &conn->r_name);
|
||||||
addrtotext(&conn->i_addr,&conn->i_num);
|
addrtotext(&conn->i_addr, &conn->i_num);
|
||||||
addrtotext(&conn->r_addr,&conn->r_num);
|
addrtotext(&conn->r_addr, &conn->r_num);
|
||||||
if((r=create_proto_handler(handler,ctx,&conn->analyzer,conn,&p->ts)))
|
if((r = create_proto_handler(handler, ctx, &conn->analyzer, conn, &p->ts)))
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
|
|
||||||
*connp=conn;
|
*connp = conn;
|
||||||
_status=0;
|
_status = 0;
|
||||||
abort:
|
abort:
|
||||||
return(_status);
|
return (_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*#define STRIM(_seq,s) { \
|
/*#define STRIM(_seq,s) { \
|
||||||
int l;\
|
int l;\
|
||||||
|
@ -222,43 +218,46 @@ new_connection (proto_mod *handler, proto_ctx *ctx, packet *p, tcp_conn **connp)
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int
|
static int process_data_segment(tcp_conn *conn,
|
||||||
process_data_segment (tcp_conn *conn, proto_mod *handler, packet *p, stream_data *stream, int direction)
|
proto_mod *handler,
|
||||||
{
|
packet *p,
|
||||||
int r,_status;
|
stream_data *stream,
|
||||||
tcp_seq seq,right_edge;
|
int direction) {
|
||||||
|
int r, _status;
|
||||||
|
tcp_seq seq, right_edge;
|
||||||
segment _seg;
|
segment _seg;
|
||||||
segment *seg,*nseg=0;
|
segment *seg, *nseg = 0;
|
||||||
long l;
|
long l;
|
||||||
|
|
||||||
l=p->len - p->tcp->th_off * 4;
|
l = p->len - p->tcp->th_off * 4;
|
||||||
|
|
||||||
if(l < 0) {
|
if(l < 0) {
|
||||||
fprintf(stderr,"Malformed packet, computed TCP segment size is negative, skipping ...\n");
|
fprintf(stderr,
|
||||||
return(0);
|
"Malformed packet, computed TCP segment size is negative, skipping "
|
||||||
|
"...\n");
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(stream->close){
|
if(stream->close) {
|
||||||
DBG((0,"Rejecting packet received after FIN: %u:%u(%u)",
|
DBG((0, "Rejecting packet received after FIN: %u:%u(%u)",
|
||||||
ntohl(p->tcp->th_seq),ntohl(p->tcp->th_seq+l),l));
|
ntohl(p->tcp->th_seq), ntohl(p->tcp->th_seq + l), l));
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*The idea here is to pass all available segments
|
/*The idea here is to pass all available segments
|
||||||
to the analyzer at once. Since we want to preserve
|
to the analyzer at once. Since we want to preserve
|
||||||
the segment packet data, we pass the data as a linked list of
|
the segment packet data, we pass the data as a linked list of
|
||||||
segments*/
|
segments*/
|
||||||
seq=ntohl(p->tcp->th_seq);
|
seq = ntohl(p->tcp->th_seq);
|
||||||
|
|
||||||
/*Add ACK processing logic here <TODO>*/
|
/*Add ACK processing logic here <TODO>*/
|
||||||
if(p->tcp->th_flags & TH_ACK){
|
if(p->tcp->th_flags & TH_ACK) {
|
||||||
long acknum,acked;
|
long acknum, acked;
|
||||||
|
|
||||||
|
acknum = ntohl(p->tcp->th_ack);
|
||||||
|
acked = acknum - stream->ack;
|
||||||
|
|
||||||
acknum=ntohl(p->tcp->th_ack);
|
if(acked && !l) {
|
||||||
acked=acknum-stream->ack;
|
|
||||||
|
|
||||||
if(acked && !l){
|
|
||||||
/*
|
/*
|
||||||
if((r=timestamp_diff(&p->ts,&conn->start_time,&dt)))
|
if((r=timestamp_diff(&p->ts,&conn->start_time,&dt)))
|
||||||
ERETURN(r);
|
ERETURN(r);
|
||||||
|
@ -271,73 +270,68 @@ process_data_segment (tcp_conn *conn, proto_mod *handler, packet *p, stream_data
|
||||||
printf("ACK (%d)\n",acked); */
|
printf("ACK (%d)\n",acked); */
|
||||||
}
|
}
|
||||||
|
|
||||||
stream->ack=acknum;
|
stream->ack = acknum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DBG((0, "Stream Seq %u ", stream->seq));
|
||||||
DBG((0,"Stream Seq %u ",stream->seq));
|
|
||||||
|
|
||||||
/* Check to see if this packet has been processed already */
|
/* Check to see if this packet has been processed already */
|
||||||
right_edge=seq + (p->len - (p->tcp->th_off)*4);
|
right_edge = seq + (p->len - (p->tcp->th_off) * 4);
|
||||||
if(!(p->tcp->th_flags & (TH_RST)) && SEQ_LT(right_edge,stream->seq))
|
if(!(p->tcp->th_flags & (TH_RST)) && SEQ_LT(right_edge, stream->seq))
|
||||||
return(0);
|
return (0);
|
||||||
|
|
||||||
if(SEQ_LT(stream->seq,seq)){
|
if(SEQ_LT(stream->seq, seq)) {
|
||||||
/* Out of order segment */
|
/* Out of order segment */
|
||||||
tcp_seq left_edge;
|
tcp_seq left_edge;
|
||||||
|
|
||||||
for(seg=0;seg;seg=seg?seg->next:stream->oo_queue){
|
for(seg = 0; seg; seg = seg ? seg->next : stream->oo_queue) {
|
||||||
if(seg->next->s_seq > seq)
|
if(seg->next->s_seq > seq)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!(nseg=(segment *)calloc(1,sizeof(segment))))
|
if(!(nseg = (segment *)calloc(1, sizeof(segment))))
|
||||||
ABORT(R_NO_MEMORY);
|
ABORT(R_NO_MEMORY);
|
||||||
if((r=packet_copy(p,&nseg->p)))
|
if((r = packet_copy(p, &nseg->p)))
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
nseg->s_seq=seq;
|
nseg->s_seq = seq;
|
||||||
|
|
||||||
/*Insert this segment into the reassembly queue*/
|
/*Insert this segment into the reassembly queue*/
|
||||||
if(seg){
|
if(seg) {
|
||||||
nseg->next=seg->next;
|
nseg->next = seg->next;
|
||||||
seg->next=nseg;
|
seg->next = nseg;
|
||||||
}
|
} else {
|
||||||
else{
|
nseg->next = stream->oo_queue;
|
||||||
nseg->next=stream->oo_queue;
|
stream->oo_queue = nseg;
|
||||||
stream->oo_queue=nseg;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
left_edge=seg?seg->s_seq:stream->seq;
|
left_edge = seg ? seg->s_seq : stream->seq;
|
||||||
STRIM(left_edge,nseg);
|
STRIM(left_edge, nseg);
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
/*First segment -- just thread the unallocated data on the
|
/*First segment -- just thread the unallocated data on the
|
||||||
list so we can pass to the analyzer*/
|
list so we can pass to the analyzer*/
|
||||||
_seg.next=0;
|
_seg.next = 0;
|
||||||
_seg.p=p;
|
_seg.p = p;
|
||||||
_seg.s_seq=seq;
|
_seg.s_seq = seq;
|
||||||
|
|
||||||
/*Now split the queue. Assemble as many packets as possible
|
/*Now split the queue. Assemble as many packets as possible
|
||||||
and pass them to the analyzer. But process anything with a
|
and pass them to the analyzer. But process anything with a
|
||||||
RST in it immediately and ignore any data that might be in it
|
RST in it immediately and ignore any data that might be in it
|
||||||
*/
|
*/
|
||||||
if(_seg.p->tcp->th_flags & (TH_RST)){
|
if(_seg.p->tcp->th_flags & (TH_RST)) {
|
||||||
stream->close=_seg.p->tcp->th_flags & (TH_RST);
|
stream->close = _seg.p->tcp->th_flags & (TH_RST);
|
||||||
seg=&_seg;
|
seg = &_seg;
|
||||||
|
|
||||||
conn->state=TCP_STATE_CLOSED;
|
conn->state = TCP_STATE_CLOSED;
|
||||||
}
|
} else {
|
||||||
else{
|
STRIM(stream->seq, &_seg);
|
||||||
STRIM(stream->seq,&_seg);
|
|
||||||
|
|
||||||
if(_seg.p->tcp->th_flags & (TH_FIN)){
|
if(_seg.p->tcp->th_flags & (TH_FIN)) {
|
||||||
stream->close=_seg.p->tcp->th_flags & (TH_FIN);
|
stream->close = _seg.p->tcp->th_flags & (TH_FIN);
|
||||||
seg=&_seg;
|
seg = &_seg;
|
||||||
}
|
} else {
|
||||||
else {
|
for(seg = &_seg; seg->next; seg = seg->next) {
|
||||||
for(seg=&_seg;seg->next;seg=seg->next){
|
if(seg->p->tcp->th_flags & (TH_FIN)) {
|
||||||
if(seg->p->tcp->th_flags & (TH_FIN)){
|
stream->close = _seg.p->tcp->th_flags & (TH_FIN);
|
||||||
stream->close=_seg.p->tcp->th_flags & (TH_FIN);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(seg->len + seg->s_seq != seg->next->s_seq)
|
if(seg->len + seg->s_seq != seg->next->s_seq)
|
||||||
|
@ -349,29 +343,34 @@ process_data_segment (tcp_conn *conn, proto_mod *handler, packet *p, stream_data
|
||||||
do the CLOSE_WAIT/FIN_WAIT stuff, but it's probably
|
do the CLOSE_WAIT/FIN_WAIT stuff, but it's probably
|
||||||
close enough, since this is a higher level protocol analyzer,
|
close enough, since this is a higher level protocol analyzer,
|
||||||
not a TCP analyzer*/
|
not a TCP analyzer*/
|
||||||
if(seg->p->tcp->th_flags & (TH_FIN) ){
|
if(seg->p->tcp->th_flags & (TH_FIN)) {
|
||||||
if(conn->state == TCP_STATE_ESTABLISHED)
|
if(conn->state == TCP_STATE_ESTABLISHED)
|
||||||
conn->state=TCP_STATE_FIN1;
|
conn->state = TCP_STATE_FIN1;
|
||||||
else
|
else
|
||||||
conn->state=TCP_STATE_CLOSED;
|
conn->state = TCP_STATE_CLOSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
free_tcp_segment_queue(stream->oo_queue);
|
free_tcp_segment_queue(stream->oo_queue);
|
||||||
stream->oo_queue=seg->next;
|
stream->oo_queue = seg->next;
|
||||||
seg->next=0;
|
seg->next = 0;
|
||||||
stream->seq=seg->s_seq + seg->len;
|
stream->seq = seg->s_seq + seg->len;
|
||||||
|
|
||||||
DBG((0,"Analyzing segment: %u:%u(%u)", seg->s_seq, seg->s_seq+seg->len, seg->len));
|
DBG((0, "Analyzing segment: %u:%u(%u)", seg->s_seq, seg->s_seq + seg->len,
|
||||||
if((r=conn->analyzer->vtbl->data(conn->analyzer->obj,&_seg,direction))) {
|
seg->len));
|
||||||
DBG((0,"ABORT due to segment: %u:%u(%u)", seg->s_seq, seg->s_seq+seg->len, seg->len));
|
if((r = conn->analyzer->vtbl->data(conn->analyzer->obj, &_seg,
|
||||||
|
direction))) {
|
||||||
|
DBG((0, "ABORT due to segment: %u:%u(%u)", seg->s_seq,
|
||||||
|
seg->s_seq + seg->len, seg->len));
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(stream->close){
|
if(stream->close) {
|
||||||
DBG((0,"Closing with segment: %u:%u(%u)", seg->s_seq, stream->seq, seg->len));
|
DBG((0, "Closing with segment: %u:%u(%u)", seg->s_seq, stream->seq,
|
||||||
if((r=conn->analyzer->vtbl->close(conn->analyzer->obj,p,direction))) {
|
seg->len));
|
||||||
DBG((0,"ABORT due to segment: %u:%u(%u)", seg->s_seq, stream->seq, seg->len));
|
if((r = conn->analyzer->vtbl->close(conn->analyzer->obj, p, direction))) {
|
||||||
|
DBG((0, "ABORT due to segment: %u:%u(%u)", seg->s_seq, stream->seq,
|
||||||
|
seg->len));
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -379,40 +378,34 @@ process_data_segment (tcp_conn *conn, proto_mod *handler, packet *p, stream_data
|
||||||
free_tcp_segment_queue(_seg.next);
|
free_tcp_segment_queue(_seg.next);
|
||||||
}
|
}
|
||||||
|
|
||||||
_status=0;
|
_status = 0;
|
||||||
abort:
|
abort:
|
||||||
return(_status);
|
return (_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int print_tcp_packet(packet *p) {
|
||||||
print_tcp_packet (packet *p)
|
char *src = 0, *dst = 0;
|
||||||
{
|
|
||||||
char *src=0,*dst=0;
|
|
||||||
|
|
||||||
struct timeval *ts = &p->ts;
|
struct timeval *ts = &p->ts;
|
||||||
|
|
||||||
if(!(NET_print_flags & NET_PRINT_TCP_HDR))
|
if(!(NET_print_flags & NET_PRINT_TCP_HDR))
|
||||||
return(0);
|
return (0);
|
||||||
|
|
||||||
lookuphostname(&p->i_addr.so_st,&src);
|
lookuphostname(&p->i_addr.so_st, &src);
|
||||||
lookuphostname(&p->r_addr.so_st,&dst);
|
lookuphostname(&p->r_addr.so_st, &dst);
|
||||||
|
|
||||||
if(!(NET_print_flags & NET_PRINT_JSON)) {
|
if(!(NET_print_flags & NET_PRINT_JSON)) {
|
||||||
if(NET_print_flags & NET_PRINT_TS) {
|
if(NET_print_flags & NET_PRINT_TS) {
|
||||||
printf("%lld%c%4.4lld ", (long long)ts->tv_sec,'.',(long long)ts->tv_usec/100);
|
printf("%lld%c%4.4lld ", (long long)ts->tv_sec, '.',
|
||||||
|
(long long)ts->tv_usec / 100);
|
||||||
}
|
}
|
||||||
printf("TCP: %s(%d) -> %s(%d) ",
|
printf("TCP: %s(%d) -> %s(%d) ", src, ntohs(p->tcp->th_sport), dst,
|
||||||
src,
|
|
||||||
ntohs(p->tcp->th_sport),
|
|
||||||
dst,
|
|
||||||
ntohs(p->tcp->th_dport));
|
ntohs(p->tcp->th_dport));
|
||||||
|
|
||||||
printf("Seq %u.(%d) ",
|
printf("Seq %u.(%d) ", ntohl(p->tcp->th_seq), p->len - p->tcp->th_off * 4);
|
||||||
ntohl(p->tcp->th_seq),
|
|
||||||
p->len - p->tcp->th_off *4);
|
|
||||||
|
|
||||||
if(p->tcp->th_flags & TH_ACK)
|
if(p->tcp->th_flags & TH_ACK)
|
||||||
printf("ACK %u ",ntohl(p->tcp->th_ack));
|
printf("ACK %u ", ntohl(p->tcp->th_ack));
|
||||||
|
|
||||||
if(p->tcp->th_flags & TH_FIN)
|
if(p->tcp->th_flags & TH_FIN)
|
||||||
printf("FIN ");
|
printf("FIN ");
|
||||||
|
@ -429,12 +422,10 @@ print_tcp_packet (packet *p)
|
||||||
}
|
}
|
||||||
free(src);
|
free(src);
|
||||||
free(dst);
|
free(dst);
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int STRIM(UINT4 _seq, segment *s) {
|
||||||
STRIM (UINT4 _seq, segment *s)
|
|
||||||
{
|
|
||||||
int l;
|
int l;
|
||||||
int off;
|
int off;
|
||||||
|
|
||||||
|
@ -444,27 +435,27 @@ STRIM (UINT4 _seq, segment *s)
|
||||||
s->s_seq-=4;
|
s->s_seq-=4;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
l=_seq - (s)->s_seq; /* number of bytes to trim
|
l = _seq - (s)->s_seq; /* number of bytes to trim
|
||||||
from the left of s */
|
from the left of s */
|
||||||
off=(s)->p->tcp->th_off*4;
|
off = (s)->p->tcp->th_off * 4;
|
||||||
if(l>((s)->p->len-off)) ERETURN(R_BAD_DATA);
|
if(l > ((s)->p->len - off))
|
||||||
|
ERETURN(R_BAD_DATA);
|
||||||
|
|
||||||
/* Now remove the leading l bytes */
|
/* Now remove the leading l bytes */
|
||||||
(s)->data=(s)->p->data + off + (l) ;
|
(s)->data = (s)->p->data + off + (l);
|
||||||
(s)->len=(s)->p->len - (off + l);
|
(s)->len = (s)->p->len - (off + l);
|
||||||
(s)->s_seq += (l);
|
(s)->s_seq += (l);
|
||||||
|
|
||||||
/* Now trim to the right if necessary */
|
/* Now trim to the right if necessary */
|
||||||
if((s)->next) {
|
if((s)->next) {
|
||||||
if((s)->s_seq >= (s)->next->s_seq) {
|
if((s)->s_seq >= (s)->next->s_seq) {
|
||||||
l=(s)->s_seq - (s)->next->s_seq;
|
l = (s)->s_seq - (s)->next->s_seq;
|
||||||
|
|
||||||
if((s)->len){
|
if((s)->len) {
|
||||||
(s)->len-=(l+1);
|
(s)->len -= (l + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: tcppack.h,v 1.3 2001/07/20 23:33:15 ekr Exp $
|
$Id: tcppack.h,v 1.3 2001/07/20 23:33:15 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,12 +44,9 @@
|
||||||
ekr@rtfm.com Wed Jan 6 15:08:30 1999
|
ekr@rtfm.com Wed Jan 6 15:08:30 1999
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _tcppack_h
|
#ifndef _tcppack_h
|
||||||
#define _tcppack_h
|
#define _tcppack_h
|
||||||
|
|
||||||
int process_tcp_packet PROTO_LIST((proto_mod *mod,proto_ctx *ctx,
|
int process_tcp_packet PROTO_LIST((proto_mod * mod, proto_ctx *ctx, packet *p));
|
||||||
packet *p));
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: r_assoc.h,v 1.3 2001/12/24 06:06:26 ekr Exp $
|
$Id: r_assoc.h,v 1.3 2001/12/24 06:06:26 ekr Exp $
|
||||||
|
|
||||||
|
@ -47,23 +48,26 @@
|
||||||
ekr@rtfm.com Sun Jan 17 17:57:18 1999
|
ekr@rtfm.com Sun Jan 17 17:57:18 1999
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _r_assoc_h
|
#ifndef _r_assoc_h
|
||||||
#define _r_assoc_h
|
#define _r_assoc_h
|
||||||
|
|
||||||
typedef struct r_assoc_ r_assoc;
|
typedef struct r_assoc_ r_assoc;
|
||||||
|
|
||||||
int r_assoc_create PROTO_LIST((r_assoc **assocp));
|
int r_assoc_create PROTO_LIST((r_assoc * *assocp));
|
||||||
int r_assoc_insert PROTO_LIST((r_assoc *assoc,char *key,int len,
|
int r_assoc_insert PROTO_LIST((r_assoc * assoc,
|
||||||
void *value,int (*copy)(void **new,void *old),
|
char *key,
|
||||||
int (*destroy)(void *ptr),int how));
|
int len,
|
||||||
|
void *value,
|
||||||
|
int (*copy)(void **new, void *old),
|
||||||
|
int (*destroy)(void *ptr),
|
||||||
|
int how));
|
||||||
#define R_ASSOC_REPLACE 0x1
|
#define R_ASSOC_REPLACE 0x1
|
||||||
#define R_ASSOC_NEW 0x2
|
#define R_ASSOC_NEW 0x2
|
||||||
|
|
||||||
int r_assoc_fetch PROTO_LIST((r_assoc *assoc,char *key, int len,
|
int r_assoc_fetch
|
||||||
void **value));
|
PROTO_LIST((r_assoc * assoc, char *key, int len, void **value));
|
||||||
int r_assoc_copy PROTO_LIST((r_assoc **new,r_assoc *old));
|
int r_assoc_copy PROTO_LIST((r_assoc * *new, r_assoc *old));
|
||||||
int r_assoc_destroy PROTO_LIST((r_assoc **assocp));
|
int r_assoc_destroy PROTO_LIST((r_assoc * *assocp));
|
||||||
|
|
||||||
/*We need iterators, but I haven't written them yet*/
|
/*We need iterators, but I haven't written them yet*/
|
||||||
typedef struct r_assoc_iterator_ {
|
typedef struct r_assoc_iterator_ {
|
||||||
|
@ -74,10 +78,9 @@ typedef struct r_assoc_iterator_ {
|
||||||
struct r_assoc_el_ *next;
|
struct r_assoc_el_ *next;
|
||||||
} r_assoc_iterator;
|
} r_assoc_iterator;
|
||||||
|
|
||||||
int r_assoc_init_iter PROTO_LIST((r_assoc *assoc,r_assoc_iterator *));
|
int r_assoc_init_iter PROTO_LIST((r_assoc * assoc, r_assoc_iterator *));
|
||||||
int r_assoc_iter PROTO_LIST((r_assoc_iterator *iter,void **key,int *keyl,
|
int r_assoc_iter
|
||||||
void **val));
|
PROTO_LIST((r_assoc_iterator * iter, void **key, int *keyl, void **val));
|
||||||
int r_assoc_iter_delete PROTO_LIST((r_assoc_iterator *));
|
int r_assoc_iter_delete PROTO_LIST((r_assoc_iterator *));
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
ekr@rtfm.com Wed Oct 3 10:43:50 2001
|
ekr@rtfm.com Wed Oct 3 10:43:50 2001
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _r_bitfield_h
|
#ifndef _r_bitfield_h
|
||||||
#define _r_bitfield_h
|
#define _r_bitfield_h
|
||||||
|
|
||||||
|
@ -17,10 +16,9 @@ typedef struct r_bitfield_ {
|
||||||
UINT4 base;
|
UINT4 base;
|
||||||
} r_bitfield;
|
} r_bitfield;
|
||||||
|
|
||||||
int r_bitfield_set PROTO_LIST((r_bitfield *,int bit));
|
int r_bitfield_set PROTO_LIST((r_bitfield *, int bit));
|
||||||
int r_bitfield_isset PROTO_LIST((r_bitfield *,int bit));
|
int r_bitfield_isset PROTO_LIST((r_bitfield *, int bit));
|
||||||
int r_bitfield_create PROTO_LIST((r_bitfield **setp,UINT4 size));
|
int r_bitfield_create PROTO_LIST((r_bitfield * *setp, UINT4 size));
|
||||||
int r_bitfield_destroy PROTO_LIST((r_bitfield **setp));
|
int r_bitfield_destroy PROTO_LIST((r_bitfield * *setp));
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: r_common.h,v 1.2 2000/10/17 16:09:59 ekr Exp $
|
$Id: r_common.h,v 1.2 2000/10/17 16:09:59 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,7 +44,6 @@
|
||||||
ekr@rtfm.com Tue Dec 22 10:40:07 1998
|
ekr@rtfm.com Tue Dec 22 10:40:07 1998
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _r_common_h
|
#ifndef _r_common_h
|
||||||
#define _r_common_h
|
#define _r_common_h
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@
|
||||||
#include "r_data.h"
|
#include "r_data.h"
|
||||||
|
|
||||||
/*AAH*/
|
/*AAH*/
|
||||||
int xdump PROTO_LIST((char *label,UCHAR *data,int len));
|
int xdump PROTO_LIST((char *label, UCHAR *data, int len));
|
||||||
|
|
||||||
/* defines for possibly replaced functions */
|
/* defines for possibly replaced functions */
|
||||||
#ifndef HAVE_STRDUP
|
#ifndef HAVE_STRDUP
|
||||||
|
@ -67,4 +67,3 @@ char *strdup PROTO_LIST((char *in));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: r_data.h,v 1.2 2000/10/17 16:09:59 ekr Exp $
|
$Id: r_data.h,v 1.2 2000/10/17 16:09:59 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,7 +44,6 @@
|
||||||
ekr@rtfm.com Wed Feb 10 14:18:19 1999
|
ekr@rtfm.com Wed Feb 10 14:18:19 1999
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _r_data_h
|
#ifndef _r_data_h
|
||||||
#define _r_data_h
|
#define _r_data_h
|
||||||
|
|
||||||
|
@ -52,17 +52,22 @@ typedef struct Data_ {
|
||||||
int len;
|
int len;
|
||||||
} Data;
|
} Data;
|
||||||
|
|
||||||
int r_data_create PROTO_LIST((Data **dp,UCHAR *d,int l));
|
int r_data_create PROTO_LIST((Data * *dp, UCHAR *d, int l));
|
||||||
int r_data_alloc PROTO_LIST((Data **dp, int l));
|
int r_data_alloc PROTO_LIST((Data * *dp, int l));
|
||||||
int r_data_make PROTO_LIST((Data *dp, UCHAR *d,int l));
|
int r_data_make PROTO_LIST((Data * dp, UCHAR *d, int l));
|
||||||
int r_data_destroy PROTO_LIST((Data **dp));
|
int r_data_destroy PROTO_LIST((Data * *dp));
|
||||||
int r_data_copy PROTO_LIST((Data *dst,Data *src));
|
int r_data_copy PROTO_LIST((Data * dst, Data *src));
|
||||||
int r_data_zfree PROTO_LIST((Data *d));
|
int r_data_zfree PROTO_LIST((Data * d));
|
||||||
int r_data_compare PROTO_LIST((Data *d1,Data *d2));
|
int r_data_compare PROTO_LIST((Data * d1, Data *d2));
|
||||||
|
|
||||||
#define INIT_DATA(a,b,c) (a).data=b; (a).len=c
|
#define INIT_DATA(a, b, c) \
|
||||||
#define ATTACH_DATA(a,b) (a).data=b; (a).len=sizeof(b)
|
(a).data = b; \
|
||||||
#define ZERO_DATA(a) (a).data=0; (a).len=0
|
(a).len = c
|
||||||
|
#define ATTACH_DATA(a, b) \
|
||||||
|
(a).data = b; \
|
||||||
|
(a).len = sizeof(b)
|
||||||
|
#define ZERO_DATA(a) \
|
||||||
|
(a).data = 0; \
|
||||||
|
(a).len = 0
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: r_defaults.h,v 1.2 2000/10/17 16:09:59 ekr Exp $
|
$Id: r_defaults.h,v 1.2 2000/10/17 16:09:59 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,7 +44,6 @@
|
||||||
ekr@rtfm.com Tue Dec 22 10:39:14 1998
|
ekr@rtfm.com Tue Dec 22 10:39:14 1998
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _r_defaults_h
|
#ifndef _r_defaults_h
|
||||||
#define _r_defaults_h
|
#define _r_defaults_h
|
||||||
|
|
||||||
|
@ -51,9 +51,7 @@
|
||||||
#define R_USE_PROTOTYPES 1
|
#define R_USE_PROTOTYPES 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*The needs defines don't belong here*/
|
/*The needs defines don't belong here*/
|
||||||
#define R_NEEDS_STDLIB_H
|
#define R_NEEDS_STDLIB_H
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: r_errors.h,v 1.3 2002/01/21 17:36:51 ekr Exp $
|
$Id: r_errors.h,v 1.3 2002/01/21 17:36:51 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,7 +44,6 @@
|
||||||
ekr@rtfm.com Tue Dec 22 10:59:49 1998
|
ekr@rtfm.com Tue Dec 22 10:59:49 1998
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _r_errors_h
|
#ifndef _r_errors_h
|
||||||
#define _r_errors_h
|
#define _r_errors_h
|
||||||
|
|
||||||
|
@ -56,7 +56,6 @@
|
||||||
#define R_BAD_DATA 7 /*Bad data*/
|
#define R_BAD_DATA 7 /*Bad data*/
|
||||||
#define R_WOULDBLOCK 8 /*Operation would block */
|
#define R_WOULDBLOCK 8 /*Operation would block */
|
||||||
|
|
||||||
int verr_exit PROTO_LIST((char *fmt,...));
|
int verr_exit PROTO_LIST((char *fmt, ...));
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: r_includes.h,v 1.2 2000/10/17 16:09:59 ekr Exp $
|
$Id: r_includes.h,v 1.2 2000/10/17 16:09:59 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,7 +44,6 @@
|
||||||
ekr@rtfm.com Tue Dec 22 11:38:50 1998
|
ekr@rtfm.com Tue Dec 22 11:38:50 1998
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _r_includes_h
|
#ifndef _r_includes_h
|
||||||
#define _r_includes_h
|
#define _r_includes_h
|
||||||
|
|
||||||
|
@ -59,4 +59,3 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: r_list.h,v 1.2 2000/10/17 16:09:59 ekr Exp $
|
$Id: r_list.h,v 1.2 2000/10/17 16:09:59 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,7 +44,6 @@
|
||||||
ekr@rtfm.com Tue Jan 19 08:36:48 1999
|
ekr@rtfm.com Tue Jan 19 08:36:48 1999
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _r_list_h
|
#ifndef _r_list_h
|
||||||
#define _r_list_h
|
#define _r_list_h
|
||||||
|
|
||||||
|
@ -54,16 +54,18 @@ typedef struct r_list_iterator_ {
|
||||||
struct r_list_el_ *ptr;
|
struct r_list_el_ *ptr;
|
||||||
} r_list_iterator;
|
} r_list_iterator;
|
||||||
|
|
||||||
int r_list_create PROTO_LIST((r_list **listp));
|
int r_list_create PROTO_LIST((r_list * *listp));
|
||||||
int r_list_destroy PROTO_LIST((r_list **listp));
|
int r_list_destroy PROTO_LIST((r_list * *listp));
|
||||||
int r_list_copy PROTO_LIST((r_list **out,r_list *in));
|
int r_list_copy PROTO_LIST((r_list * *out, r_list *in));
|
||||||
int r_list_insert PROTO_LIST((r_list *list,void *value,
|
int r_list_insert PROTO_LIST((r_list * list,
|
||||||
int (*copy)(void **new,void *old),
|
void *value,
|
||||||
|
int (*copy)(void **new, void *old),
|
||||||
int (*destroy)(void **ptr)));
|
int (*destroy)(void **ptr)));
|
||||||
int r_list_append PROTO_LIST((r_list *list,void *value,
|
int r_list_append PROTO_LIST((r_list * list,
|
||||||
int (*copy)(void **new,void *old),
|
void *value,
|
||||||
|
int (*copy)(void **new, void *old),
|
||||||
int (*destroy)(void **ptr)));
|
int (*destroy)(void **ptr)));
|
||||||
int r_list_init_iter PROTO_LIST((r_list *list,r_list_iterator *iter));
|
int r_list_init_iter PROTO_LIST((r_list * list, r_list_iterator *iter));
|
||||||
int r_list_iter PROTO_LIST((r_list_iterator *iter,void **val));
|
int r_list_iter PROTO_LIST((r_list_iterator * iter, void **val));
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: r_macros.h,v 1.4 2001/11/20 17:45:18 ekr Exp $
|
$Id: r_macros.h,v 1.4 2001/11/20 17:45:18 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,11 +44,10 @@
|
||||||
ekr@rtfm.com Tue Dec 22 10:37:32 1998
|
ekr@rtfm.com Tue Dec 22 10:37:32 1998
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _r_macros_h
|
#ifndef _r_macros_h
|
||||||
#define _r_macros_h
|
#define _r_macros_h
|
||||||
|
|
||||||
#if (R_USE_PROTOTYPES==1)
|
#if(R_USE_PROTOTYPES == 1)
|
||||||
#define PROTO_LIST(a) a
|
#define PROTO_LIST(a) a
|
||||||
#else
|
#else
|
||||||
#define PROTO_LIST(a) ()
|
#define PROTO_LIST(a) ()
|
||||||
|
@ -58,34 +58,52 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef R_TRACE_ERRORS
|
#ifdef R_TRACE_ERRORS
|
||||||
#define REPORT_ERROR_(caller,a) fprintf(stderr,"%s: error %d at %s:%d (function %s)\n", \
|
#define REPORT_ERROR_(caller, a) \
|
||||||
caller,a,__FILE__,__LINE__,__FUNCTION__)
|
fprintf(stderr, "%s: error %d at %s:%d (function %s)\n", caller, a, \
|
||||||
|
__FILE__, __LINE__, __FUNCTION__)
|
||||||
#else
|
#else
|
||||||
#define REPORT_ERROR_(caller,a)
|
#define REPORT_ERROR_(caller, a)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ERETURN
|
#ifndef ERETURN
|
||||||
#define ERETURN(a) do {int _r=a; if(!_r) _r=-1; REPORT_ERROR_("ERETURN",_r); return(_r);} while(0)
|
#define ERETURN(a) \
|
||||||
|
do { \
|
||||||
|
int _r = a; \
|
||||||
|
if(!_r) \
|
||||||
|
_r = -1; \
|
||||||
|
REPORT_ERROR_("ERETURN", _r); \
|
||||||
|
return (_r); \
|
||||||
|
} while(0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ABORT
|
#ifndef ABORT
|
||||||
#define ABORT(a) do { int _r=a; if(!_r) _r=-1; REPORT_ERROR_("ABORT",_r); _status=_r; goto abort;} while(0)
|
#define ABORT(a) \
|
||||||
|
do { \
|
||||||
|
int _r = a; \
|
||||||
|
if(!_r) \
|
||||||
|
_r = -1; \
|
||||||
|
REPORT_ERROR_("ABORT", _r); \
|
||||||
|
_status = _r; \
|
||||||
|
goto abort; \
|
||||||
|
} while(0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef FREE
|
#ifndef FREE
|
||||||
#define FREE(a) if(a) free(a)
|
#define FREE(a) \
|
||||||
|
if(a) \
|
||||||
|
free(a)
|
||||||
#endif
|
#endif
|
||||||
#ifndef MIN
|
#ifndef MIN
|
||||||
#define MIN(a,b) (((a)>(b))?(b):(a))
|
#define MIN(a, b) (((a) > (b)) ? (b) : (a))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef MAX
|
#ifndef MAX
|
||||||
#define MAX(a,b) (((b)>(a))?(b):(a))
|
#define MAX(a, b) (((b) > (a)) ? (b) : (a))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
#define DBG(a) debug a
|
#define DBG(a) debug a
|
||||||
int debug(int class,char *format,...);
|
int debug(int class, char *format, ...);
|
||||||
#else
|
#else
|
||||||
#define DBG(a)
|
#define DBG(a)
|
||||||
#endif
|
#endif
|
||||||
|
@ -95,18 +113,24 @@ int debug(int class,char *format,...);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef RCALLOC
|
#ifndef RCALLOC
|
||||||
#define RCALLOC(a) calloc(1,a)
|
#define RCALLOC(a) calloc(1, a)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef RFREE
|
#ifndef RFREE
|
||||||
#define RFREE(a) if(a) free(a)
|
#define RFREE(a) \
|
||||||
|
if(a) \
|
||||||
|
free(a)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef RREALLOC
|
#ifndef RREALLOC
|
||||||
#define RREALLOC(a,b) realloc(a,b)
|
#define RREALLOC(a, b) realloc(a, b)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define UNIMPLEMENTED do { fprintf(stderr,"Function %s unimplemented\n",__FUNCTION__); abort(); } while(0)
|
#define UNIMPLEMENTED \
|
||||||
|
do { \
|
||||||
|
fprintf(stderr, "Function %s unimplemented\n", __FUNCTION__); \
|
||||||
|
abort(); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
#ifdef STDC_HEADERS
|
#ifdef STDC_HEADERS
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -115,9 +139,9 @@ int debug(int class,char *format,...);
|
||||||
#ifndef STRNICMP
|
#ifndef STRNICMP
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define STRNICMP(a,b,n) strnicmp(a,b,n)
|
#define STRNICMP(a, b, n) strnicmp(a, b, n)
|
||||||
#else
|
#else
|
||||||
#define STRNICMP(a,b,n) strncasecmp(a,b,n)
|
#define STRNICMP(a, b, n) strncasecmp(a, b, n)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: r_thread.h,v 1.2 2000/10/17 16:09:59 ekr Exp $
|
$Id: r_thread.h,v 1.2 2000/10/17 16:09:59 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,27 +44,24 @@
|
||||||
ekr@rtfm.com Tue Feb 23 14:58:36 1999
|
ekr@rtfm.com Tue Feb 23 14:58:36 1999
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _r_thread_h
|
#ifndef _r_thread_h
|
||||||
#define _r_thread_h
|
#define _r_thread_h
|
||||||
|
|
||||||
typedef void *r_thread;
|
typedef void *r_thread;
|
||||||
typedef void *r_rwlock;
|
typedef void *r_rwlock;
|
||||||
|
|
||||||
int r_thread_fork PROTO_LIST((void (*func)(void *),void *arg,
|
int r_thread_fork PROTO_LIST((void (*func)(void *), void *arg, r_thread *tid));
|
||||||
r_thread *tid));
|
|
||||||
int r_thread_destroy PROTO_LIST((r_thread tid));
|
int r_thread_destroy PROTO_LIST((r_thread tid));
|
||||||
int r_thread_yield PROTO_LIST((void));
|
int r_thread_yield PROTO_LIST((void));
|
||||||
int r_thread_exit PROTO_LIST((void));
|
int r_thread_exit PROTO_LIST((void));
|
||||||
int r_thread_wait_last PROTO_LIST((void));
|
int r_thread_wait_last PROTO_LIST((void));
|
||||||
|
|
||||||
int r_rwlock_create PROTO_LIST((r_rwlock **lockp));
|
int r_rwlock_create PROTO_LIST((r_rwlock * *lockp));
|
||||||
int r_rwlock_destroy PROTO_LIST((r_rwlock **lock));
|
int r_rwlock_destroy PROTO_LIST((r_rwlock * *lock));
|
||||||
int r_rwlock_lock PROTO_LIST((r_rwlock *lock,int action));
|
int r_rwlock_lock PROTO_LIST((r_rwlock * lock, int action));
|
||||||
|
|
||||||
#define R_RWLOCK_UNLOCK 0
|
#define R_RWLOCK_UNLOCK 0
|
||||||
#define R_RWLOCK_RLOCK 1
|
#define R_RWLOCK_RLOCK 1
|
||||||
#define R_RWLOCK_WLOCK 2
|
#define R_RWLOCK_WLOCK 2
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: r_time.h,v 1.4 2001/12/24 06:06:26 ekr Exp $
|
$Id: r_time.h,v 1.4 2001/12/24 06:06:26 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,7 +44,6 @@
|
||||||
ekr@rtfm.com Thu Mar 4 08:45:41 1999
|
ekr@rtfm.com Thu Mar 4 08:45:41 1999
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _r_time_h
|
#ifndef _r_time_h
|
||||||
#define _r_time_h
|
#define _r_time_h
|
||||||
|
|
||||||
|
@ -52,28 +52,29 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
# include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#else
|
#else
|
||||||
/* Cribbed from the autoconf doc */
|
/* Cribbed from the autoconf doc */
|
||||||
# if TIME_WITH_SYS_TIME
|
#if TIME_WITH_SYS_TIME
|
||||||
# include <sys/time.h>
|
#include <sys/time.h>
|
||||||
# include <time.h>
|
#include <time.h>
|
||||||
# else
|
#else
|
||||||
# if HAVE_SYS_TIME_H
|
#if HAVE_SYS_TIME_H
|
||||||
# include <sys/time.h>
|
#include <sys/time.h>
|
||||||
# else
|
#else
|
||||||
# include <time.h>
|
#include <time.h>
|
||||||
# endif
|
#endif
|
||||||
# endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int r_timeval_diff PROTO_LIST((struct timeval *t1,struct timeval *t0,
|
int r_timeval_diff PROTO_LIST((struct timeval * t1,
|
||||||
|
struct timeval *t0,
|
||||||
struct timeval *diff));
|
struct timeval *diff));
|
||||||
int r_timeval_add PROTO_LIST((struct timeval *t1,struct timeval *t2,
|
int r_timeval_add PROTO_LIST((struct timeval * t1,
|
||||||
|
struct timeval *t2,
|
||||||
struct timeval *sum));
|
struct timeval *sum));
|
||||||
|
|
||||||
UINT8 r_timeval2int PROTO_LIST((struct timeval *tv));
|
UINT8 r_timeval2int PROTO_LIST((struct timeval * tv));
|
||||||
UINT8 r_gettimeint PROTO_LIST((void));
|
UINT8 r_gettimeint PROTO_LIST((void));
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: r_types.h,v 1.3 2002/09/09 21:02:58 ekr Exp $
|
$Id: r_types.h,v 1.3 2002/09/09 21:02:58 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,7 +44,6 @@
|
||||||
ekr@rtfm.com Tue Dec 22 10:36:02 1998
|
ekr@rtfm.com Tue Dec 22 10:36:02 1998
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _r_types_h
|
#ifndef _r_types_h
|
||||||
#define _r_types_h
|
#define _r_types_h
|
||||||
|
|
||||||
|
@ -55,15 +55,15 @@
|
||||||
#ifndef SIZEOF_UNSIGNED_INT
|
#ifndef SIZEOF_UNSIGNED_INT
|
||||||
typedef unsigned int UINT4;
|
typedef unsigned int UINT4;
|
||||||
#else
|
#else
|
||||||
# if (SIZEOF_UNSIGNED_INT==4)
|
#if(SIZEOF_UNSIGNED_INT == 4)
|
||||||
typedef unsigned int UINT4;
|
typedef unsigned int UINT4;
|
||||||
# elif (SIZEOF_UNSIGNED_SHORT==4)
|
#elif(SIZEOF_UNSIGNED_SHORT == 4)
|
||||||
typedef unsigned short UINT4;
|
typedef unsigned short UINT4;
|
||||||
# elif (SIZEOF_UNSIGNED_LONG==4)
|
#elif(SIZEOF_UNSIGNED_LONG == 4)
|
||||||
typedef unsigned long UINT4;
|
typedef unsigned long UINT4;
|
||||||
# else
|
#else
|
||||||
# error no type for UINT4
|
#error no type for UINT4
|
||||||
# endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -71,19 +71,19 @@ typedef unsigned long UINT4;
|
||||||
#ifndef SIZEOF_UNSIGNED_LONG
|
#ifndef SIZEOF_UNSIGNED_LONG
|
||||||
typedef unsigned long UINT8;
|
typedef unsigned long UINT8;
|
||||||
#else
|
#else
|
||||||
# if (SIZEOF_UNSIGNED_INT==8)
|
#if(SIZEOF_UNSIGNED_INT == 8)
|
||||||
typedef unsigned int UINT8;
|
typedef unsigned int UINT8;
|
||||||
# elif (SIZEOF_UNSIGNED_SHORT==8)
|
#elif(SIZEOF_UNSIGNED_SHORT == 8)
|
||||||
typedef unsigned short UINT8;
|
typedef unsigned short UINT8;
|
||||||
# elif (SIZEOF_UNSIGNED_LONG==8)
|
#elif(SIZEOF_UNSIGNED_LONG == 8)
|
||||||
typedef unsigned long UINT8;
|
typedef unsigned long UINT8;
|
||||||
# elif (SIZEOF_UNSIGNED_LONG_LONG==8)
|
#elif(SIZEOF_UNSIGNED_LONG_LONG == 8)
|
||||||
typedef unsigned long long UINT8;
|
typedef unsigned long long UINT8;
|
||||||
# elif defined (_WIN32) && defined (_MSC_VER)
|
#elif defined(_WIN32) && defined(_MSC_VER)
|
||||||
typedef unsigned __int64 UINT8;
|
typedef unsigned __int64 UINT8;
|
||||||
# else
|
#else
|
||||||
# error no type for UINT8
|
#error no type for UINT8
|
||||||
# endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -92,4 +92,3 @@ typedef unsigned char UCHAR;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: assoc.h,v 1.2 2000/10/17 16:10:00 ekr Exp $
|
$Id: assoc.h,v 1.2 2000/10/17 16:10:00 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,11 +44,9 @@
|
||||||
ekr@rtfm.com Sun Jan 17 17:56:35 1999
|
ekr@rtfm.com Sun Jan 17 17:56:35 1999
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _assoc_h
|
#ifndef _assoc_h
|
||||||
#define _assoc_h
|
#define _assoc_h
|
||||||
|
|
||||||
typedef struct assoc_ assoc;
|
typedef struct assoc_ assoc;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: debug.c,v 1.3 2001/12/24 06:06:26 ekr Exp $
|
$Id: debug.c,v 1.3 2001/12/24 06:06:26 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,47 +44,34 @@
|
||||||
ekr@rtfm.com Wed Jan 6 17:08:58 1999
|
ekr@rtfm.com Wed Jan 6 17:08:58 1999
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "r_common.h"
|
#include "r_common.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
int debug(int class,char *format,...)
|
int debug(int class, char *format, ...) {
|
||||||
{
|
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap,format);
|
va_start(ap, format);
|
||||||
vfprintf(stderr,format,ap);
|
vfprintf(stderr, format, ap);
|
||||||
fprintf(stderr,"\n");
|
fprintf(stderr, "\n");
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int xdump(char *name, UCHAR *data, int len) {
|
||||||
xdump (char *name, UCHAR *data, int len)
|
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if(name){
|
if(name) {
|
||||||
printf("%s[%d]=\n",name,len);
|
printf("%s[%d]=\n", name, len);
|
||||||
}
|
}
|
||||||
for(i=0;i<len;i++){
|
for(i = 0; i < len; i++) {
|
||||||
|
if((len > 8) && i && !(i % 12)) {
|
||||||
if((len>8) && i && !(i%12)){
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
printf("%.2x ",data[i]&255);
|
printf("%.2x ", data[i] & 255);
|
||||||
}
|
}
|
||||||
if(i%12)
|
if(i % 12)
|
||||||
printf("\n");
|
printf("\n");
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: debug.h,v 1.3 2001/12/24 06:06:26 ekr Exp $
|
$Id: debug.h,v 1.3 2001/12/24 06:06:26 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,7 +44,6 @@
|
||||||
ekr@rtfm.com Wed Jan 6 17:13:00 1999
|
ekr@rtfm.com Wed Jan 6 17:13:00 1999
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _debug_h
|
#ifndef _debug_h
|
||||||
#define _debug_h
|
#define _debug_h
|
||||||
|
|
||||||
|
@ -53,9 +53,7 @@
|
||||||
#define DBG(a)
|
#define DBG(a)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int debug(int class,char *format,...);
|
int debug(int class, char *format, ...);
|
||||||
int xdump PROTO_LIST((char *name,UCHAR *data,
|
int xdump PROTO_LIST((char *name, UCHAR *data, int len));
|
||||||
int len));
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: r_assoc.c,v 1.4 2001/12/24 06:06:26 ekr Exp $
|
$Id: r_assoc.c,v 1.4 2001/12/24 06:06:26 ekr Exp $
|
||||||
|
|
||||||
|
@ -54,7 +55,6 @@
|
||||||
ekr@rtfm.com Sun Jan 17 17:57:15 1999
|
ekr@rtfm.com Sun Jan 17 17:57:15 1999
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <r_common.h>
|
#include <r_common.h>
|
||||||
#include "r_assoc.h"
|
#include "r_assoc.h"
|
||||||
|
|
||||||
|
@ -64,8 +64,8 @@ typedef struct r_assoc_el_ {
|
||||||
void *data;
|
void *data;
|
||||||
struct r_assoc_el_ *prev;
|
struct r_assoc_el_ *prev;
|
||||||
struct r_assoc_el_ *next;
|
struct r_assoc_el_ *next;
|
||||||
int (*copy) PROTO_LIST((void **new,void *old));
|
int(*copy) PROTO_LIST((void **new, void *old));
|
||||||
int (*destroy) PROTO_LIST((void *ptr));
|
int(*destroy) PROTO_LIST((void *ptr));
|
||||||
} r_assoc_el;
|
} r_assoc_el;
|
||||||
|
|
||||||
struct r_assoc_ {
|
struct r_assoc_ {
|
||||||
|
@ -76,64 +76,57 @@ struct r_assoc_ {
|
||||||
|
|
||||||
#define DEFAULT_TABLE_BITS 5
|
#define DEFAULT_TABLE_BITS 5
|
||||||
|
|
||||||
static int destroy_assoc_chain PROTO_LIST((r_assoc_el *chain));
|
static int destroy_assoc_chain PROTO_LIST((r_assoc_el * chain));
|
||||||
static int r_assoc_fetch_bucket PROTO_LIST((r_assoc *assoc,
|
static int r_assoc_fetch_bucket
|
||||||
char *key,int len,r_assoc_el **bucketp));
|
PROTO_LIST((r_assoc * assoc, char *key, int len, r_assoc_el **bucketp));
|
||||||
UINT4 hash_compute PROTO_LIST((char *key,int len,int size));
|
UINT4 hash_compute PROTO_LIST((char *key, int len, int size));
|
||||||
static int copy_assoc_chain PROTO_LIST((r_assoc_el **newp,
|
static int copy_assoc_chain PROTO_LIST((r_assoc_el * *newp, r_assoc_el *old));
|
||||||
r_assoc_el *old));
|
|
||||||
|
|
||||||
int
|
int r_assoc_create(r_assoc **assocp) {
|
||||||
r_assoc_create (r_assoc **assocp)
|
r_assoc *assoc = 0;
|
||||||
{
|
|
||||||
r_assoc *assoc=0;
|
|
||||||
int _status;
|
int _status;
|
||||||
|
|
||||||
if(!(assoc=(r_assoc *)calloc(sizeof(r_assoc),1)))
|
if(!(assoc = (r_assoc *)calloc(sizeof(r_assoc), 1)))
|
||||||
ABORT(R_NO_MEMORY);
|
ABORT(R_NO_MEMORY);
|
||||||
assoc->size=(1<<DEFAULT_TABLE_BITS);
|
assoc->size = (1 << DEFAULT_TABLE_BITS);
|
||||||
assoc->bits=DEFAULT_TABLE_BITS;
|
assoc->bits = DEFAULT_TABLE_BITS;
|
||||||
|
|
||||||
if(!(assoc->chains=(r_assoc_el **)calloc(sizeof(r_assoc_el *),
|
if(!(assoc->chains =
|
||||||
assoc->size)))
|
(r_assoc_el **)calloc(sizeof(r_assoc_el *), assoc->size)))
|
||||||
ABORT(R_NO_MEMORY);
|
ABORT(R_NO_MEMORY);
|
||||||
|
|
||||||
*assocp=assoc;
|
*assocp = assoc;
|
||||||
|
|
||||||
_status=0;
|
_status = 0;
|
||||||
abort:
|
abort:
|
||||||
if(_status){
|
if(_status) {
|
||||||
r_assoc_destroy(&assoc);
|
r_assoc_destroy(&assoc);
|
||||||
}
|
}
|
||||||
return(_status);
|
return (_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int r_assoc_destroy(r_assoc **assocp) {
|
||||||
r_assoc_destroy (r_assoc **assocp)
|
|
||||||
{
|
|
||||||
r_assoc *assoc;
|
r_assoc *assoc;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if(!assocp || !*assocp)
|
if(!assocp || !*assocp)
|
||||||
return(0);
|
return (0);
|
||||||
|
|
||||||
assoc=*assocp;
|
assoc = *assocp;
|
||||||
for(i=0;i<assoc->size;i++)
|
for(i = 0; i < assoc->size; i++)
|
||||||
destroy_assoc_chain(assoc->chains[i]);
|
destroy_assoc_chain(assoc->chains[i]);
|
||||||
|
|
||||||
free(assoc->chains);
|
free(assoc->chains);
|
||||||
free(assoc);
|
free(assoc);
|
||||||
|
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int destroy_assoc_chain(r_assoc_el *chain) {
|
||||||
destroy_assoc_chain (r_assoc_el *chain)
|
|
||||||
{
|
|
||||||
r_assoc_el *nxt;
|
r_assoc_el *nxt;
|
||||||
|
|
||||||
while(chain){
|
while(chain) {
|
||||||
nxt=chain->next;
|
nxt = chain->next;
|
||||||
|
|
||||||
if(chain->destroy)
|
if(chain->destroy)
|
||||||
chain->destroy(chain->data);
|
chain->destroy(chain->data);
|
||||||
|
@ -141,273 +134,252 @@ destroy_assoc_chain (r_assoc_el *chain)
|
||||||
free(chain->key);
|
free(chain->key);
|
||||||
|
|
||||||
free(chain);
|
free(chain);
|
||||||
chain=nxt;
|
chain = nxt;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int copy_assoc_chain(r_assoc_el **newp, r_assoc_el *old) {
|
||||||
copy_assoc_chain (r_assoc_el **newp, r_assoc_el *old)
|
r_assoc_el *new = 0, *ptr, *tmp;
|
||||||
{
|
int r, _status;
|
||||||
r_assoc_el *new=0,*ptr,*tmp;
|
|
||||||
int r,_status;
|
|
||||||
|
|
||||||
if(!old) {
|
if(!old) {
|
||||||
*newp=0;
|
*newp = 0;
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
for(;old;old=old->next){
|
for(; old; old = old->next) {
|
||||||
if(!(tmp=(r_assoc_el *)calloc(sizeof(r_assoc_el),1)))
|
if(!(tmp = (r_assoc_el *)calloc(sizeof(r_assoc_el), 1)))
|
||||||
ABORT(R_NO_MEMORY);
|
ABORT(R_NO_MEMORY);
|
||||||
|
|
||||||
if(!new){
|
if(!new) {
|
||||||
new=tmp;
|
new = tmp;
|
||||||
ptr=new;
|
ptr = new;
|
||||||
}
|
} else {
|
||||||
else{
|
ptr->next = tmp;
|
||||||
ptr->next=tmp;
|
tmp->prev = ptr;
|
||||||
tmp->prev=ptr;
|
ptr = tmp;
|
||||||
ptr=tmp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr->destroy=old->destroy;
|
ptr->destroy = old->destroy;
|
||||||
ptr->copy=old->copy;
|
ptr->copy = old->copy;
|
||||||
|
|
||||||
if(old->copy){
|
if(old->copy) {
|
||||||
if((r=old->copy(&ptr->data,old->data)))
|
if((r = old->copy(&ptr->data, old->data)))
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
}
|
} else
|
||||||
else
|
ptr->data = old->data;
|
||||||
ptr->data=old->data;
|
|
||||||
|
|
||||||
if(!(ptr->key=(char *)malloc(old->key_len)))
|
if(!(ptr->key = (char *)malloc(old->key_len)))
|
||||||
ABORT(R_NO_MEMORY);
|
ABORT(R_NO_MEMORY);
|
||||||
memcpy(ptr->key,old->key,ptr->key_len=old->key_len);
|
memcpy(ptr->key, old->key, ptr->key_len = old->key_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
*newp=new;
|
*newp = new;
|
||||||
|
|
||||||
_status=0;
|
_status = 0;
|
||||||
abort:
|
abort:
|
||||||
if(_status){
|
if(_status) {
|
||||||
destroy_assoc_chain(new);
|
destroy_assoc_chain(new);
|
||||||
}
|
}
|
||||||
return(_status);
|
return (_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int r_assoc_fetch_bucket(r_assoc *assoc,
|
||||||
r_assoc_fetch_bucket (r_assoc *assoc, char *key, int len, r_assoc_el **bucketp)
|
char *key,
|
||||||
{
|
int len,
|
||||||
|
r_assoc_el **bucketp) {
|
||||||
UINT4 hash_value;
|
UINT4 hash_value;
|
||||||
r_assoc_el *bucket;
|
r_assoc_el *bucket;
|
||||||
|
|
||||||
hash_value=hash_compute(key,len,assoc->bits);
|
hash_value = hash_compute(key, len, assoc->bits);
|
||||||
|
|
||||||
for(bucket=assoc->chains[hash_value];bucket;bucket=bucket->next){
|
for(bucket = assoc->chains[hash_value]; bucket; bucket = bucket->next) {
|
||||||
if(bucket->key_len == len && !memcmp(bucket->key,key,len)){
|
if(bucket->key_len == len && !memcmp(bucket->key, key, len)) {
|
||||||
*bucketp=bucket;
|
*bucketp = bucket;
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return(R_NOT_FOUND);
|
return (R_NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int r_assoc_fetch(r_assoc *assoc, char *key, int len, void **datap) {
|
||||||
r_assoc_fetch (r_assoc *assoc, char *key, int len, void **datap)
|
|
||||||
{
|
|
||||||
r_assoc_el *bucket;
|
r_assoc_el *bucket;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if((r=r_assoc_fetch_bucket(assoc,key,len,&bucket))){
|
if((r = r_assoc_fetch_bucket(assoc, key, len, &bucket))) {
|
||||||
if(r!=R_NOT_FOUND)
|
if(r != R_NOT_FOUND)
|
||||||
ERETURN(r);
|
ERETURN(r);
|
||||||
return(r);
|
return (r);
|
||||||
}
|
}
|
||||||
|
|
||||||
*datap=bucket->data;
|
*datap = bucket->data;
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int r_assoc_insert(
|
int r_assoc_insert(r_assoc *assoc,
|
||||||
r_assoc *assoc,
|
|
||||||
char *key,
|
char *key,
|
||||||
int len,
|
int len,
|
||||||
void *data,
|
void *data,
|
||||||
int (*copy) PROTO_LIST((void **new,void *old)),
|
int(*copy) PROTO_LIST((void **new, void *old)),
|
||||||
int (*destroy) PROTO_LIST((void *ptr)),
|
int(*destroy) PROTO_LIST((void *ptr)),
|
||||||
int how)
|
int how) {
|
||||||
{
|
r_assoc_el *bucket, *new_bucket = 0;
|
||||||
r_assoc_el *bucket,*new_bucket=0;
|
int r, _status;
|
||||||
int r,_status;
|
|
||||||
|
|
||||||
if((r=r_assoc_fetch_bucket(assoc,key,len,&bucket))){
|
if((r = r_assoc_fetch_bucket(assoc, key, len, &bucket))) {
|
||||||
/*Note that we compute the hash value twice*/
|
/*Note that we compute the hash value twice*/
|
||||||
UINT4 hash_value;
|
UINT4 hash_value;
|
||||||
|
|
||||||
if(r!=R_NOT_FOUND)
|
if(r != R_NOT_FOUND)
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
hash_value=hash_compute(key,len,assoc->bits);
|
hash_value = hash_compute(key, len, assoc->bits);
|
||||||
|
|
||||||
if(!(new_bucket=(r_assoc_el *)calloc(sizeof(r_assoc_el),1)))
|
if(!(new_bucket = (r_assoc_el *)calloc(sizeof(r_assoc_el), 1)))
|
||||||
ABORT(R_NO_MEMORY);
|
ABORT(R_NO_MEMORY);
|
||||||
if(!(new_bucket->key=(char *)malloc(len)))
|
if(!(new_bucket->key = (char *)malloc(len)))
|
||||||
ABORT(R_NO_MEMORY);
|
ABORT(R_NO_MEMORY);
|
||||||
memcpy(new_bucket->key,key,len);
|
memcpy(new_bucket->key, key, len);
|
||||||
new_bucket->key_len=len;
|
new_bucket->key_len = len;
|
||||||
|
|
||||||
/*Insert at the list head. Is FIFO a good algorithm?*/
|
/*Insert at the list head. Is FIFO a good algorithm?*/
|
||||||
if(assoc->chains[hash_value])
|
if(assoc->chains[hash_value])
|
||||||
assoc->chains[hash_value]->prev=new_bucket;
|
assoc->chains[hash_value]->prev = new_bucket;
|
||||||
new_bucket->next=assoc->chains[hash_value];
|
new_bucket->next = assoc->chains[hash_value];
|
||||||
assoc->chains[hash_value]=new_bucket;
|
assoc->chains[hash_value] = new_bucket;
|
||||||
bucket=new_bucket;
|
bucket = new_bucket;
|
||||||
}
|
} else {
|
||||||
else{
|
if(!(how & R_ASSOC_REPLACE))
|
||||||
if(!(how&R_ASSOC_REPLACE))
|
|
||||||
ABORT(R_ALREADY);
|
ABORT(R_ALREADY);
|
||||||
|
|
||||||
if(bucket->destroy)
|
if(bucket->destroy)
|
||||||
bucket->destroy(bucket->data);
|
bucket->destroy(bucket->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
bucket->data=data;
|
bucket->data = data;
|
||||||
bucket->copy=copy;
|
bucket->copy = copy;
|
||||||
bucket->destroy=destroy;
|
bucket->destroy = destroy;
|
||||||
|
|
||||||
_status=0;
|
_status = 0;
|
||||||
abort:
|
abort:
|
||||||
if(_status && new_bucket){
|
if(_status && new_bucket) {
|
||||||
free(new_bucket->key);
|
free(new_bucket->key);
|
||||||
free(new_bucket);
|
free(new_bucket);
|
||||||
}
|
}
|
||||||
return(_status);
|
return (_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int r_assoc_copy(r_assoc **newp, r_assoc *old) {
|
||||||
r_assoc_copy (r_assoc **newp, r_assoc *old)
|
int r, _status, i;
|
||||||
{
|
|
||||||
int r,_status,i;
|
|
||||||
r_assoc *new;
|
r_assoc *new;
|
||||||
|
|
||||||
if(!(new=(r_assoc *)calloc(sizeof(r_assoc),1)))
|
if(!(new = (r_assoc *)calloc(sizeof(r_assoc), 1)))
|
||||||
ABORT(R_NO_MEMORY);
|
ABORT(R_NO_MEMORY);
|
||||||
new->size=old->size;
|
new->size = old->size;
|
||||||
new->bits=old->bits;
|
new->bits = old->bits;
|
||||||
|
|
||||||
if(!(new->chains=(r_assoc_el **)calloc(sizeof(r_assoc_el),old->size)))
|
if(!(new->chains = (r_assoc_el **)calloc(sizeof(r_assoc_el), old->size)))
|
||||||
ABORT(R_NO_MEMORY);
|
ABORT(R_NO_MEMORY);
|
||||||
for(i=0;i<new->size;i++){
|
for(i = 0; i < new->size; i++) {
|
||||||
if((r=copy_assoc_chain(new->chains+i,old->chains[i])))
|
if((r = copy_assoc_chain(new->chains + i, old->chains[i])))
|
||||||
ABORT(R_NO_MEMORY);
|
ABORT(R_NO_MEMORY);
|
||||||
}
|
}
|
||||||
*newp=new;
|
*newp = new;
|
||||||
|
|
||||||
_status=0;
|
_status = 0;
|
||||||
abort:
|
abort:
|
||||||
if(_status){
|
if(_status) {
|
||||||
r_assoc_destroy(&new);
|
r_assoc_destroy(&new);
|
||||||
}
|
}
|
||||||
return(_status);
|
return (_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int r_assoc_init_iter(r_assoc *assoc, r_assoc_iterator *iter) {
|
||||||
r_assoc_init_iter (r_assoc *assoc, r_assoc_iterator *iter)
|
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
iter->assoc=assoc;
|
iter->assoc = assoc;
|
||||||
iter->prev_chain=-1;
|
iter->prev_chain = -1;
|
||||||
iter->prev=0;
|
iter->prev = 0;
|
||||||
|
|
||||||
iter->next_chain=assoc->size;
|
iter->next_chain = assoc->size;
|
||||||
iter->next=0;
|
iter->next = 0;
|
||||||
|
|
||||||
for(i=0;i<assoc->size;i++){
|
for(i = 0; i < assoc->size; i++) {
|
||||||
if(assoc->chains[i]!=0){
|
if(assoc->chains[i] != 0) {
|
||||||
iter->next_chain=i;
|
iter->next_chain = i;
|
||||||
iter->next=assoc->chains[i];
|
iter->next = assoc->chains[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int r_assoc_iter(r_assoc_iterator *iter, void **key, int *keyl, void **val) {
|
||||||
r_assoc_iter (r_assoc_iterator *iter, void **key, int *keyl, void **val)
|
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
r_assoc_el *ret;
|
r_assoc_el *ret;
|
||||||
|
|
||||||
if(!iter->next)
|
if(!iter->next)
|
||||||
return(R_EOD);
|
return (R_EOD);
|
||||||
ret=iter->next;
|
ret = iter->next;
|
||||||
|
|
||||||
*key=ret->key;
|
*key = ret->key;
|
||||||
*keyl=ret->key_len;
|
*keyl = ret->key_len;
|
||||||
*val=ret->data;
|
*val = ret->data;
|
||||||
|
|
||||||
/* Now increment */
|
/* Now increment */
|
||||||
iter->prev_chain=iter->next_chain;
|
iter->prev_chain = iter->next_chain;
|
||||||
iter->prev=iter->next;
|
iter->prev = iter->next;
|
||||||
|
|
||||||
/* More on this chain */
|
/* More on this chain */
|
||||||
if(iter->next->next){
|
if(iter->next->next) {
|
||||||
iter->next=iter->next->next;
|
iter->next = iter->next->next;
|
||||||
}
|
} else {
|
||||||
else{
|
iter->next = 0;
|
||||||
iter->next=0;
|
|
||||||
|
|
||||||
/* FInd the next occupied chain*/
|
/* FInd the next occupied chain*/
|
||||||
for(i=iter->next_chain;i<iter->assoc->size;i++){
|
for(i = iter->next_chain; i < iter->assoc->size; i++) {
|
||||||
if(iter->assoc->chains[i]){
|
if(iter->assoc->chains[i]) {
|
||||||
iter->next_chain=i;
|
iter->next_chain = i;
|
||||||
iter->next=iter->assoc->chains[i];
|
iter->next = iter->assoc->chains[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Delete the last returned value*/
|
/* Delete the last returned value*/
|
||||||
int
|
int r_assoc_iter_delete(r_assoc_iterator *iter) {
|
||||||
r_assoc_iter_delete (r_assoc_iterator *iter)
|
|
||||||
{
|
|
||||||
/* First unhook it from the list*/
|
/* First unhook it from the list*/
|
||||||
if(!iter->prev->prev){
|
if(!iter->prev->prev) {
|
||||||
/* First element*/
|
/* First element*/
|
||||||
iter->assoc->chains[iter->prev_chain]=iter->prev->next;
|
iter->assoc->chains[iter->prev_chain] = iter->prev->next;
|
||||||
}
|
} else {
|
||||||
else{
|
iter->prev->prev->next = iter->prev->next;
|
||||||
iter->prev->prev->next=iter->prev->next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(iter->prev->next){
|
if(iter->prev->next) {
|
||||||
iter->prev->next->prev=iter->prev->prev;
|
iter->prev->next->prev = iter->prev->prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
iter->prev->destroy(iter->prev->data);
|
iter->prev->destroy(iter->prev->data);
|
||||||
free(iter->prev->data);
|
free(iter->prev->data);
|
||||||
free(iter->prev);
|
free(iter->prev);
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*This is a hack from AMS. Supposedly, it's pretty good for strings, even
|
/*This is a hack from AMS. Supposedly, it's pretty good for strings, even
|
||||||
though it doesn't take into account all the data*/
|
though it doesn't take into account all the data*/
|
||||||
UINT4
|
UINT4
|
||||||
hash_compute (char *key, int len, int bits)
|
hash_compute(char *key, int len, int bits) {
|
||||||
{
|
UINT4 h = 0;
|
||||||
UINT4 h=0;
|
|
||||||
|
|
||||||
h=key[0] +(key[len-1] * len);
|
h = key[0] + (key[len - 1] * len);
|
||||||
|
|
||||||
h &= (1<<bits) - 1;
|
h &= (1 << bits) - 1;
|
||||||
|
|
||||||
return(h);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
return (h);
|
||||||
|
}
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: r_assoc_test.c,v 1.2 2000/10/17 16:10:00 ekr Exp $
|
$Id: r_assoc_test.c,v 1.2 2000/10/17 16:10:00 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,45 +44,40 @@
|
||||||
ekr@rtfm.com Sun Jan 17 21:09:22 1999
|
ekr@rtfm.com Sun Jan 17 21:09:22 1999
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <r_common.h>
|
#include <r_common.h>
|
||||||
#include <r_assoc.h>
|
#include <r_assoc.h>
|
||||||
|
|
||||||
int
|
int main(void) {
|
||||||
main (void)
|
char test_vector[1024], *v;
|
||||||
{
|
int rnd, ct, r;
|
||||||
char test_vector[1024],*v;
|
r_assoc *assoc, *new_assoc;
|
||||||
int rnd,ct,r;
|
|
||||||
r_assoc *assoc,*new_assoc;
|
|
||||||
|
|
||||||
if(r=r_assoc_create(&assoc)){
|
if(r = r_assoc_create(&assoc)) {
|
||||||
fprintf(stderr,"Couldn't create\n");
|
fprintf(stderr, "Couldn't create\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
srand(getpid());
|
srand(getpid());
|
||||||
|
|
||||||
v=test_vector;
|
v = test_vector;
|
||||||
for(ct=0;ct<256;ct++){
|
for(ct = 0; ct < 256; ct++) {
|
||||||
v[0]=ct & 255;
|
v[0] = ct & 255;
|
||||||
v[1]=(ct>>8) & 255;
|
v[1] = (ct >> 8) & 255;
|
||||||
v[2]=(ct>>16) & 255;
|
v[2] = (ct >> 16) & 255;
|
||||||
v[3]=(ct>>24) & 255;
|
v[3] = (ct >> 24) & 255;
|
||||||
|
|
||||||
|
if(r = r_assoc_insert(assoc, v, 4, v, 0, 0, R_ASSOC_REPLACE)) {
|
||||||
if(r=r_assoc_insert(assoc,v,4,v,0,0,R_ASSOC_REPLACE)){
|
fprintf(stderr, "Couldn't insert %d\n", ct);
|
||||||
fprintf(stderr,"Couldn't insert %d\n",ct);
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
v+=4;
|
v += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
fetch_test(assoc);
|
fetch_test(assoc);
|
||||||
|
|
||||||
if(r=r_assoc_copy(&new_assoc,assoc)){
|
if(r = r_assoc_copy(&new_assoc, assoc)) {
|
||||||
fprintf(stderr,"Couldn't copy\n");
|
fprintf(stderr, "Couldn't copy\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,45 +89,40 @@ main (void)
|
||||||
|
|
||||||
printf("Tests pass\n");
|
printf("Tests pass\n");
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int fetch_test(r_assoc *assoc) {
|
||||||
fetch_test (r_assoc *assoc)
|
|
||||||
{
|
|
||||||
int ct;
|
int ct;
|
||||||
char vec[4],*v;
|
char vec[4], *v;
|
||||||
int r,_status,rnd;
|
int r, _status, rnd;
|
||||||
|
|
||||||
for(ct=0;ct<65537;ct++){
|
for(ct = 0; ct < 65537; ct++) {
|
||||||
rnd=rand();
|
rnd = rand();
|
||||||
|
|
||||||
rnd &= 0x3ff;
|
rnd &= 0x3ff;
|
||||||
|
|
||||||
vec[0]=rnd & 255;
|
vec[0] = rnd & 255;
|
||||||
vec[1]=(rnd>>8) & 255;
|
vec[1] = (rnd >> 8) & 255;
|
||||||
vec[2]=(rnd>>16) & 255;
|
vec[2] = (rnd >> 16) & 255;
|
||||||
vec[3]=(rnd>>24) & 255;
|
vec[3] = (rnd >> 24) & 255;
|
||||||
|
|
||||||
if(r=r_assoc_fetch(assoc,vec,4,(void **)&v)){
|
if(r = r_assoc_fetch(assoc, vec, 4, (void **)&v)) {
|
||||||
|
if(rnd < 256) {
|
||||||
if(rnd<256){
|
fprintf(stderr, "Couldn't fetch\n");
|
||||||
fprintf(stderr,"Couldn't fetch\n");
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
continue;
|
continue;
|
||||||
}
|
} else {
|
||||||
else{
|
if(rnd > 255) {
|
||||||
if(rnd>255){
|
fprintf(stderr, "Spurious fetch\n");
|
||||||
fprintf(stderr,"Spurious fetch\n");
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(memcmp(vec,v,4)){
|
if(memcmp(vec, v, 4)) {
|
||||||
fprintf(stderr,"Fetch error\n");
|
fprintf(stderr, "Fetch error\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,100 +7,90 @@
|
||||||
ekr@rtfm.com Wed Oct 3 11:15:23 2001
|
ekr@rtfm.com Wed Oct 3 11:15:23 2001
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <r_common.h>
|
#include <r_common.h>
|
||||||
#include "r_bitfield.h"
|
#include "r_bitfield.h"
|
||||||
|
|
||||||
int
|
int r_bitfield_create(r_bitfield **setp, UINT4 size) {
|
||||||
r_bitfield_create (r_bitfield **setp, UINT4 size)
|
r_bitfield *set = 0;
|
||||||
{
|
|
||||||
r_bitfield *set=0;
|
|
||||||
int _status;
|
int _status;
|
||||||
int num_words=size/32+!!(size%32);
|
int num_words = size / 32 + !!(size % 32);
|
||||||
|
|
||||||
if(!(set=(r_bitfield *)RMALLOC(sizeof(r_bitfield))))
|
if(!(set = (r_bitfield *)RMALLOC(sizeof(r_bitfield))))
|
||||||
ABORT(R_NO_MEMORY);
|
ABORT(R_NO_MEMORY);
|
||||||
|
|
||||||
if(!(set->data=(UINT4 *)RMALLOC(num_words*4)))
|
if(!(set->data = (UINT4 *)RMALLOC(num_words * 4)))
|
||||||
ABORT(R_NO_MEMORY);
|
ABORT(R_NO_MEMORY);
|
||||||
memset(set->data,0,4*num_words);
|
memset(set->data, 0, 4 * num_words);
|
||||||
|
|
||||||
set->base=0;
|
set->base = 0;
|
||||||
set->len=num_words;
|
set->len = num_words;
|
||||||
|
|
||||||
*setp=set;
|
*setp = set;
|
||||||
|
|
||||||
_status=0;
|
_status = 0;
|
||||||
abort:
|
abort:
|
||||||
if(_status){
|
if(_status) {
|
||||||
r_bitfield_destroy(&set);
|
r_bitfield_destroy(&set);
|
||||||
}
|
}
|
||||||
return(_status);
|
return (_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int r_bitfield_destroy(r_bitfield **setp) {
|
||||||
r_bitfield_destroy (r_bitfield **setp)
|
|
||||||
{
|
|
||||||
r_bitfield *set;
|
r_bitfield *set;
|
||||||
|
|
||||||
if(!setp || !*setp)
|
if(!setp || !*setp)
|
||||||
return(0);
|
return (0);
|
||||||
|
|
||||||
set=*setp;
|
set = *setp;
|
||||||
|
|
||||||
RFREE(set->data);
|
RFREE(set->data);
|
||||||
RFREE(set);
|
RFREE(set);
|
||||||
|
|
||||||
*setp=0;
|
*setp = 0;
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int r_bitfield_set(r_bitfield *set, int bit) {
|
||||||
r_bitfield_set (r_bitfield *set, int bit)
|
int word = (bit - set->base) / 32;
|
||||||
{
|
int bbit = (bit - set->base) % 32;
|
||||||
int word=(bit-set->base)/32;
|
|
||||||
int bbit=(bit-set->base)%32;
|
|
||||||
int _status;
|
int _status;
|
||||||
|
|
||||||
/* Resize? */
|
/* Resize? */
|
||||||
if(word>set->len){
|
if(word > set->len) {
|
||||||
UINT4 newlen=set->len;
|
UINT4 newlen = set->len;
|
||||||
UINT4 *tmp;
|
UINT4 *tmp;
|
||||||
|
|
||||||
while(newlen<word)
|
while(newlen < word)
|
||||||
newlen*=2;
|
newlen *= 2;
|
||||||
|
|
||||||
if(!(tmp=(UINT4 *)RMALLOC(newlen)))
|
if(!(tmp = (UINT4 *)RMALLOC(newlen)))
|
||||||
ABORT(R_NO_MEMORY);
|
ABORT(R_NO_MEMORY);
|
||||||
|
|
||||||
memcpy(tmp,set->data,set->len*4);
|
memcpy(tmp, set->data, set->len * 4);
|
||||||
memset(tmp+set->len*4,0,(newlen-set->len)*4);
|
memset(tmp + set->len * 4, 0, (newlen - set->len) * 4);
|
||||||
|
|
||||||
RFREE(set->data);
|
RFREE(set->data);
|
||||||
set->data=tmp;
|
set->data = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
set->data[word]|=1<<bbit;
|
set->data[word] |= 1 << bbit;
|
||||||
|
|
||||||
_status=0;
|
_status = 0;
|
||||||
abort:
|
abort:
|
||||||
return(_status);
|
return (_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int r_bitfield_isset(r_bitfield *set, int bit) {
|
||||||
r_bitfield_isset (r_bitfield *set, int bit)
|
int word = (bit - set->base) / 32;
|
||||||
{
|
int bbit = (bit - set->base) % 32;
|
||||||
int word=(bit-set->base)/32;
|
|
||||||
int bbit=(bit-set->base)%32;
|
|
||||||
int _status;
|
int _status;
|
||||||
|
|
||||||
if(bit<set->base)
|
if(bit < set->base)
|
||||||
return(0);
|
return (0);
|
||||||
|
|
||||||
/* Resize? */
|
/* Resize? */
|
||||||
if(word>set->len)
|
if(word > set->len)
|
||||||
return(0);
|
return (0);
|
||||||
|
|
||||||
return(set->data[word]&(1<<bbit));
|
return (set->data[word] & (1 << bbit));
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: r_data.c,v 1.3 2001/07/20 23:33:15 ekr Exp $
|
$Id: r_data.c,v 1.3 2001/07/20 23:33:15 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,112 +44,95 @@
|
||||||
ekr@rtfm.com Tue Aug 17 15:39:50 1999
|
ekr@rtfm.com Tue Aug 17 15:39:50 1999
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <r_common.h>
|
#include <r_common.h>
|
||||||
#include <r_data.h>
|
#include <r_data.h>
|
||||||
|
|
||||||
int
|
int r_data_create(Data **dp, UCHAR *d, int l) {
|
||||||
r_data_create (Data **dp, UCHAR *d, int l)
|
Data *d_ = 0;
|
||||||
{
|
|
||||||
Data *d_=0;
|
|
||||||
int _status;
|
int _status;
|
||||||
|
|
||||||
if(!(d_=(Data *)calloc(sizeof(Data),1)))
|
if(!(d_ = (Data *)calloc(sizeof(Data), 1)))
|
||||||
ABORT(R_NO_MEMORY);
|
ABORT(R_NO_MEMORY);
|
||||||
if(!(d_->data=(UCHAR *)malloc(l)))
|
if(!(d_->data = (UCHAR *)malloc(l)))
|
||||||
ABORT(R_NO_MEMORY);
|
ABORT(R_NO_MEMORY);
|
||||||
|
|
||||||
memcpy(d_->data,d,l);
|
memcpy(d_->data, d, l);
|
||||||
d_->len=l;
|
d_->len = l;
|
||||||
|
|
||||||
*dp=d_;
|
*dp = d_;
|
||||||
|
|
||||||
_status=0;
|
_status = 0;
|
||||||
abort:
|
abort:
|
||||||
if(_status)
|
if(_status)
|
||||||
r_data_destroy(&d_);
|
r_data_destroy(&d_);
|
||||||
|
|
||||||
return(_status);
|
return (_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int r_data_alloc(Data **dp, int l) {
|
||||||
r_data_alloc (Data **dp, int l)
|
Data *d_ = 0;
|
||||||
{
|
|
||||||
Data *d_=0;
|
|
||||||
int _status;
|
int _status;
|
||||||
|
|
||||||
if(!(d_=(Data *)calloc(sizeof(Data),1)))
|
if(!(d_ = (Data *)calloc(sizeof(Data), 1)))
|
||||||
ABORT(R_NO_MEMORY);
|
ABORT(R_NO_MEMORY);
|
||||||
if(!(d_->data=(UCHAR *)calloc(l,1)))
|
if(!(d_->data = (UCHAR *)calloc(l, 1)))
|
||||||
ABORT(R_NO_MEMORY);
|
ABORT(R_NO_MEMORY);
|
||||||
|
|
||||||
d_->len=l;
|
d_->len = l;
|
||||||
|
|
||||||
*dp=d_;
|
*dp = d_;
|
||||||
_status=0;
|
_status = 0;
|
||||||
abort:
|
abort:
|
||||||
if(_status)
|
if(_status)
|
||||||
r_data_destroy(&d_);
|
r_data_destroy(&d_);
|
||||||
|
|
||||||
return(_status);
|
return (_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int r_data_make(Data *dp, UCHAR *d, int l) {
|
||||||
r_data_make (Data *dp, UCHAR *d, int l)
|
if(!(dp->data = (UCHAR *)malloc(l)))
|
||||||
{
|
|
||||||
if(!(dp->data=(UCHAR *)malloc(l)))
|
|
||||||
ERETURN(R_NO_MEMORY);
|
ERETURN(R_NO_MEMORY);
|
||||||
|
|
||||||
memcpy(dp->data,d,l);
|
memcpy(dp->data, d, l);
|
||||||
dp->len=l;
|
dp->len = l;
|
||||||
|
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int r_data_destroy(Data **dp) {
|
||||||
r_data_destroy (Data **dp)
|
|
||||||
{
|
|
||||||
if(!dp || !*dp)
|
if(!dp || !*dp)
|
||||||
return(0);
|
return (0);
|
||||||
|
|
||||||
if((*dp)->data)
|
if((*dp)->data)
|
||||||
free((*dp)->data);
|
free((*dp)->data);
|
||||||
|
|
||||||
free(*dp);
|
free(*dp);
|
||||||
*dp=0;
|
*dp = 0;
|
||||||
|
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int r_data_copy(Data *dst, Data *src) {
|
||||||
r_data_copy (Data *dst, Data *src)
|
if(!(dst->data = (UCHAR *)malloc(src->len)))
|
||||||
{
|
|
||||||
if(!(dst->data=(UCHAR *)malloc(src->len)))
|
|
||||||
ERETURN(R_NO_MEMORY);
|
ERETURN(R_NO_MEMORY);
|
||||||
memcpy(dst->data,src->data,dst->len=src->len);
|
memcpy(dst->data, src->data, dst->len = src->len);
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int r_data_zfree(Data *d) {
|
||||||
r_data_zfree (Data *d)
|
|
||||||
{
|
|
||||||
if(!d)
|
if(!d)
|
||||||
return(0);
|
return (0);
|
||||||
if(!d->data)
|
if(!d->data)
|
||||||
return(0);
|
return (0);
|
||||||
memset(d->data,0,d->len);
|
memset(d->data, 0, d->len);
|
||||||
free(d->data);
|
free(d->data);
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
r_data_compare (Data *d1, Data *d2)
|
|
||||||
{
|
|
||||||
if(d1->len<d2->len)
|
|
||||||
return(-1);
|
|
||||||
if(d2->len<d1->len)
|
|
||||||
return(-1);
|
|
||||||
return(memcmp(d1->data,d2->data,d1->len));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
int r_data_compare(Data *d1, Data *d2) {
|
||||||
|
if(d1->len < d2->len)
|
||||||
|
return (-1);
|
||||||
|
if(d2->len < d1->len)
|
||||||
|
return (-1);
|
||||||
|
return (memcmp(d1->data, d2->data, d1->len));
|
||||||
|
}
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: r_data.h,v 1.2 2000/10/17 16:10:00 ekr Exp $
|
$Id: r_data.h,v 1.2 2000/10/17 16:10:00 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,10 +44,7 @@
|
||||||
ekr@rtfm.com Fri Feb 4 08:58:48 2000
|
ekr@rtfm.com Fri Feb 4 08:58:48 2000
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _r_data_h
|
#ifndef _r_data_h
|
||||||
#define _r_data_h
|
#define _r_data_h
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: r_errors.c,v 1.3 2001/12/24 06:06:27 ekr Exp $
|
$Id: r_errors.c,v 1.3 2001/12/24 06:06:27 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,18 +44,15 @@
|
||||||
ekr@rtfm.com Tue Feb 16 16:37:05 1999
|
ekr@rtfm.com Tue Feb 16 16:37:05 1999
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include "r_common.h"
|
#include "r_common.h"
|
||||||
#include "r_errors.h"
|
#include "r_errors.h"
|
||||||
|
|
||||||
int verr_exit(char *fmt,...)
|
int verr_exit(char *fmt, ...) {
|
||||||
{
|
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap,fmt);
|
va_start(ap, fmt);
|
||||||
vfprintf(stderr,fmt,ap);
|
vfprintf(stderr, fmt, ap);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: r_list.c,v 1.4 2001/12/24 06:06:27 ekr Exp $
|
$Id: r_list.c,v 1.4 2001/12/24 06:06:27 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,8 +44,6 @@
|
||||||
ekr@rtfm.com Tue Jan 19 08:36:39 1999
|
ekr@rtfm.com Tue Jan 19 08:36:39 1999
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <r_common.h>
|
#include <r_common.h>
|
||||||
#include "r_list.h"
|
#include "r_list.h"
|
||||||
|
|
||||||
|
@ -52,8 +51,8 @@ typedef struct r_list_el_ {
|
||||||
void *data;
|
void *data;
|
||||||
struct r_list_el_ *next;
|
struct r_list_el_ *next;
|
||||||
struct r_list_el_ *prev;
|
struct r_list_el_ *prev;
|
||||||
int (*copy) PROTO_LIST((void **new,void *old));
|
int(*copy) PROTO_LIST((void **new, void *old));
|
||||||
int (*destroy) PROTO_LIST((void **ptr));
|
int(*destroy) PROTO_LIST((void **ptr));
|
||||||
} r_list_el;
|
} r_list_el;
|
||||||
|
|
||||||
struct r_list_ {
|
struct r_list_ {
|
||||||
|
@ -61,170 +60,155 @@ struct r_list_ {
|
||||||
struct r_list_el_ *last;
|
struct r_list_el_ *last;
|
||||||
};
|
};
|
||||||
|
|
||||||
int
|
int r_list_create(r_list **listp) {
|
||||||
r_list_create (r_list **listp)
|
r_list *list = 0;
|
||||||
{
|
|
||||||
r_list *list=0;
|
|
||||||
int _status;
|
int _status;
|
||||||
|
|
||||||
if(!(list=(r_list *)calloc(sizeof(r_list),1)))
|
if(!(list = (r_list *)calloc(sizeof(r_list), 1)))
|
||||||
ABORT(R_NO_MEMORY);
|
ABORT(R_NO_MEMORY);
|
||||||
|
|
||||||
list->first=0;
|
list->first = 0;
|
||||||
list->last=0;
|
list->last = 0;
|
||||||
*listp=list;
|
*listp = list;
|
||||||
|
|
||||||
_status=0;
|
_status = 0;
|
||||||
abort:
|
abort:
|
||||||
return(_status);
|
return (_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int r_list_destroy(r_list **listp) {
|
||||||
r_list_destroy (r_list **listp)
|
|
||||||
{
|
|
||||||
r_list *list;
|
r_list *list;
|
||||||
r_list_el *el;
|
r_list_el *el;
|
||||||
|
|
||||||
if(!listp || !*listp)
|
if(!listp || !*listp)
|
||||||
return(0);
|
return (0);
|
||||||
list=*listp;
|
list = *listp;
|
||||||
|
|
||||||
el=list->first;
|
el = list->first;
|
||||||
|
|
||||||
while(el){
|
while(el) {
|
||||||
r_list_el *el_t;
|
r_list_el *el_t;
|
||||||
|
|
||||||
if(el->destroy && el->data)
|
if(el->destroy && el->data)
|
||||||
el->destroy(&el->data);
|
el->destroy(&el->data);
|
||||||
el_t=el;
|
el_t = el;
|
||||||
el=el->next;
|
el = el->next;
|
||||||
free(el_t);
|
free(el_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(list);
|
free(list);
|
||||||
*listp=0;
|
*listp = 0;
|
||||||
|
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int r_list_copy(r_list **outp, r_list *in) {
|
||||||
r_list_copy (r_list **outp, r_list *in)
|
r_list *out = 0;
|
||||||
{
|
r_list_el *el, *el2, *last = 0;
|
||||||
r_list *out=0;
|
|
||||||
r_list_el *el,*el2,*last=0;
|
|
||||||
int r, _status;
|
int r, _status;
|
||||||
|
|
||||||
if(r=r_list_create(&out))
|
if(r = r_list_create(&out))
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
|
|
||||||
for(el=in->first;in;el=el->next){
|
for(el = in->first; in; el = el->next) {
|
||||||
if(!(el2=(r_list_el *)calloc(sizeof(r_list_el),1)))
|
if(!(el2 = (r_list_el *)calloc(sizeof(r_list_el), 1)))
|
||||||
ABORT(R_NO_MEMORY);
|
ABORT(R_NO_MEMORY);
|
||||||
|
|
||||||
if(el->copy && el->data){
|
if(el->copy && el->data) {
|
||||||
if(r=el->copy(&el2->data,el->data))
|
if(r = el->copy(&el2->data, el->data))
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
el2->copy=el->copy;
|
el2->copy = el->copy;
|
||||||
el2->destroy=el->destroy;
|
el2->destroy = el->destroy;
|
||||||
|
|
||||||
if(!(out->first))
|
if(!(out->first))
|
||||||
out->first=el2;
|
out->first = el2;
|
||||||
|
|
||||||
el2->prev=last;
|
el2->prev = last;
|
||||||
last->next=el2;
|
last->next = el2;
|
||||||
last=el2;
|
last = el2;
|
||||||
}
|
}
|
||||||
|
|
||||||
out->last=last;
|
out->last = last;
|
||||||
|
|
||||||
*outp=out;
|
*outp = out;
|
||||||
|
|
||||||
_status=0;
|
_status = 0;
|
||||||
abort:
|
abort:
|
||||||
if(_status)
|
if(_status)
|
||||||
r_list_destroy(&out);
|
r_list_destroy(&out);
|
||||||
return(_status);
|
return (_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
int r_list_insert(list,value,copy,destroy)
|
int r_list_insert(list, value, copy, destroy) r_list *list;
|
||||||
r_list *list;
|
void *value;
|
||||||
void *value;
|
int(*copy) PROTO_LIST((void **out, void *in));
|
||||||
int (*copy) PROTO_LIST((void **out, void *in));
|
int(*destroy) PROTO_LIST((void **val));
|
||||||
int (*destroy) PROTO_LIST((void **val));
|
{
|
||||||
{
|
r_list_el *el = 0;
|
||||||
r_list_el *el=0;
|
|
||||||
int _status;
|
int _status;
|
||||||
|
|
||||||
if(!(el=(r_list_el *)calloc(sizeof(r_list_el),1)))
|
if(!(el = (r_list_el *)calloc(sizeof(r_list_el), 1)))
|
||||||
ABORT(R_NO_MEMORY);
|
ABORT(R_NO_MEMORY);
|
||||||
el->data=value;
|
el->data = value;
|
||||||
el->copy=copy;
|
el->copy = copy;
|
||||||
el->destroy=destroy;
|
el->destroy = destroy;
|
||||||
|
|
||||||
el->prev=0;
|
el->prev = 0;
|
||||||
el->next=list->first;
|
el->next = list->first;
|
||||||
if(list->first){
|
if(list->first) {
|
||||||
list->first->prev=el;
|
list->first->prev = el;
|
||||||
}
|
}
|
||||||
list->first=el;
|
list->first = el;
|
||||||
|
|
||||||
_status=0;
|
_status = 0;
|
||||||
abort:
|
abort:
|
||||||
return(_status);
|
return (_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
int r_list_append(list,value,copy,destroy)
|
int r_list_append(list, value, copy, destroy) r_list *list;
|
||||||
r_list *list;
|
void *value;
|
||||||
void *value;
|
int(*copy) PROTO_LIST((void **out, void *in));
|
||||||
int (*copy) PROTO_LIST((void **out, void *in));
|
int(*destroy) PROTO_LIST((void **val));
|
||||||
int (*destroy) PROTO_LIST((void **val));
|
{
|
||||||
{
|
r_list_el *el = 0;
|
||||||
r_list_el *el=0;
|
|
||||||
int _status;
|
int _status;
|
||||||
|
|
||||||
if(!(el=(r_list_el *)calloc(sizeof(r_list_el),1)))
|
if(!(el = (r_list_el *)calloc(sizeof(r_list_el), 1)))
|
||||||
ABORT(R_NO_MEMORY);
|
ABORT(R_NO_MEMORY);
|
||||||
el->data=value;
|
el->data = value;
|
||||||
el->copy=copy;
|
el->copy = copy;
|
||||||
el->destroy=destroy;
|
el->destroy = destroy;
|
||||||
|
|
||||||
el->prev=list->last;
|
el->prev = list->last;
|
||||||
el->next=0;
|
el->next = 0;
|
||||||
|
|
||||||
if(list->last) list->last->next=el;
|
if(list->last)
|
||||||
else list->first=el;
|
list->last->next = el;
|
||||||
|
else
|
||||||
|
list->first = el;
|
||||||
|
|
||||||
list->last=el;
|
list->last = el;
|
||||||
|
|
||||||
_status=0;
|
_status = 0;
|
||||||
abort:
|
abort:
|
||||||
return(_status);
|
return (_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int r_list_init_iter(r_list *list, r_list_iterator *iter) {
|
||||||
r_list_init_iter (r_list *list, r_list_iterator *iter)
|
iter->list = list;
|
||||||
{
|
iter->ptr = list->first;
|
||||||
iter->list=list;
|
|
||||||
iter->ptr=list->first;
|
|
||||||
|
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int r_list_iter(r_list_iterator *iter, void **val) {
|
||||||
r_list_iter (r_list_iterator *iter, void **val)
|
|
||||||
{
|
|
||||||
if(!iter->ptr)
|
if(!iter->ptr)
|
||||||
return(R_EOD);
|
return (R_EOD);
|
||||||
|
|
||||||
*val=iter->ptr->data;
|
|
||||||
iter->ptr=iter->ptr->next;
|
|
||||||
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*val = iter->ptr->data;
|
||||||
|
iter->ptr = iter->ptr->next;
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: r_replace.c,v 1.2 2000/10/17 16:10:00 ekr Exp $
|
$Id: r_replace.c,v 1.2 2000/10/17 16:10:00 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,24 +44,19 @@
|
||||||
ekr@rtfm.com Sun Oct 1 11:18:49 2000
|
ekr@rtfm.com Sun Oct 1 11:18:49 2000
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "r_common.h"
|
#include "r_common.h"
|
||||||
|
|
||||||
#ifndef HAVE_STRDUP
|
#ifndef HAVE_STRDUP
|
||||||
|
|
||||||
char *
|
char *strdup(char *str) {
|
||||||
strdup (char *str)
|
int len = strlen(str);
|
||||||
{
|
|
||||||
int len=strlen(str);
|
|
||||||
char *n;
|
char *n;
|
||||||
|
|
||||||
if(!(n=(char *)malloc(len+1)))
|
if(!(n = (char *)malloc(len + 1)))
|
||||||
return(0);
|
return (0);
|
||||||
|
|
||||||
memcpy(n,str,len+1);
|
memcpy(n, str, len + 1);
|
||||||
|
|
||||||
return(n);
|
return (n);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: r_time.c,v 1.6 2002/09/09 21:02:58 ekr Exp $
|
$Id: r_time.c,v 1.6 2002/09/09 21:02:58 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,8 +44,6 @@
|
||||||
ekr@rtfm.com Thu Mar 4 08:43:46 1999
|
ekr@rtfm.com Thu Mar 4 08:43:46 1999
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <r_common.h>
|
#include <r_common.h>
|
||||||
#include <r_time.h>
|
#include <r_time.h>
|
||||||
|
|
||||||
|
@ -52,8 +51,7 @@
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
int gettimeofday(struct timeval *tv, struct timezone *tzp)
|
int gettimeofday(struct timeval *tv, struct timezone *tzp) {
|
||||||
{
|
|
||||||
/* JAN1_1970_OFFSET is the number of 100-nanoseconds ticks
|
/* JAN1_1970_OFFSET is the number of 100-nanoseconds ticks
|
||||||
between midnight jan 1, 1970 and jan 1, 1601.
|
between midnight jan 1, 1970 and jan 1, 1601.
|
||||||
*/
|
*/
|
||||||
|
@ -62,7 +60,7 @@ int gettimeofday(struct timeval *tv, struct timezone *tzp)
|
||||||
ULARGE_INTEGER currentTimeSinceJan_1_1970;
|
ULARGE_INTEGER currentTimeSinceJan_1_1970;
|
||||||
FILETIME currentTime;
|
FILETIME currentTime;
|
||||||
|
|
||||||
GetSystemTimeAsFileTime( ¤tTime );
|
GetSystemTimeAsFileTime(¤tTime);
|
||||||
currentTimeSinceJan_1_1970.LowPart = currentTime.dwLowDateTime;
|
currentTimeSinceJan_1_1970.LowPart = currentTime.dwLowDateTime;
|
||||||
currentTimeSinceJan_1_1970.HighPart = currentTime.dwHighDateTime;
|
currentTimeSinceJan_1_1970.HighPart = currentTime.dwHighDateTime;
|
||||||
currentTimeSinceJan_1_1970.QuadPart -= JAN1_1970_OFFSET.QuadPart;
|
currentTimeSinceJan_1_1970.QuadPart -= JAN1_1970_OFFSET.QuadPart;
|
||||||
|
@ -84,71 +82,66 @@ int gettimeofday(struct timeval *tv, struct timezone *tzp)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/*Note that t1 must be > t0 */
|
/*Note that t1 must be > t0 */
|
||||||
int
|
int r_timeval_diff(struct timeval *t1,
|
||||||
r_timeval_diff (struct timeval *t1, struct timeval *t0, struct timeval *diff)
|
struct timeval *t0,
|
||||||
{
|
struct timeval *diff) {
|
||||||
long d;
|
long d;
|
||||||
|
|
||||||
if(t0->tv_sec > t1->tv_sec)
|
if(t0->tv_sec > t1->tv_sec)
|
||||||
ERETURN(R_BAD_ARGS);
|
ERETURN(R_BAD_ARGS);
|
||||||
|
|
||||||
/*Easy case*/
|
/*Easy case*/
|
||||||
if(t0->tv_usec <= t1->tv_usec){
|
if(t0->tv_usec <= t1->tv_usec) {
|
||||||
diff->tv_sec=t1->tv_sec - t0->tv_sec;
|
diff->tv_sec = t1->tv_sec - t0->tv_sec;
|
||||||
diff->tv_usec=t1->tv_usec - t0->tv_usec;
|
diff->tv_usec = t1->tv_usec - t0->tv_usec;
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Hard case*/
|
/*Hard case*/
|
||||||
d=t0->tv_usec - t1->tv_usec;
|
d = t0->tv_usec - t1->tv_usec;
|
||||||
if(t1->tv_sec < (t0->tv_sec + 1))
|
if(t1->tv_sec < (t0->tv_sec + 1))
|
||||||
ERETURN(R_BAD_ARGS);
|
ERETURN(R_BAD_ARGS);
|
||||||
diff->tv_sec=t1->tv_sec - (t0->tv_sec + 1);
|
diff->tv_sec = t1->tv_sec - (t0->tv_sec + 1);
|
||||||
diff->tv_usec=1000000 - d;
|
diff->tv_usec = 1000000 - d;
|
||||||
|
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int r_timeval_add(struct timeval *t1, struct timeval *t2, struct timeval *sum) {
|
||||||
r_timeval_add (struct timeval *t1, struct timeval *t2, struct timeval *sum)
|
long tv_sec, tv_usec, d;
|
||||||
{
|
|
||||||
long tv_sec,tv_usec,d;
|
|
||||||
|
|
||||||
tv_sec=t1->tv_sec + t2->tv_sec;
|
tv_sec = t1->tv_sec + t2->tv_sec;
|
||||||
|
|
||||||
d=t1->tv_usec + t2->tv_usec;
|
d = t1->tv_usec + t2->tv_usec;
|
||||||
if(d>1000000){
|
if(d > 1000000) {
|
||||||
tv_sec++;
|
tv_sec++;
|
||||||
tv_usec=d-1000000;
|
tv_usec = d - 1000000;
|
||||||
}
|
} else {
|
||||||
else{
|
tv_usec = d;
|
||||||
tv_usec=d;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sum->tv_sec=tv_sec;
|
sum->tv_sec = tv_sec;
|
||||||
sum->tv_usec=tv_usec;
|
sum->tv_usec = tv_usec;
|
||||||
|
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT8
|
UINT8
|
||||||
r_timeval2int (struct timeval *tv)
|
r_timeval2int(struct timeval *tv) {
|
||||||
{
|
UINT8 r = 0;
|
||||||
UINT8 r=0;
|
|
||||||
|
|
||||||
r=(tv->tv_sec);
|
r = (tv->tv_sec);
|
||||||
r*=1000000;
|
r *= 1000000;
|
||||||
r+=tv->tv_usec;
|
r += tv->tv_usec;
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT8
|
UINT8
|
||||||
r_gettimeint (void)
|
r_gettimeint(void) {
|
||||||
{
|
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
|
||||||
gettimeofday(&tv,0);
|
gettimeofday(&tv, 0);
|
||||||
|
|
||||||
return r_timeval2int(&tv);
|
return r_timeval2int(&tv);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,28 +7,23 @@
|
||||||
ekr@rtfm.com Tue Feb 23 15:08:03 1999
|
ekr@rtfm.com Tue Feb 23 15:08:03 1999
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <r_common.h>
|
#include <r_common.h>
|
||||||
#include <r_thread.h>
|
#include <r_thread.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
static int thread_count=0;
|
static int thread_count = 0;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void (*func) PROTO_LIST((void *));
|
void(*func) PROTO_LIST((void *));
|
||||||
void *arg;
|
void *arg;
|
||||||
} helper;
|
} helper;
|
||||||
|
|
||||||
|
|
||||||
static void *r_thread_real_create PROTO_LIST((void *arg));
|
static void *r_thread_real_create PROTO_LIST((void *arg));
|
||||||
|
|
||||||
static void *
|
static void *r_thread_real_create(void *arg) {
|
||||||
r_thread_real_create (void *arg)
|
|
||||||
{
|
|
||||||
helper *h;
|
helper *h;
|
||||||
|
|
||||||
h=(helper *)arg;
|
h = (helper *)arg;
|
||||||
|
|
||||||
thread_count++;
|
thread_count++;
|
||||||
|
|
||||||
|
@ -36,117 +31,101 @@ r_thread_real_create (void *arg)
|
||||||
|
|
||||||
thread_count--;
|
thread_count--;
|
||||||
free(h);
|
free(h);
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int r_thread_fork(func,arg,id)
|
int r_thread_fork(func, arg, id) void(*func) PROTO_LIST((void *));
|
||||||
void (*func) PROTO_LIST((void *));
|
void *arg;
|
||||||
void *arg;
|
r_thread *id;
|
||||||
r_thread *id;
|
{
|
||||||
{
|
|
||||||
pthread_t thread;
|
pthread_t thread;
|
||||||
helper *h;
|
helper *h;
|
||||||
int r,_status;
|
int r, _status;
|
||||||
|
|
||||||
h=(helper *)malloc(sizeof(helper));
|
h = (helper *)malloc(sizeof(helper));
|
||||||
|
|
||||||
h->func=func;
|
h->func = func;
|
||||||
h->arg=arg;
|
h->arg = arg;
|
||||||
|
|
||||||
if(r=pthread_create(&thread,0,r_thread_real_create,(void *)h))
|
if(r = pthread_create(&thread, 0, r_thread_real_create, (void *)h))
|
||||||
ABORT(R_INTERNAL);
|
ABORT(R_INTERNAL);
|
||||||
|
|
||||||
_status=0;
|
_status = 0;
|
||||||
abort:
|
abort:
|
||||||
return(_status);
|
return (_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int r_thread_yield(void) {
|
||||||
r_thread_yield (void)
|
|
||||||
{
|
|
||||||
pthread_yield();
|
pthread_yield();
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int r_thread_exit(void) {
|
||||||
r_thread_exit (void)
|
|
||||||
{
|
|
||||||
thread_count--;
|
thread_count--;
|
||||||
pthread_exit(0);
|
pthread_exit(0);
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int r_thread_wait_last(void) {
|
||||||
r_thread_wait_last (void)
|
|
||||||
{
|
|
||||||
do {
|
do {
|
||||||
pthread_yield();
|
pthread_yield();
|
||||||
usleep(10000);
|
usleep(10000);
|
||||||
DBG((0,"%d threads left",thread_count));
|
DBG((0, "%d threads left", thread_count));
|
||||||
} while (thread_count);
|
} while(thread_count);
|
||||||
|
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int r_rwlock_create(r_rwlock **lockp) {
|
||||||
r_rwlock_create (r_rwlock **lockp)
|
|
||||||
{
|
|
||||||
pthread_rwlock_t *lock;
|
pthread_rwlock_t *lock;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if(!(lock=(pthread_rwlock_t *)malloc(sizeof(pthread_rwlock_t))))
|
if(!(lock = (pthread_rwlock_t *)malloc(sizeof(pthread_rwlock_t))))
|
||||||
ERETURN(R_NO_MEMORY);
|
ERETURN(R_NO_MEMORY);
|
||||||
|
|
||||||
if(r=pthread_rwlock_init(lock,0))
|
if(r = pthread_rwlock_init(lock, 0))
|
||||||
ERETURN(R_INTERNAL);
|
ERETURN(R_INTERNAL);
|
||||||
|
|
||||||
*lockp=(void *)lock;
|
*lockp = (void *)lock;
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int r_rwlock_destroy(r_rwlock **lock) {
|
||||||
r_rwlock_destroy (r_rwlock **lock)
|
|
||||||
{
|
|
||||||
pthread_rwlock_t *plock;
|
pthread_rwlock_t *plock;
|
||||||
|
|
||||||
if(!lock || !*lock)
|
if(!lock || !*lock)
|
||||||
return(0);
|
return (0);
|
||||||
|
|
||||||
plock=(pthread_rwlock_t *)(*lock);
|
plock = (pthread_rwlock_t *)(*lock);
|
||||||
|
|
||||||
pthread_rwlock_destroy(plock);
|
pthread_rwlock_destroy(plock);
|
||||||
|
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int r_rwlock_lock(r_rwlock *lock, int action) {
|
||||||
r_rwlock_lock (r_rwlock *lock, int action)
|
|
||||||
{
|
|
||||||
pthread_rwlock_t *plock;
|
pthread_rwlock_t *plock;
|
||||||
int r,_status;
|
int r, _status;
|
||||||
|
|
||||||
plock=(pthread_rwlock_t *)lock;
|
plock = (pthread_rwlock_t *)lock;
|
||||||
|
|
||||||
switch(action){
|
switch(action) {
|
||||||
case R_RWLOCK_UNLOCK:
|
case R_RWLOCK_UNLOCK:
|
||||||
if(r=pthread_rwlock_unlock(plock))
|
if(r = pthread_rwlock_unlock(plock))
|
||||||
ABORT(R_INTERNAL);
|
ABORT(R_INTERNAL);
|
||||||
break;
|
break;
|
||||||
case R_RWLOCK_RLOCK:
|
case R_RWLOCK_RLOCK:
|
||||||
if(r=pthread_rwlock_rdlock(plock))
|
if(r = pthread_rwlock_rdlock(plock))
|
||||||
ABORT(R_INTERNAL);
|
ABORT(R_INTERNAL);
|
||||||
break;
|
break;
|
||||||
case R_RWLOCK_WLOCK:
|
case R_RWLOCK_WLOCK:
|
||||||
if(r=pthread_rwlock_wrlock(plock))
|
if(r = pthread_rwlock_wrlock(plock))
|
||||||
ABORT(R_INTERNAL);
|
ABORT(R_INTERNAL);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ABORT(R_BAD_ARGS);
|
ABORT(R_BAD_ARGS);
|
||||||
}
|
}
|
||||||
|
|
||||||
_status=0;
|
_status = 0;
|
||||||
abort:
|
abort:
|
||||||
return(_status);
|
return (_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: null_analyze.c,v 1.6 2001/11/26 22:28:16 ekr Exp $
|
$Id: null_analyze.c,v 1.6 2001/11/26 22:28:16 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,8 +44,6 @@
|
||||||
ekr@rtfm.com Thu Jan 7 22:58:27 1999
|
ekr@rtfm.com Thu Jan 7 22:58:27 1999
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "network.h"
|
#include "network.h"
|
||||||
#include "proto_mod.h"
|
#include "proto_mod.h"
|
||||||
|
@ -55,87 +54,87 @@ typedef struct null_analyzer_ {
|
||||||
} null_analyzer;
|
} null_analyzer;
|
||||||
|
|
||||||
static int create_null_analyzer PROTO_LIST((void *handle,
|
static int create_null_analyzer PROTO_LIST((void *handle,
|
||||||
proto_ctx *ctx,tcp_conn *conn,proto_obj **objp,
|
proto_ctx *ctx,
|
||||||
struct sockaddr_storage *i_addr,u_short i_port,
|
tcp_conn *conn,
|
||||||
struct sockaddr_storage *r_addr,u_short r_port, struct timeval *base_time));
|
proto_obj **objp,
|
||||||
|
struct sockaddr_storage *i_addr,
|
||||||
|
u_short i_port,
|
||||||
|
struct sockaddr_storage *r_addr,
|
||||||
|
u_short r_port,
|
||||||
|
struct timeval *base_time));
|
||||||
|
|
||||||
static int create_null_analyzer(void *handle, proto_ctx *ctx, tcp_conn *conn,
|
static int create_null_analyzer(void *handle,
|
||||||
proto_obj **objp, struct sockaddr_storage *i_addr, u_short i_port, struct sockaddr_storage *r_addr,
|
proto_ctx *ctx,
|
||||||
u_short r_port, struct timeval *base_time)
|
tcp_conn *conn,
|
||||||
{
|
proto_obj **objp,
|
||||||
null_analyzer *obj=0;
|
struct sockaddr_storage *i_addr,
|
||||||
|
u_short i_port,
|
||||||
|
struct sockaddr_storage *r_addr,
|
||||||
|
u_short r_port,
|
||||||
|
struct timeval *base_time) {
|
||||||
|
null_analyzer *obj = 0;
|
||||||
static int ctr;
|
static int ctr;
|
||||||
|
|
||||||
if(!(obj=(null_analyzer *)calloc(1,sizeof(null_analyzer))))
|
if(!(obj = (null_analyzer *)calloc(1, sizeof(null_analyzer))))
|
||||||
ERETURN(R_NO_MEMORY);
|
ERETURN(R_NO_MEMORY);
|
||||||
|
|
||||||
obj->num=ctr++;
|
obj->num = ctr++;
|
||||||
|
|
||||||
DBG((0,"Creating analyzer for connection %d\n",obj->num));
|
DBG((0, "Creating analyzer for connection %d\n", obj->num));
|
||||||
|
|
||||||
*objp=(proto_obj *)obj;
|
*objp = (proto_obj *)obj;
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int destroy_null_analyzer(proto_obj **objp) {
|
||||||
destroy_null_analyzer (proto_obj **objp)
|
|
||||||
{
|
|
||||||
null_analyzer *obj;
|
null_analyzer *obj;
|
||||||
|
|
||||||
if(!objp || !*objp)
|
if(!objp || !*objp)
|
||||||
return(0);
|
return (0);
|
||||||
|
|
||||||
obj=(null_analyzer *)*objp;
|
obj = (null_analyzer *)*objp;
|
||||||
DBG((0,"Destroying analyzer for connection %d\n",obj->num));
|
DBG((0, "Destroying analyzer for connection %d\n", obj->num));
|
||||||
|
|
||||||
free(*objp);
|
free(*objp);
|
||||||
*objp=0;
|
*objp = 0;
|
||||||
|
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int data_null_analyzer(proto_obj *_obj, segment *seg, int direction) {
|
||||||
data_null_analyzer (proto_obj *_obj, segment *seg, int direction)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
null_analyzer *obj=(null_analyzer *)_obj;
|
null_analyzer *obj = (null_analyzer *)_obj;
|
||||||
#endif
|
#endif
|
||||||
DBG((0,"Processing data for connection %d dir %d\n",obj->num,
|
DBG((0, "Processing data for connection %d dir %d\n", obj->num, direction));
|
||||||
direction));
|
|
||||||
|
|
||||||
for(;seg;seg=seg->next){
|
for(; seg; seg = seg->next) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for(i=0;i<MIN(seg->len,20);i++){
|
for(i = 0; i < MIN(seg->len, 20); i++) {
|
||||||
if(!isascii(seg->data[i]))
|
if(!isascii(seg->data[i]))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(i<20)
|
if(i < 20)
|
||||||
xdump("NSEGMENT",seg->data,seg->len);
|
xdump("NSEGMENT", seg->data, seg->len);
|
||||||
else{
|
else {
|
||||||
printf("NSEGMENT: ");
|
printf("NSEGMENT: ");
|
||||||
fwrite(seg->data,1,seg->len,stdout);
|
fwrite(seg->data, 1, seg->len, stdout);
|
||||||
}
|
}
|
||||||
printf("====\n");
|
printf("====\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int fin_null_analyzer(proto_obj *_obj, packet *p, int direction) {
|
||||||
fin_null_analyzer (proto_obj *_obj, packet *p, int direction)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
null_analyzer *obj=(null_analyzer *)_obj;
|
null_analyzer *obj = (null_analyzer *)_obj;
|
||||||
#endif
|
#endif
|
||||||
DBG((0,"Received FIN on connection %d\n",obj->num));
|
DBG((0, "Received FIN on connection %d\n", obj->num));
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct proto_mod_vtbl_ null_vtbl = {
|
||||||
|
|
||||||
|
|
||||||
static struct proto_mod_vtbl_ null_vtbl ={
|
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
|
@ -146,7 +145,4 @@ static struct proto_mod_vtbl_ null_vtbl ={
|
||||||
fin_null_analyzer,
|
fin_null_analyzer,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct proto_mod_ null_mod = {
|
struct proto_mod_ null_mod = {0, &null_vtbl};
|
||||||
0,
|
|
||||||
&null_vtbl
|
|
||||||
};
|
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: null_analyze.h,v 1.2 2000/10/17 16:10:01 ekr Exp $
|
$Id: null_analyze.h,v 1.2 2000/10/17 16:10:01 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,11 +44,9 @@
|
||||||
ekr@rtfm.com Fri Jan 8 11:23:10 1999
|
ekr@rtfm.com Fri Jan 8 11:23:10 1999
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _null_analyze_h
|
#ifndef _null_analyze_h
|
||||||
#define _null_analyze_h
|
#define _null_analyze_h
|
||||||
|
|
||||||
extern proto_mod null_mod;
|
extern proto_mod null_mod;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -48,8 +48,8 @@
|
||||||
|
|
||||||
#define UNUSED __attribute__((unused))
|
#define UNUSED __attribute__((unused))
|
||||||
#define NORET __attribute__((noreturn))
|
#define NORET __attribute__((noreturn))
|
||||||
#define PRINTF(f,a) __attribute__((format(printf,(f),(a))))
|
#define PRINTF(f, a) __attribute__((format(printf, (f), (a))))
|
||||||
#define SCANF(f,a) __attribute__((format(scanf,(f),(a))))
|
#define SCANF(f, a) __attribute__((format(scanf, (f), (a))))
|
||||||
#define WUNRES __attribute__((warn_unused_result))
|
#define WUNRES __attribute__((warn_unused_result))
|
||||||
#define MALLOC __attribute__((malloc)) WUNRES
|
#define MALLOC __attribute__((malloc)) WUNRES
|
||||||
#define NONNULL(...) __attribute__((nonnull(__VA_ARGS__)))
|
#define NONNULL(...) __attribute__((nonnull(__VA_ARGS__)))
|
||||||
|
|
462
pcap/logpkt.c
462
pcap/logpkt.c
|
@ -140,7 +140,7 @@ typedef struct __attribute__((packed)) {
|
||||||
* These constants are only used for PCAP writing, not for mirroring.
|
* These constants are only used for PCAP writing, not for mirroring.
|
||||||
*/
|
*/
|
||||||
//#define MTU 1500
|
//#define MTU 1500
|
||||||
#define MTU 65535//we add support for jumboframes and offload
|
#define MTU 65535 // we add support for jumboframes and offload
|
||||||
#define MAX_PKTSZ (MTU + sizeof(ether_hdr_t))
|
#define MAX_PKTSZ (MTU + sizeof(ether_hdr_t))
|
||||||
#define MSS_IP4 (MTU - sizeof(ip4_hdr_t) - sizeof(tcp_hdr_t))
|
#define MSS_IP4 (MTU - sizeof(ip4_hdr_t) - sizeof(tcp_hdr_t))
|
||||||
#define MSS_IP6 (MTU - sizeof(ip6_hdr_t) - sizeof(tcp_hdr_t))
|
#define MSS_IP6 (MTU - sizeof(ip6_hdr_t) - sizeof(tcp_hdr_t))
|
||||||
|
@ -149,31 +149,25 @@ typedef struct __attribute__((packed)) {
|
||||||
* IP/TCP checksumming operating on uint32_t intermediate state variable C.
|
* IP/TCP checksumming operating on uint32_t intermediate state variable C.
|
||||||
*/
|
*/
|
||||||
#define CHKSUM_INIT(C) \
|
#define CHKSUM_INIT(C) \
|
||||||
{ \
|
{ (C) = 0; }
|
||||||
(C) = 0; \
|
#define CHKSUM_ADD_RANGE(C, B, S) \
|
||||||
}
|
|
||||||
#define CHKSUM_ADD_RANGE(C,B,S) \
|
|
||||||
{ \
|
{ \
|
||||||
uint16_t *p = (uint16_t *)(B); \
|
uint16_t *p = (uint16_t *)(B); \
|
||||||
size_t words = (S) >> 1; \
|
size_t words = (S) >> 1; \
|
||||||
while (words--) { \
|
while(words--) { \
|
||||||
(C) += *p++; \
|
(C) += *p++; \
|
||||||
} \
|
} \
|
||||||
if ((S) & 1) { \
|
if((S)&1) { \
|
||||||
(C) += htons(*((char *)p) << 8); \
|
(C) += htons(*((char *)p) << 8); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
#define CHKSUM_ADD_UINT32(C,U) \
|
#define CHKSUM_ADD_UINT32(C, U) \
|
||||||
{ \
|
{ (C) += ((U) >> 16) + ((U)&0xFFFF); }
|
||||||
(C) += ((U) >> 16) + ((U) & 0xFFFF); \
|
#define CHKSUM_ADD_UINT16(C, U) \
|
||||||
}
|
{ (C) += (U); }
|
||||||
#define CHKSUM_ADD_UINT16(C,U) \
|
|
||||||
{ \
|
|
||||||
(C) += (U); \
|
|
||||||
}
|
|
||||||
#define CHKSUM_FINALIZE(C) \
|
#define CHKSUM_FINALIZE(C) \
|
||||||
{ \
|
{ \
|
||||||
(C) = ((C) >> 16) + ((C) & 0xffff); \
|
(C) = ((C) >> 16) + ((C)&0xffff); \
|
||||||
(C) += ((C) >> 16); \
|
(C) += ((C) >> 16); \
|
||||||
(C) = ~(C); \
|
(C) = ~(C); \
|
||||||
}
|
}
|
||||||
|
@ -189,9 +183,7 @@ typedef struct __attribute__((packed)) {
|
||||||
*
|
*
|
||||||
* Returns 0 on success and -1 on failure.
|
* Returns 0 on success and -1 on failure.
|
||||||
*/
|
*/
|
||||||
static int
|
static int logpkt_write_global_pcap_hdr(int fd) {
|
||||||
logpkt_write_global_pcap_hdr(int fd)
|
|
||||||
{
|
|
||||||
pcap_file_hdr_t hdr;
|
pcap_file_hdr_t hdr;
|
||||||
|
|
||||||
memset(&hdr, 0x0, sizeof(hdr));
|
memset(&hdr, 0x0, sizeof(hdr));
|
||||||
|
@ -214,8 +206,7 @@ logpkt_write_global_pcap_hdr(int fd)
|
||||||
* file descriptor. On error, -1 is returned and the file descriptor is in an
|
* file descriptor. On error, -1 is returned and the file descriptor is in an
|
||||||
* undefined but still open state.
|
* undefined but still open state.
|
||||||
*/
|
*/
|
||||||
int
|
int logpkt_pcap_open_fd(int fd) {
|
||||||
logpkt_pcap_open_fd(int fd) {
|
|
||||||
pcap_file_hdr_t hdr;
|
pcap_file_hdr_t hdr;
|
||||||
off_t sz;
|
off_t sz;
|
||||||
ssize_t n;
|
ssize_t n;
|
||||||
|
@ -226,20 +217,20 @@ logpkt_pcap_open_fd(int fd) {
|
||||||
|
|
||||||
if(!S_ISFIFO(st.st_mode)) {
|
if(!S_ISFIFO(st.st_mode)) {
|
||||||
sz = lseek(fd, 0, SEEK_END);
|
sz = lseek(fd, 0, SEEK_END);
|
||||||
if (sz == -1)
|
if(sz == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (sz > 0) {
|
if(sz > 0) {
|
||||||
if (lseek(fd, 0, SEEK_SET) == -1)
|
if(lseek(fd, 0, SEEK_SET) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
n = read(fd, &hdr, sizeof(pcap_file_hdr_t));
|
n = read(fd, &hdr, sizeof(pcap_file_hdr_t));
|
||||||
if (n != sizeof(pcap_file_hdr_t))
|
if(n != sizeof(pcap_file_hdr_t))
|
||||||
return -1;
|
return -1;
|
||||||
if (hdr.magic_number == PCAP_MAGIC)
|
if(hdr.magic_number == PCAP_MAGIC)
|
||||||
return lseek(fd, 0, SEEK_END) == -1 ? -1 : 0;
|
return lseek(fd, 0, SEEK_END) == -1 ? -1 : 0;
|
||||||
if (lseek(fd, 0, SEEK_SET) == -1)
|
if(lseek(fd, 0, SEEK_SET) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
if (ftruncate(fd, 0) == -1)
|
if(ftruncate(fd, 0) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -255,12 +246,15 @@ logpkt_pcap_open_fd(int fd) {
|
||||||
* match the actual link layer addresses to be used when sending traffic, not
|
* match the actual link layer addresses to be used when sending traffic, not
|
||||||
* some emulated addresses.
|
* some emulated addresses.
|
||||||
*/
|
*/
|
||||||
void
|
void logpkt_ctx_init(logpkt_ctx_t *ctx,
|
||||||
logpkt_ctx_init(logpkt_ctx_t *ctx, libnet_t *libnet, size_t mtu,
|
libnet_t *libnet,
|
||||||
const uint8_t *src_ether, const uint8_t *dst_ether,
|
size_t mtu,
|
||||||
const struct sockaddr *src_addr, socklen_t src_addr_len,
|
const uint8_t *src_ether,
|
||||||
const struct sockaddr *dst_addr, socklen_t dst_addr_len)
|
const uint8_t *dst_ether,
|
||||||
{
|
const struct sockaddr *src_addr,
|
||||||
|
socklen_t src_addr_len,
|
||||||
|
const struct sockaddr *dst_addr,
|
||||||
|
socklen_t dst_addr_len) {
|
||||||
ctx->libnet = libnet;
|
ctx->libnet = libnet;
|
||||||
memcpy(ctx->src_ether, src_ether, ETHER_ADDR_LEN);
|
memcpy(ctx->src_ether, src_ether, ETHER_ADDR_LEN);
|
||||||
memcpy(ctx->dst_ether, dst_ether, ETHER_ADDR_LEN);
|
memcpy(ctx->dst_ether, dst_ether, ETHER_ADDR_LEN);
|
||||||
|
@ -268,10 +262,9 @@ logpkt_ctx_init(logpkt_ctx_t *ctx, libnet_t *libnet, size_t mtu,
|
||||||
memcpy(&ctx->dst_addr, dst_addr, dst_addr_len);
|
memcpy(&ctx->dst_addr, dst_addr, dst_addr_len);
|
||||||
ctx->src_seq = 0;
|
ctx->src_seq = 0;
|
||||||
ctx->dst_seq = 0;
|
ctx->dst_seq = 0;
|
||||||
if (mtu) {
|
if(mtu) {
|
||||||
ctx->mss = mtu - sizeof(tcp_hdr_t)
|
ctx->mss = mtu - sizeof(tcp_hdr_t) -
|
||||||
- (dst_addr->sa_family == AF_INET
|
(dst_addr->sa_family == AF_INET ? sizeof(ip4_hdr_t)
|
||||||
? sizeof(ip4_hdr_t)
|
|
||||||
: sizeof(ip6_hdr_t));
|
: sizeof(ip6_hdr_t));
|
||||||
} else {
|
} else {
|
||||||
ctx->mss = dst_addr->sa_family == AF_INET ? MSS_IP4 : MSS_IP6;
|
ctx->mss = dst_addr->sa_family == AF_INET ? MSS_IP4 : MSS_IP6;
|
||||||
|
@ -282,9 +275,7 @@ logpkt_ctx_init(logpkt_ctx_t *ctx, libnet_t *libnet, size_t mtu,
|
||||||
* Write the layer 2 frame contained in *pkt* to file descriptor *fd* already
|
* Write the layer 2 frame contained in *pkt* to file descriptor *fd* already
|
||||||
* open for writing. First writes a PCAP record header, then the actual frame.
|
* open for writing. First writes a PCAP record header, then the actual frame.
|
||||||
*/
|
*/
|
||||||
static int
|
static int logpkt_pcap_write(const uint8_t *pkt, size_t pktsz, int fd) {
|
||||||
logpkt_pcap_write(const uint8_t *pkt, size_t pktsz, int fd)
|
|
||||||
{
|
|
||||||
pcap_rec_hdr_t rec_hdr;
|
pcap_rec_hdr_t rec_hdr;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
|
||||||
|
@ -293,14 +284,12 @@ logpkt_pcap_write(const uint8_t *pkt, size_t pktsz, int fd)
|
||||||
rec_hdr.ts_usec = tv.tv_usec;
|
rec_hdr.ts_usec = tv.tv_usec;
|
||||||
rec_hdr.orig_len = rec_hdr.incl_len = pktsz;
|
rec_hdr.orig_len = rec_hdr.incl_len = pktsz;
|
||||||
|
|
||||||
if (write(fd, &rec_hdr, sizeof(rec_hdr)) != sizeof(rec_hdr)) {
|
if(write(fd, &rec_hdr, sizeof(rec_hdr)) != sizeof(rec_hdr)) {
|
||||||
printf("Error writing pcap record hdr: %s\n",
|
printf("Error writing pcap record hdr: %s\n", strerror(errno));
|
||||||
strerror(errno));
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (write(fd, pkt, pktsz) != (ssize_t)pktsz) {
|
if(write(fd, pkt, pktsz) != (ssize_t)pktsz) {
|
||||||
printf("Error writing pcap record: %s\n",
|
printf("Error writing pcap record: %s\n", strerror(errno));
|
||||||
strerror(errno));
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -317,14 +306,16 @@ logpkt_pcap_write(const uint8_t *pkt, size_t pktsz, int fd)
|
||||||
* This function is stateless. For header fields that cannot be directly
|
* This function is stateless. For header fields that cannot be directly
|
||||||
* derived from the arguments, default values will be used.
|
* derived from the arguments, default values will be used.
|
||||||
*/
|
*/
|
||||||
static size_t
|
static size_t logpkt_pcap_build(uint8_t *pkt,
|
||||||
logpkt_pcap_build(uint8_t *pkt,
|
uint8_t *src_ether,
|
||||||
uint8_t *src_ether, uint8_t *dst_ether,
|
uint8_t *dst_ether,
|
||||||
const struct sockaddr *src_addr,
|
const struct sockaddr *src_addr,
|
||||||
const struct sockaddr *dst_addr,
|
const struct sockaddr *dst_addr,
|
||||||
char flags, uint32_t seq, uint32_t ack,
|
char flags,
|
||||||
const uint8_t *payload, size_t payloadlen)
|
uint32_t seq,
|
||||||
{
|
uint32_t ack,
|
||||||
|
const uint8_t *payload,
|
||||||
|
size_t payloadlen) {
|
||||||
ether_hdr_t *ether_hdr;
|
ether_hdr_t *ether_hdr;
|
||||||
ip4_hdr_t *ip4_hdr;
|
ip4_hdr_t *ip4_hdr;
|
||||||
ip6_hdr_t *ip6_hdr;
|
ip6_hdr_t *ip6_hdr;
|
||||||
|
@ -337,16 +328,13 @@ logpkt_pcap_build(uint8_t *pkt,
|
||||||
memcpy(ether_hdr->dst_mac, dst_ether, sizeof(ether_hdr->dst_mac));
|
memcpy(ether_hdr->dst_mac, dst_ether, sizeof(ether_hdr->dst_mac));
|
||||||
sz = sizeof(ether_hdr_t);
|
sz = sizeof(ether_hdr_t);
|
||||||
|
|
||||||
if (dst_addr->sa_family == AF_INET) {
|
if(dst_addr->sa_family == AF_INET) {
|
||||||
ether_hdr->ethertype = htons(ETHERTYPE_IP);
|
ether_hdr->ethertype = htons(ETHERTYPE_IP);
|
||||||
ip4_hdr = (ip4_hdr_t *)(((uint8_t *)ether_hdr) +
|
ip4_hdr = (ip4_hdr_t *)(((uint8_t *)ether_hdr) + sizeof(ether_hdr_t));
|
||||||
sizeof(ether_hdr_t));
|
|
||||||
ip4_hdr->version_ihl = 0x45; /* version 4, ihl 5 words */
|
ip4_hdr->version_ihl = 0x45; /* version 4, ihl 5 words */
|
||||||
ip4_hdr->dscp_ecn = 0;
|
ip4_hdr->dscp_ecn = 0;
|
||||||
ip4_hdr->len = htons(sizeof(ip4_hdr_t) +
|
ip4_hdr->len = htons(sizeof(ip4_hdr_t) + sizeof(tcp_hdr_t) + payloadlen);
|
||||||
sizeof(tcp_hdr_t) + payloadlen);
|
ip4_hdr->id = sys_rand16(), ip4_hdr->frag = 0;
|
||||||
ip4_hdr->id = sys_rand16(),
|
|
||||||
ip4_hdr->frag = 0;
|
|
||||||
ip4_hdr->ttl = 64;
|
ip4_hdr->ttl = 64;
|
||||||
ip4_hdr->proto = IPPROTO_TCP;
|
ip4_hdr->proto = IPPROTO_TCP;
|
||||||
ip4_hdr->src_addr = CSIN(src_addr)->sin_addr.s_addr;
|
ip4_hdr->src_addr = CSIN(src_addr)->sin_addr.s_addr;
|
||||||
|
@ -357,8 +345,7 @@ logpkt_pcap_build(uint8_t *pkt,
|
||||||
CHKSUM_FINALIZE(sum);
|
CHKSUM_FINALIZE(sum);
|
||||||
ip4_hdr->chksum = sum;
|
ip4_hdr->chksum = sum;
|
||||||
sz += sizeof(ip4_hdr_t);
|
sz += sizeof(ip4_hdr_t);
|
||||||
tcp_hdr = (tcp_hdr_t *)(((uint8_t *)ip4_hdr) +
|
tcp_hdr = (tcp_hdr_t *)(((uint8_t *)ip4_hdr) + sizeof(ip4_hdr_t));
|
||||||
sizeof(ip4_hdr_t));
|
|
||||||
tcp_hdr->src_port = CSIN(src_addr)->sin_port;
|
tcp_hdr->src_port = CSIN(src_addr)->sin_port;
|
||||||
tcp_hdr->dst_port = CSIN(dst_addr)->sin_port;
|
tcp_hdr->dst_port = CSIN(dst_addr)->sin_port;
|
||||||
/* pseudo header */
|
/* pseudo header */
|
||||||
|
@ -369,8 +356,7 @@ logpkt_pcap_build(uint8_t *pkt,
|
||||||
CHKSUM_ADD_UINT16(sum, htons(sizeof(tcp_hdr_t) + payloadlen));
|
CHKSUM_ADD_UINT16(sum, htons(sizeof(tcp_hdr_t) + payloadlen));
|
||||||
} else {
|
} else {
|
||||||
ether_hdr->ethertype = htons(ETHERTYPE_IPV6);
|
ether_hdr->ethertype = htons(ETHERTYPE_IPV6);
|
||||||
ip6_hdr = (ip6_hdr_t *)(((uint8_t *)ether_hdr) +
|
ip6_hdr = (ip6_hdr_t *)(((uint8_t *)ether_hdr) + sizeof(ether_hdr_t));
|
||||||
sizeof(ether_hdr_t));
|
|
||||||
ip6_hdr->flags = htonl(0x60000000UL); /* version 6 */
|
ip6_hdr->flags = htonl(0x60000000UL); /* version 6 */
|
||||||
ip6_hdr->len = htons(sizeof(tcp_hdr_t) + payloadlen);
|
ip6_hdr->len = htons(sizeof(tcp_hdr_t) + payloadlen);
|
||||||
ip6_hdr->next_hdr = IPPROTO_TCP;
|
ip6_hdr->next_hdr = IPPROTO_TCP;
|
||||||
|
@ -380,22 +366,19 @@ logpkt_pcap_build(uint8_t *pkt,
|
||||||
memcpy(ip6_hdr->dst_addr, CSIN6(dst_addr)->sin6_addr.s6_addr,
|
memcpy(ip6_hdr->dst_addr, CSIN6(dst_addr)->sin6_addr.s6_addr,
|
||||||
sizeof(ip6_hdr->dst_addr));
|
sizeof(ip6_hdr->dst_addr));
|
||||||
sz += sizeof(ip6_hdr_t);
|
sz += sizeof(ip6_hdr_t);
|
||||||
tcp_hdr = (tcp_hdr_t *)(((uint8_t *)ip6_hdr) +
|
tcp_hdr = (tcp_hdr_t *)(((uint8_t *)ip6_hdr) + sizeof(ip6_hdr_t));
|
||||||
sizeof(ip6_hdr_t));
|
|
||||||
tcp_hdr->src_port = CSIN6(src_addr)->sin6_port;
|
tcp_hdr->src_port = CSIN6(src_addr)->sin6_port;
|
||||||
tcp_hdr->dst_port = CSIN6(dst_addr)->sin6_port;
|
tcp_hdr->dst_port = CSIN6(dst_addr)->sin6_port;
|
||||||
/* pseudo header */
|
/* pseudo header */
|
||||||
CHKSUM_INIT(sum);
|
CHKSUM_INIT(sum);
|
||||||
CHKSUM_ADD_RANGE(sum, ip6_hdr->src_addr,
|
CHKSUM_ADD_RANGE(sum, ip6_hdr->src_addr, sizeof(ip6_hdr->src_addr));
|
||||||
sizeof(ip6_hdr->src_addr));
|
CHKSUM_ADD_RANGE(sum, ip6_hdr->dst_addr, sizeof(ip6_hdr->dst_addr));
|
||||||
CHKSUM_ADD_RANGE(sum, ip6_hdr->dst_addr,
|
|
||||||
sizeof(ip6_hdr->dst_addr));
|
|
||||||
CHKSUM_ADD_UINT32(sum, ip6_hdr->len);
|
CHKSUM_ADD_UINT32(sum, ip6_hdr->len);
|
||||||
CHKSUM_ADD_UINT16(sum, htons(IPPROTO_TCP));
|
CHKSUM_ADD_UINT16(sum, htons(IPPROTO_TCP));
|
||||||
}
|
}
|
||||||
tcp_hdr->seq = htonl(seq);
|
tcp_hdr->seq = htonl(seq);
|
||||||
tcp_hdr->ack = htonl(ack);
|
tcp_hdr->ack = htonl(ack);
|
||||||
tcp_hdr->flags = htons(0x5000|flags); /* data offset 5 words */
|
tcp_hdr->flags = htons(0x5000 | flags); /* data offset 5 words */
|
||||||
tcp_hdr->win = htons(32767);
|
tcp_hdr->win = htons(32767);
|
||||||
tcp_hdr->urgp = 0;
|
tcp_hdr->urgp = 0;
|
||||||
tcp_hdr->chksum = 0;
|
tcp_hdr->chksum = 0;
|
||||||
|
@ -412,80 +395,63 @@ logpkt_pcap_build(uint8_t *pkt,
|
||||||
* Build a packet using libnet intended for mirroring mode. The packet will
|
* Build a packet using libnet intended for mirroring mode. The packet will
|
||||||
* be dynamically allocated on the heap by the libnet instance *libnet*.
|
* be dynamically allocated on the heap by the libnet instance *libnet*.
|
||||||
*/
|
*/
|
||||||
static int
|
static int logpkt_mirror_build(libnet_t *libnet,
|
||||||
logpkt_mirror_build(libnet_t *libnet,
|
uint8_t *src_ether,
|
||||||
uint8_t *src_ether, uint8_t *dst_ether,
|
uint8_t *dst_ether,
|
||||||
const struct sockaddr *src_addr,
|
const struct sockaddr *src_addr,
|
||||||
const struct sockaddr *dst_addr,
|
const struct sockaddr *dst_addr,
|
||||||
char flags, uint32_t seq, uint32_t ack,
|
char flags,
|
||||||
const uint8_t *payload, size_t payloadlen)
|
uint32_t seq,
|
||||||
{
|
uint32_t ack,
|
||||||
|
const uint8_t *payload,
|
||||||
|
size_t payloadlen) {
|
||||||
libnet_ptag_t ptag;
|
libnet_ptag_t ptag;
|
||||||
|
|
||||||
ptag = libnet_build_tcp(htons(src_addr->sa_family == AF_INET
|
ptag = libnet_build_tcp(
|
||||||
? CSIN(src_addr)->sin_port
|
htons(src_addr->sa_family == AF_INET ? CSIN(src_addr)->sin_port
|
||||||
: CSIN6(src_addr)->sin6_port),
|
: CSIN6(src_addr)->sin6_port),
|
||||||
htons(dst_addr->sa_family == AF_INET
|
htons(dst_addr->sa_family == AF_INET ? CSIN(dst_addr)->sin_port
|
||||||
? CSIN(dst_addr)->sin_port
|
|
||||||
: CSIN6(dst_addr)->sin6_port),
|
: CSIN6(dst_addr)->sin6_port),
|
||||||
seq,
|
seq, ack, flags, 32767, /* window size */
|
||||||
ack,
|
|
||||||
flags,
|
|
||||||
32767, /* window size */
|
|
||||||
0, /* checksum */
|
0, /* checksum */
|
||||||
0, /* urgent pointer */
|
0, /* urgent pointer */
|
||||||
LIBNET_TCP_H + payloadlen,
|
LIBNET_TCP_H + payloadlen, (uint8_t *)payload, payloadlen, libnet, 0);
|
||||||
(uint8_t *)payload, payloadlen,
|
if(ptag == -1) {
|
||||||
libnet, 0);
|
printf("Error building tcp header: %s", libnet_geterror(libnet));
|
||||||
if (ptag == -1) {
|
|
||||||
printf("Error building tcp header: %s",
|
|
||||||
libnet_geterror(libnet));
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dst_addr->sa_family == AF_INET) {
|
if(dst_addr->sa_family == AF_INET) {
|
||||||
ptag = libnet_build_ipv4(LIBNET_IPV4_H + LIBNET_TCP_H +
|
ptag = libnet_build_ipv4(
|
||||||
payloadlen,
|
LIBNET_IPV4_H + LIBNET_TCP_H + payloadlen, 0, /* TOS */
|
||||||
0, /* TOS */
|
(uint16_t)sys_rand16(), /* id */
|
||||||
(uint16_t)
|
|
||||||
sys_rand16(), /* id */
|
|
||||||
0x4000, /* frag */
|
0x4000, /* frag */
|
||||||
64, /* TTL */
|
64, /* TTL */
|
||||||
IPPROTO_TCP, /* protocol */
|
IPPROTO_TCP, /* protocol */
|
||||||
0, /* checksum */
|
0, /* checksum */
|
||||||
CSIN(src_addr)->sin_addr.s_addr,
|
CSIN(src_addr)->sin_addr.s_addr, CSIN(dst_addr)->sin_addr.s_addr, NULL,
|
||||||
CSIN(dst_addr)->sin_addr.s_addr,
|
0, libnet, 0);
|
||||||
NULL, 0,
|
|
||||||
libnet, 0);
|
|
||||||
} else {
|
} else {
|
||||||
ptag = libnet_build_ipv6(0, /* traffic class */
|
ptag = libnet_build_ipv6(
|
||||||
|
0, /* traffic class */
|
||||||
0, /* flow label */
|
0, /* flow label */
|
||||||
LIBNET_IPV6_H + LIBNET_TCP_H +
|
LIBNET_IPV6_H + LIBNET_TCP_H + payloadlen, IPPROTO_TCP,
|
||||||
payloadlen,
|
|
||||||
IPPROTO_TCP,
|
|
||||||
255, /* hop limit */
|
255, /* hop limit */
|
||||||
*(struct libnet_in6_addr *)
|
*(struct libnet_in6_addr *)&CSIN6(src_addr)->sin6_addr,
|
||||||
&CSIN6(src_addr)->sin6_addr,
|
*(struct libnet_in6_addr *)&CSIN6(dst_addr)->sin6_addr, NULL, 0, libnet,
|
||||||
*(struct libnet_in6_addr *)
|
0);
|
||||||
&CSIN6(dst_addr)->sin6_addr,
|
|
||||||
NULL, 0,
|
|
||||||
libnet, 0);
|
|
||||||
}
|
}
|
||||||
if (ptag == -1) {
|
if(ptag == -1) {
|
||||||
printf("Error building ip header: %s",
|
printf("Error building ip header: %s", libnet_geterror(libnet));
|
||||||
libnet_geterror(libnet));
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptag = libnet_build_ethernet(dst_ether,
|
ptag = libnet_build_ethernet(
|
||||||
src_ether,
|
dst_ether, src_ether,
|
||||||
dst_addr->sa_family == AF_INET
|
dst_addr->sa_family == AF_INET ? ETHERTYPE_IP : ETHERTYPE_IPV6, NULL, 0,
|
||||||
? ETHERTYPE_IP : ETHERTYPE_IPV6,
|
|
||||||
NULL, 0,
|
|
||||||
libnet, 0);
|
libnet, 0);
|
||||||
if (ptag == -1) {
|
if(ptag == -1) {
|
||||||
printf("Error building ethernet header: %s",
|
printf("Error building ethernet header: %s", libnet_geterror(libnet));
|
||||||
libnet_geterror(libnet));
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -502,34 +468,28 @@ logpkt_mirror_build(libnet_t *libnet,
|
||||||
* Caller must ensure that *payload* fits into a frame depending on the MTU
|
* Caller must ensure that *payload* fits into a frame depending on the MTU
|
||||||
* selected (interface in mirroring mode, MTU value in PCAP writing mode).
|
* selected (interface in mirroring mode, MTU value in PCAP writing mode).
|
||||||
*/
|
*/
|
||||||
static int
|
static int logpkt_write_packet(logpkt_ctx_t *ctx,
|
||||||
logpkt_write_packet(logpkt_ctx_t *ctx, int fd, int direction, char flags,
|
int fd,
|
||||||
const uint8_t *payload, size_t payloadlen)
|
int direction,
|
||||||
{
|
char flags,
|
||||||
|
const uint8_t *payload,
|
||||||
|
size_t payloadlen) {
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
if (fd != -1) {
|
if(fd != -1) {
|
||||||
uint8_t buf[MAX_PKTSZ];
|
uint8_t buf[MAX_PKTSZ];
|
||||||
size_t sz;
|
size_t sz;
|
||||||
if (direction == LOGPKT_REQUEST) {
|
if(direction == LOGPKT_REQUEST) {
|
||||||
sz = logpkt_pcap_build(buf,
|
sz = logpkt_pcap_build(buf, ctx->src_ether, ctx->dst_ether,
|
||||||
ctx->src_ether, ctx->dst_ether,
|
CSA(&ctx->src_addr), CSA(&ctx->dst_addr), flags,
|
||||||
CSA(&ctx->src_addr),
|
ctx->src_seq, ctx->dst_seq, payload, payloadlen);
|
||||||
CSA(&ctx->dst_addr),
|
|
||||||
flags,
|
|
||||||
ctx->src_seq, ctx->dst_seq,
|
|
||||||
payload, payloadlen);
|
|
||||||
} else {
|
} else {
|
||||||
sz = logpkt_pcap_build(buf,
|
sz = logpkt_pcap_build(buf, ctx->dst_ether, ctx->src_ether,
|
||||||
ctx->dst_ether, ctx->src_ether,
|
CSA(&ctx->dst_addr), CSA(&ctx->src_addr), flags,
|
||||||
CSA(&ctx->dst_addr),
|
ctx->dst_seq, ctx->src_seq, payload, payloadlen);
|
||||||
CSA(&ctx->src_addr),
|
|
||||||
flags,
|
|
||||||
ctx->dst_seq, ctx->src_seq,
|
|
||||||
payload, payloadlen);
|
|
||||||
}
|
}
|
||||||
rv = logpkt_pcap_write(buf, sz, fd);
|
rv = logpkt_pcap_write(buf, sz, fd);
|
||||||
if (rv == -1) {
|
if(rv == -1) {
|
||||||
printf("Error writing packet to PCAP file\n");
|
printf("Error writing packet to PCAP file\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -538,31 +498,22 @@ logpkt_write_packet(logpkt_ctx_t *ctx, int fd, int direction, char flags,
|
||||||
/* Source and destination ether are determined by the actual
|
/* Source and destination ether are determined by the actual
|
||||||
* local MAC address and target MAC address for mirroring the
|
* local MAC address and target MAC address for mirroring the
|
||||||
* packets to; use them as-is for both directions. */
|
* packets to; use them as-is for both directions. */
|
||||||
if (direction == LOGPKT_REQUEST) {
|
if(direction == LOGPKT_REQUEST) {
|
||||||
rv = logpkt_mirror_build(ctx->libnet,
|
rv = logpkt_mirror_build(ctx->libnet, ctx->src_ether, ctx->dst_ether,
|
||||||
ctx->src_ether, ctx->dst_ether,
|
CSA(&ctx->src_addr), CSA(&ctx->dst_addr), flags,
|
||||||
CSA(&ctx->src_addr),
|
ctx->src_seq, ctx->dst_seq, payload, payloadlen);
|
||||||
CSA(&ctx->dst_addr),
|
|
||||||
flags,
|
|
||||||
ctx->src_seq, ctx->dst_seq,
|
|
||||||
payload, payloadlen);
|
|
||||||
} else {
|
} else {
|
||||||
rv = logpkt_mirror_build(ctx->libnet,
|
rv = logpkt_mirror_build(ctx->libnet, ctx->src_ether, ctx->dst_ether,
|
||||||
ctx->src_ether, ctx->dst_ether,
|
CSA(&ctx->dst_addr), CSA(&ctx->src_addr), flags,
|
||||||
CSA(&ctx->dst_addr),
|
ctx->dst_seq, ctx->src_seq, payload, payloadlen);
|
||||||
CSA(&ctx->src_addr),
|
|
||||||
flags,
|
|
||||||
ctx->dst_seq, ctx->src_seq,
|
|
||||||
payload, payloadlen);
|
|
||||||
}
|
}
|
||||||
if (rv == -1) {
|
if(rv == -1) {
|
||||||
printf("Error building packet\n");
|
printf("Error building packet\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
rv = libnet_write(ctx->libnet);
|
rv = libnet_write(ctx->libnet);
|
||||||
if (rv == -1) {
|
if(rv == -1) {
|
||||||
printf("Error writing packet: %s\n",
|
printf("Error writing packet: %s\n", libnet_geterror(ctx->libnet));
|
||||||
libnet_geterror(ctx->libnet));
|
|
||||||
}
|
}
|
||||||
libnet_clear_packet(ctx->libnet);
|
libnet_clear_packet(ctx->libnet);
|
||||||
#else /* WITHOUT_MIRROR */
|
#else /* WITHOUT_MIRROR */
|
||||||
|
@ -575,21 +526,17 @@ logpkt_write_packet(logpkt_ctx_t *ctx, int fd, int direction, char flags,
|
||||||
/*
|
/*
|
||||||
* Emulate the initial SYN handshake.
|
* Emulate the initial SYN handshake.
|
||||||
*/
|
*/
|
||||||
static int
|
static int logpkt_write_syn_handshake(logpkt_ctx_t *ctx, int fd) {
|
||||||
logpkt_write_syn_handshake(logpkt_ctx_t *ctx, int fd)
|
|
||||||
{
|
|
||||||
ctx->src_seq = sys_rand32();
|
ctx->src_seq = sys_rand32();
|
||||||
if (logpkt_write_packet(ctx, fd, LOGPKT_REQUEST,
|
if(logpkt_write_packet(ctx, fd, LOGPKT_REQUEST, TH_SYN, NULL, 0) == -1)
|
||||||
TH_SYN, NULL, 0) == -1)
|
|
||||||
return -1;
|
return -1;
|
||||||
ctx->src_seq += 1;
|
ctx->src_seq += 1;
|
||||||
ctx->dst_seq = sys_rand32();
|
ctx->dst_seq = sys_rand32();
|
||||||
if (logpkt_write_packet(ctx, fd, LOGPKT_RESPONSE,
|
if(logpkt_write_packet(ctx, fd, LOGPKT_RESPONSE, TH_SYN | TH_ACK, NULL, 0) ==
|
||||||
TH_SYN|TH_ACK, NULL, 0) == -1)
|
-1)
|
||||||
return -1;
|
return -1;
|
||||||
ctx->dst_seq += 1;
|
ctx->dst_seq += 1;
|
||||||
if (logpkt_write_packet(ctx, fd, LOGPKT_REQUEST,
|
if(logpkt_write_packet(ctx, fd, LOGPKT_REQUEST, TH_ACK, NULL, 0) == -1)
|
||||||
TH_ACK, NULL, 0) == -1)
|
|
||||||
return -1;
|
return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -599,27 +546,30 @@ logpkt_write_syn_handshake(logpkt_ctx_t *ctx, int fd)
|
||||||
* necessary, a SYN handshake will automatically be generated before emitting
|
* necessary, a SYN handshake will automatically be generated before emitting
|
||||||
* the packet carrying the payload plus a matching ACK.
|
* the packet carrying the payload plus a matching ACK.
|
||||||
*/
|
*/
|
||||||
int
|
int logpkt_write_payload(logpkt_ctx_t *ctx,
|
||||||
logpkt_write_payload(logpkt_ctx_t *ctx, int fd, int direction,
|
int fd,
|
||||||
const uint8_t *payload, size_t payloadlen)
|
int direction,
|
||||||
{
|
const uint8_t *payload,
|
||||||
int other_direction = (direction == LOGPKT_REQUEST) ? LOGPKT_RESPONSE
|
size_t payloadlen) {
|
||||||
: LOGPKT_REQUEST;
|
int other_direction =
|
||||||
|
(direction == LOGPKT_REQUEST) ? LOGPKT_RESPONSE : LOGPKT_REQUEST;
|
||||||
|
|
||||||
if (ctx->src_seq == 0) {
|
if(ctx->src_seq == 0) {
|
||||||
if (logpkt_write_syn_handshake(ctx, fd) == -1)
|
if(logpkt_write_syn_handshake(ctx, fd) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (payloadlen > 0) {
|
while(payloadlen > 0) {
|
||||||
size_t n = payloadlen > ctx->mss ? ctx->mss : payloadlen;
|
size_t n = payloadlen > ctx->mss ? ctx->mss : payloadlen;
|
||||||
if (logpkt_write_packet(ctx, fd, direction,
|
if(logpkt_write_packet(ctx, fd, direction, TH_PUSH | TH_ACK, payload, n) ==
|
||||||
TH_PUSH|TH_ACK, payload, n) == -1) {
|
-1) {
|
||||||
printf("Warning: Failed to write to pcap log"
|
printf(
|
||||||
": %s\n", strerror(errno));
|
"Warning: Failed to write to pcap log"
|
||||||
|
": %s\n",
|
||||||
|
strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (direction == LOGPKT_REQUEST) {
|
if(direction == LOGPKT_REQUEST) {
|
||||||
ctx->src_seq += n;
|
ctx->src_seq += n;
|
||||||
} else {
|
} else {
|
||||||
ctx->dst_seq += n;
|
ctx->dst_seq += n;
|
||||||
|
@ -628,10 +578,8 @@ logpkt_write_payload(logpkt_ctx_t *ctx, int fd, int direction,
|
||||||
payloadlen -= n;
|
payloadlen -= n;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (logpkt_write_packet(ctx, fd, other_direction,
|
if(logpkt_write_packet(ctx, fd, other_direction, TH_ACK, NULL, 0) == -1) {
|
||||||
TH_ACK, NULL, 0) == -1) {
|
printf("Warning: Failed to write to pcap log: %s\n", strerror(errno));
|
||||||
printf("Warning: Failed to write to pcap log: %s\n",
|
|
||||||
strerror(errno));
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -641,40 +589,37 @@ logpkt_write_payload(logpkt_ctx_t *ctx, int fd, int direction,
|
||||||
* Emulate a connection close, emitting a FIN handshake in the correct
|
* Emulate a connection close, emitting a FIN handshake in the correct
|
||||||
* direction. Does not close the file descriptor.
|
* direction. Does not close the file descriptor.
|
||||||
*/
|
*/
|
||||||
int
|
int logpkt_write_close(logpkt_ctx_t *ctx, int fd, int direction) {
|
||||||
logpkt_write_close(logpkt_ctx_t *ctx, int fd, int direction) {
|
int other_direction =
|
||||||
int other_direction = (direction == LOGPKT_REQUEST) ? LOGPKT_RESPONSE
|
(direction == LOGPKT_REQUEST) ? LOGPKT_RESPONSE : LOGPKT_REQUEST;
|
||||||
: LOGPKT_REQUEST;
|
|
||||||
|
|
||||||
if (ctx->src_seq == 0) {
|
if(ctx->src_seq == 0) {
|
||||||
if (logpkt_write_syn_handshake(ctx, fd) == -1)
|
if(logpkt_write_syn_handshake(ctx, fd) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (logpkt_write_packet(ctx, fd, direction,
|
if(logpkt_write_packet(ctx, fd, direction, TH_FIN | TH_ACK, NULL, 0) == -1) {
|
||||||
TH_FIN|TH_ACK, NULL, 0) == -1) {
|
|
||||||
printf("Warning: Failed to write packet\n");
|
printf("Warning: Failed to write packet\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (direction == LOGPKT_REQUEST) {
|
if(direction == LOGPKT_REQUEST) {
|
||||||
ctx->src_seq += 1;
|
ctx->src_seq += 1;
|
||||||
} else {
|
} else {
|
||||||
ctx->dst_seq += 1;
|
ctx->dst_seq += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (logpkt_write_packet(ctx, fd, other_direction,
|
if(logpkt_write_packet(ctx, fd, other_direction, TH_FIN | TH_ACK, NULL, 0) ==
|
||||||
TH_FIN|TH_ACK, NULL, 0) == -1) {
|
-1) {
|
||||||
printf("Warning: Failed to write packet\n");
|
printf("Warning: Failed to write packet\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (other_direction == LOGPKT_REQUEST) {
|
if(other_direction == LOGPKT_REQUEST) {
|
||||||
ctx->src_seq += 1;
|
ctx->src_seq += 1;
|
||||||
} else {
|
} else {
|
||||||
ctx->dst_seq += 1;
|
ctx->dst_seq += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (logpkt_write_packet(ctx, fd, direction,
|
if(logpkt_write_packet(ctx, fd, direction, TH_ACK, NULL, 0) == -1) {
|
||||||
TH_ACK, NULL, 0) == -1) {
|
|
||||||
printf("Warning: Failed to write packet\n");
|
printf("Warning: Failed to write packet\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -692,34 +637,31 @@ typedef struct {
|
||||||
/*
|
/*
|
||||||
* Receive a single ARP reply and copy the resulting ether to ctx->ether.
|
* Receive a single ARP reply and copy the resulting ether to ctx->ether.
|
||||||
*/
|
*/
|
||||||
static void
|
static void logpkt_recv_arp_reply(uint8_t *user,
|
||||||
logpkt_recv_arp_reply(uint8_t *user,
|
|
||||||
UNUSED const struct pcap_pkthdr *h,
|
UNUSED const struct pcap_pkthdr *h,
|
||||||
const uint8_t *packet)
|
const uint8_t *packet) {
|
||||||
{
|
logpkt_recv_arp_reply_ctx_t *ctx = (logpkt_recv_arp_reply_ctx_t *)user;
|
||||||
logpkt_recv_arp_reply_ctx_t *ctx = (logpkt_recv_arp_reply_ctx_t*)user;
|
struct libnet_802_3_hdr *heth = (void *)packet;
|
||||||
struct libnet_802_3_hdr *heth = (void*)packet;
|
struct libnet_arp_hdr *harp = (void *)((char *)heth + LIBNET_ETH_H);
|
||||||
struct libnet_arp_hdr *harp = (void*)((char*)heth + LIBNET_ETH_H);
|
|
||||||
|
|
||||||
/* skip if wrong protocol */
|
/* skip if wrong protocol */
|
||||||
if (htons(harp->ar_op) != ARPOP_REPLY)
|
if(htons(harp->ar_op) != ARPOP_REPLY)
|
||||||
return;
|
return;
|
||||||
if (htons(harp->ar_pro) != ETHERTYPE_IP)
|
if(htons(harp->ar_pro) != ETHERTYPE_IP)
|
||||||
return;
|
return;
|
||||||
if (htons(harp->ar_hrd) != ARPHRD_ETHER)
|
if(htons(harp->ar_hrd) != ARPHRD_ETHER)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* skip if wrong target IP address */
|
/* skip if wrong target IP address */
|
||||||
if (!!memcmp(&ctx->ip, (char*)harp + harp->ar_hln + LIBNET_ARP_H, 4))
|
if(!!memcmp(&ctx->ip, (char *)harp + harp->ar_hln + LIBNET_ARP_H, 4))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* skip if source ether mismatch */
|
/* skip if source ether mismatch */
|
||||||
if (!!memcmp((u_char*)harp + sizeof(struct libnet_arp_hdr),
|
if(!!memcmp((u_char *)harp + sizeof(struct libnet_arp_hdr),
|
||||||
heth->_802_3_shost, ETHER_ADDR_LEN))
|
heth->_802_3_shost, ETHER_ADDR_LEN))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
memcpy(ctx->ether,
|
memcpy(ctx->ether, (u_char *)harp + sizeof(struct libnet_arp_hdr),
|
||||||
(u_char*)harp + sizeof(struct libnet_arp_hdr),
|
|
||||||
ETHER_ADDR_LEN);
|
ETHER_ADDR_LEN);
|
||||||
ctx->result = 0;
|
ctx->result = 0;
|
||||||
}
|
}
|
||||||
|
@ -729,107 +671,89 @@ logpkt_recv_arp_reply(uint8_t *user,
|
||||||
* mirroring packets to dst_ip_s on interface dst_if_s.
|
* mirroring packets to dst_ip_s on interface dst_if_s.
|
||||||
* Only IPv4 mirror targets are supported.
|
* Only IPv4 mirror targets are supported.
|
||||||
*/
|
*/
|
||||||
int
|
int logpkt_ether_lookup(libnet_t *libnet,
|
||||||
logpkt_ether_lookup(libnet_t *libnet,
|
uint8_t *src_ether,
|
||||||
uint8_t *src_ether, uint8_t *dst_ether,
|
uint8_t *dst_ether,
|
||||||
const char *dst_ip_s, const char *dst_if_s)
|
const char *dst_ip_s,
|
||||||
{
|
const char *dst_if_s) {
|
||||||
char errbuf[PCAP_ERRBUF_SIZE];
|
char errbuf[PCAP_ERRBUF_SIZE];
|
||||||
uint8_t broadcast_ether[ETHER_ADDR_LEN] = {
|
uint8_t broadcast_ether[ETHER_ADDR_LEN] = {0xff, 0xff, 0xff,
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
0xff, 0xff, 0xff};
|
||||||
uint8_t zero_ether[ETHER_ADDR_LEN] = {
|
uint8_t zero_ether[ETHER_ADDR_LEN] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
|
||||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
|
|
||||||
struct libnet_ether_addr *src_ether_addr;
|
struct libnet_ether_addr *src_ether_addr;
|
||||||
uint32_t src_ip;
|
uint32_t src_ip;
|
||||||
struct bpf_program bp;
|
struct bpf_program bp;
|
||||||
int count = 50;
|
int count = 50;
|
||||||
logpkt_recv_arp_reply_ctx_t ctx;
|
logpkt_recv_arp_reply_ctx_t ctx;
|
||||||
|
|
||||||
if (sys_get_af(dst_ip_s) != AF_INET) {
|
if(sys_get_af(dst_ip_s) != AF_INET) {
|
||||||
printf("Mirroring target must be an IPv4 address.\n");
|
printf("Mirroring target must be an IPv4 address.\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.result = -1;
|
ctx.result = -1;
|
||||||
ctx.ip = libnet_name2addr4(libnet, (char *)dst_ip_s,
|
ctx.ip = libnet_name2addr4(libnet, (char *)dst_ip_s, LIBNET_DONT_RESOLVE);
|
||||||
LIBNET_DONT_RESOLVE);
|
if(ctx.ip == (uint32_t)-1) {
|
||||||
if (ctx.ip == (uint32_t)-1) {
|
printf("Error converting dst IP address: %s\n", libnet_geterror(libnet));
|
||||||
printf("Error converting dst IP address: %s\n",
|
|
||||||
libnet_geterror(libnet));
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
src_ip = libnet_get_ipaddr4(libnet);
|
src_ip = libnet_get_ipaddr4(libnet);
|
||||||
if (src_ip == (uint32_t)-1) {
|
if(src_ip == (uint32_t)-1) {
|
||||||
printf("Error getting src IP address: %s\n",
|
printf("Error getting src IP address: %s\n", libnet_geterror(libnet));
|
||||||
libnet_geterror(libnet));
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
src_ether_addr = libnet_get_hwaddr(libnet);
|
src_ether_addr = libnet_get_hwaddr(libnet);
|
||||||
if (src_ether_addr == NULL) {
|
if(src_ether_addr == NULL) {
|
||||||
printf("Error getting src ethernet address: %s\n",
|
printf("Error getting src ethernet address: %s\n", libnet_geterror(libnet));
|
||||||
libnet_geterror(libnet));
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
memcpy(src_ether, src_ether_addr->ether_addr_octet, ETHER_ADDR_LEN);
|
memcpy(src_ether, src_ether_addr->ether_addr_octet, ETHER_ADDR_LEN);
|
||||||
|
|
||||||
if (libnet_autobuild_arp(ARPOP_REQUEST,
|
if(libnet_autobuild_arp(ARPOP_REQUEST, src_ether, (uint8_t *)&src_ip,
|
||||||
src_ether,
|
zero_ether, (uint8_t *)&ctx.ip, libnet) == -1) {
|
||||||
(uint8_t*)&src_ip,
|
printf("Error building arp header: %s\n", libnet_geterror(libnet));
|
||||||
zero_ether,
|
|
||||||
(uint8_t*)&ctx.ip,
|
|
||||||
libnet) == -1) {
|
|
||||||
printf("Error building arp header: %s\n",
|
|
||||||
libnet_geterror(libnet));
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (libnet_autobuild_ethernet(broadcast_ether,
|
if(libnet_autobuild_ethernet(broadcast_ether, ETHERTYPE_ARP, libnet) == -1) {
|
||||||
ETHERTYPE_ARP,
|
printf("Error building ethernet header: %s", libnet_geterror(libnet));
|
||||||
libnet) == -1) {
|
|
||||||
printf("Error building ethernet header: %s",
|
|
||||||
libnet_geterror(libnet));
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
pcap_t *pcap = pcap_open_live(dst_if_s, 100, 0, 10, errbuf);
|
pcap_t *pcap = pcap_open_live(dst_if_s, 100, 0, 10, errbuf);
|
||||||
if (pcap == NULL) {
|
if(pcap == NULL) {
|
||||||
printf("Error in pcap_open_live(): %s\n", errbuf);
|
printf("Error in pcap_open_live(): %s\n", errbuf);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pcap_compile(pcap, &bp, "arp", 0, -1) == -1) {
|
if(pcap_compile(pcap, &bp, "arp", 0, -1) == -1) {
|
||||||
printf("Error in pcap_compile(): %s\n",
|
printf("Error in pcap_compile(): %s\n", pcap_geterr(pcap));
|
||||||
pcap_geterr(pcap));
|
|
||||||
goto out2;
|
goto out2;
|
||||||
}
|
}
|
||||||
if (pcap_setfilter(pcap, &bp) == -1) {
|
if(pcap_setfilter(pcap, &bp) == -1) {
|
||||||
printf("Error in pcap_setfilter(): %s\n",
|
printf("Error in pcap_setfilter(): %s\n", pcap_geterr(pcap));
|
||||||
pcap_geterr(pcap));
|
|
||||||
goto out3;
|
goto out3;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (libnet_write(libnet) != -1) {
|
if(libnet_write(libnet) != -1) {
|
||||||
/* Limit # of packets to process, so we can loop to
|
/* Limit # of packets to process, so we can loop to
|
||||||
* send arp requests on busy networks. */
|
* send arp requests on busy networks. */
|
||||||
if (pcap_dispatch(pcap, 1000,
|
if(pcap_dispatch(pcap, 1000, (pcap_handler)logpkt_recv_arp_reply,
|
||||||
(pcap_handler)logpkt_recv_arp_reply,
|
(u_char *)&ctx) < 0) {
|
||||||
(u_char*)&ctx) < 0) {
|
printf("Error in pcap_dispatch(): %s\n", pcap_geterr(pcap));
|
||||||
printf("Error in pcap_dispatch(): %s\n",
|
|
||||||
pcap_geterr(pcap));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printf("Error writing arp packet: %s",
|
printf("Error writing arp packet: %s", libnet_geterror(libnet));
|
||||||
libnet_geterror(libnet));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sleep(1);
|
sleep(1);
|
||||||
} while (ctx.result == -1 && --count > 0);
|
} while(ctx.result == -1 && --count > 0);
|
||||||
|
|
||||||
if (ctx.result == 0) {
|
if(ctx.result == 0) {
|
||||||
memcpy(dst_ether, &ctx.ether, ETHER_ADDR_LEN);
|
memcpy(dst_ether, &ctx.ether, ETHER_ADDR_LEN);
|
||||||
//log_dbg_printf("Mirror target is up: "
|
// log_dbg_printf("Mirror target is up: "
|
||||||
// "%02x:%02x:%02x:%02x:%02x:%02x\n",
|
// "%02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||||
// dst_ether[0], dst_ether[1], dst_ether[2],
|
// dst_ether[0], dst_ether[1], dst_ether[2],
|
||||||
// dst_ether[3], dst_ether[4], dst_ether[5]);
|
// dst_ether[3], dst_ether[4], dst_ether[5]);
|
||||||
|
|
|
@ -35,7 +35,6 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
|
|
||||||
#ifndef WITHOUT_MIRROR
|
#ifndef WITHOUT_MIRROR
|
||||||
#include <libnet.h>
|
#include <libnet.h>
|
||||||
#else /* WITHOUT_MIRROR */
|
#else /* WITHOUT_MIRROR */
|
||||||
|
@ -58,14 +57,25 @@ typedef struct {
|
||||||
#define LOGPKT_RESPONSE 1
|
#define LOGPKT_RESPONSE 1
|
||||||
|
|
||||||
int logpkt_pcap_open_fd(int fd) WUNRES;
|
int logpkt_pcap_open_fd(int fd) WUNRES;
|
||||||
void logpkt_ctx_init(logpkt_ctx_t *, libnet_t *, size_t,
|
void logpkt_ctx_init(logpkt_ctx_t *,
|
||||||
const uint8_t *, const uint8_t *,
|
libnet_t *,
|
||||||
const struct sockaddr *, socklen_t,
|
size_t,
|
||||||
const struct sockaddr *, socklen_t);
|
const uint8_t *,
|
||||||
int logpkt_write_payload(logpkt_ctx_t *, int, int,
|
const uint8_t *,
|
||||||
const unsigned char *, size_t) WUNRES;
|
const struct sockaddr *,
|
||||||
|
socklen_t,
|
||||||
|
const struct sockaddr *,
|
||||||
|
socklen_t);
|
||||||
|
int logpkt_write_payload(logpkt_ctx_t *,
|
||||||
|
int,
|
||||||
|
int,
|
||||||
|
const unsigned char *,
|
||||||
|
size_t) WUNRES;
|
||||||
int logpkt_write_close(logpkt_ctx_t *, int, int);
|
int logpkt_write_close(logpkt_ctx_t *, int, int);
|
||||||
int logpkt_ether_lookup(libnet_t *, uint8_t *, uint8_t *,
|
int logpkt_ether_lookup(libnet_t *,
|
||||||
const char *, const char *) WUNRES;
|
uint8_t *,
|
||||||
|
uint8_t *,
|
||||||
|
const char *,
|
||||||
|
const char *) WUNRES;
|
||||||
|
|
||||||
#endif /* !LOGPKT_H */
|
#endif /* !LOGPKT_H */
|
||||||
|
|
|
@ -17,132 +17,137 @@
|
||||||
|
|
||||||
#define DFLT_FILEMODE 0666
|
#define DFLT_FILEMODE 0666
|
||||||
|
|
||||||
static int init_pcap_logger PROTO_LIST((void * data));
|
static int init_pcap_logger PROTO_LIST((void *data));
|
||||||
static int deinit_pcap_logger PROTO_LIST(());
|
static int deinit_pcap_logger PROTO_LIST(());
|
||||||
static int create_pcap_logger PROTO_LIST((proto_obj **objp, struct sockaddr_storage *i_addr,
|
static int create_pcap_logger PROTO_LIST((proto_obj * *objp,
|
||||||
u_short i_port,struct sockaddr_storage *r_addr, u_short r_port, struct timeval *base_time));
|
struct sockaddr_storage *i_addr,
|
||||||
static int destroy_pcap_logger PROTO_LIST((proto_obj **objp));
|
u_short i_port,
|
||||||
static int data_pcap_logger PROTO_LIST((proto_obj *_obj, unsigned char *data,unsigned int len, int dir));
|
struct sockaddr_storage *r_addr,
|
||||||
static int close_pcap_logger PROTO_LIST((proto_obj *_obj, unsigned char *data,unsigned int len, int dir));
|
u_short r_port,
|
||||||
|
struct timeval *base_time));
|
||||||
|
static int destroy_pcap_logger PROTO_LIST((proto_obj * *objp));
|
||||||
|
static int data_pcap_logger PROTO_LIST(
|
||||||
|
(proto_obj * _obj, unsigned char *data, unsigned int len, int dir));
|
||||||
|
static int close_pcap_logger PROTO_LIST(
|
||||||
|
(proto_obj * _obj, unsigned char *data, unsigned int len, int dir));
|
||||||
|
|
||||||
int pcap_fd = -1;
|
int pcap_fd = -1;
|
||||||
static uint8_t content_pcap_src_ether[ETHER_ADDR_LEN] = {0x02, 0x00, 0x00, 0x11, 0x11, 0x11};
|
static uint8_t content_pcap_src_ether[ETHER_ADDR_LEN] = {0x02, 0x00, 0x00,
|
||||||
static uint8_t content_pcap_dst_ether[ETHER_ADDR_LEN] = {0x02, 0x00, 0x00, 0x22, 0x22, 0x22};
|
0x11, 0x11, 0x11};
|
||||||
|
static uint8_t content_pcap_dst_ether[ETHER_ADDR_LEN] = {0x02, 0x00, 0x00,
|
||||||
|
0x22, 0x22, 0x22};
|
||||||
|
|
||||||
static int
|
static int init_pcap_logger(void *data) {
|
||||||
init_pcap_logger (void *data)
|
char *pcap_outfile = (char *)data;
|
||||||
{
|
pcap_fd = open(pcap_outfile, O_RDWR | O_CREAT, DFLT_FILEMODE);
|
||||||
char *pcap_outfile = (char *) data;
|
if(pcap_fd == -1) {
|
||||||
pcap_fd = open(pcap_outfile, O_RDWR|O_CREAT, DFLT_FILEMODE);
|
// printf("Failed to open pcap '%s' for writing\n", pcap_outfile);
|
||||||
if (pcap_fd == -1) {
|
|
||||||
//printf("Failed to open pcap '%s' for writing\n", pcap_outfile);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (logpkt_pcap_open_fd(pcap_fd) == -1) {
|
if(logpkt_pcap_open_fd(pcap_fd) == -1) {
|
||||||
//printf("Failed to prepare '%s' for PCAP writing\n", pcap_outfile);
|
// printf("Failed to prepare '%s' for PCAP writing\n", pcap_outfile);
|
||||||
close(pcap_fd);
|
close(pcap_fd);
|
||||||
pcap_fd = -1;
|
pcap_fd = -1;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int deinit_pcap_logger(void) {
|
||||||
deinit_pcap_logger (void)
|
|
||||||
{
|
|
||||||
fdatasync(pcap_fd);
|
fdatasync(pcap_fd);
|
||||||
close(pcap_fd);
|
close(pcap_fd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int create_pcap_logger(proto_obj **objp, struct sockaddr_storage *i_addr, u_short i_port, struct sockaddr_storage *r_addr, u_short r_port, struct timeval *base_time)
|
static int create_pcap_logger(proto_obj **objp,
|
||||||
{
|
struct sockaddr_storage *i_addr,
|
||||||
int r,_status;
|
u_short i_port,
|
||||||
logpkt_ctx_t *pcap_obj=0;
|
struct sockaddr_storage *r_addr,
|
||||||
|
u_short r_port,
|
||||||
|
struct timeval *base_time) {
|
||||||
|
int r, _status;
|
||||||
|
logpkt_ctx_t *pcap_obj = 0;
|
||||||
struct sockaddr_in src_addr, dst_addr;
|
struct sockaddr_in src_addr, dst_addr;
|
||||||
|
|
||||||
if(!(pcap_obj=(logpkt_ctx_t *)calloc(1,sizeof(logpkt_ctx_t))))
|
if(!(pcap_obj = (logpkt_ctx_t *)calloc(1, sizeof(logpkt_ctx_t))))
|
||||||
ABORT(R_NO_MEMORY);
|
ABORT(R_NO_MEMORY);
|
||||||
|
|
||||||
//src_addr.sin_family = AF_INET;
|
// src_addr.sin_family = AF_INET;
|
||||||
//src_addr.sin_addr = *i_addr;
|
// src_addr.sin_addr = *i_addr;
|
||||||
memcpy(&src_addr, i_addr, sizeof(struct sockaddr_in));
|
memcpy(&src_addr, i_addr, sizeof(struct sockaddr_in));
|
||||||
src_addr.sin_port = htons(i_port);
|
src_addr.sin_port = htons(i_port);
|
||||||
|
|
||||||
//dst_addr.sin_family = AF_INET;
|
// dst_addr.sin_family = AF_INET;
|
||||||
//dst_addr.sin_addr = *r_addr;
|
// dst_addr.sin_addr = *r_addr;
|
||||||
memcpy(&dst_addr, r_addr, sizeof(struct sockaddr_in));
|
memcpy(&dst_addr, r_addr, sizeof(struct sockaddr_in));
|
||||||
dst_addr.sin_port = htons(r_port);
|
dst_addr.sin_port = htons(r_port);
|
||||||
|
|
||||||
logpkt_ctx_init(pcap_obj,NULL,0,content_pcap_src_ether, content_pcap_dst_ether,
|
logpkt_ctx_init(pcap_obj, NULL, 0, content_pcap_src_ether,
|
||||||
(const struct sockaddr*)&src_addr, sizeof(src_addr),
|
content_pcap_dst_ether, (const struct sockaddr *)&src_addr,
|
||||||
(const struct sockaddr*)&dst_addr, sizeof(dst_addr));
|
sizeof(src_addr), (const struct sockaddr *)&dst_addr,
|
||||||
*objp=(proto_obj *)pcap_obj;
|
sizeof(dst_addr));
|
||||||
_status=0;
|
*objp = (proto_obj *)pcap_obj;
|
||||||
abort:
|
_status = 0;
|
||||||
if(_status){
|
abort:
|
||||||
|
if(_status) {
|
||||||
destroy_pcap_logger((proto_obj **)&pcap_obj);
|
destroy_pcap_logger((proto_obj **)&pcap_obj);
|
||||||
}
|
}
|
||||||
return(_status);
|
return (_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int destroy_pcap_logger(proto_obj **objp) {
|
||||||
destroy_pcap_logger (proto_obj **objp)
|
|
||||||
{
|
|
||||||
logpkt_ctx_t *pcap_obj;
|
logpkt_ctx_t *pcap_obj;
|
||||||
|
|
||||||
if(!objp || !*objp)
|
if(!objp || !*objp)
|
||||||
return(0);
|
return (0);
|
||||||
|
|
||||||
pcap_obj=(logpkt_ctx_t *)*objp;
|
pcap_obj = (logpkt_ctx_t *)*objp;
|
||||||
|
|
||||||
free(pcap_obj);
|
free(pcap_obj);
|
||||||
*objp=0;
|
*objp = 0;
|
||||||
|
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int data_pcap_logger(proto_obj *_obj,
|
||||||
data_pcap_logger (proto_obj *_obj, unsigned char *data, unsigned int len, int dir)
|
unsigned char *data,
|
||||||
{
|
unsigned int len,
|
||||||
|
int dir) {
|
||||||
logpkt_ctx_t *pcap_obj = (logpkt_ctx_t *)_obj;
|
logpkt_ctx_t *pcap_obj = (logpkt_ctx_t *)_obj;
|
||||||
int direction;
|
int direction;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
if (dir == DIR_I2R ) direction = LOGPKT_REQUEST;
|
if(dir == DIR_I2R)
|
||||||
else direction = LOGPKT_RESPONSE;
|
direction = LOGPKT_REQUEST;
|
||||||
|
else
|
||||||
|
direction = LOGPKT_RESPONSE;
|
||||||
|
|
||||||
status = logpkt_write_payload(pcap_obj,pcap_fd,direction,data,len);
|
status = logpkt_write_payload(pcap_obj, pcap_fd, direction, data, len);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int close_pcap_logger(proto_obj *_obj,
|
||||||
close_pcap_logger (proto_obj *_obj, unsigned char *data, unsigned int len, int dir)
|
unsigned char *data,
|
||||||
{
|
unsigned int len,
|
||||||
|
int dir) {
|
||||||
logpkt_ctx_t *pcap_obj = (logpkt_ctx_t *)_obj;
|
logpkt_ctx_t *pcap_obj = (logpkt_ctx_t *)_obj;
|
||||||
int direction;
|
int direction;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
if (dir == DIR_I2R ) direction = LOGPKT_REQUEST;
|
if(dir == DIR_I2R)
|
||||||
else direction = LOGPKT_RESPONSE;
|
direction = LOGPKT_REQUEST;
|
||||||
|
else
|
||||||
|
direction = LOGPKT_RESPONSE;
|
||||||
|
|
||||||
status = logpkt_write_close(pcap_obj, pcap_fd, direction);
|
status = logpkt_write_close(pcap_obj, pcap_fd, direction);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct logger_mod_vtbl_ pcap_vtbl ={
|
static struct logger_mod_vtbl_ pcap_vtbl = {
|
||||||
init_pcap_logger,
|
init_pcap_logger, deinit_pcap_logger, create_pcap_logger,
|
||||||
deinit_pcap_logger,
|
destroy_pcap_logger, data_pcap_logger, close_pcap_logger,
|
||||||
create_pcap_logger,
|
|
||||||
destroy_pcap_logger,
|
|
||||||
data_pcap_logger,
|
|
||||||
close_pcap_logger,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct logger_mod_ pcap_mod = {
|
|
||||||
"PCAP",
|
|
||||||
&pcap_vtbl
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct logger_mod_ pcap_mod = {"PCAP", &pcap_vtbl};
|
||||||
|
|
|
@ -4,4 +4,3 @@
|
||||||
extern logger_mod pcap_mod;
|
extern logger_mod pcap_mod;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
26
pcap/sys.c
26
pcap/sys.c
|
@ -53,12 +53,11 @@
|
||||||
/*
|
/*
|
||||||
* Determine address family of addr
|
* Determine address family of addr
|
||||||
*/
|
*/
|
||||||
int
|
int sys_get_af(const char *addr) {
|
||||||
sys_get_af(const char *addr)
|
if(strstr(addr, ":"))
|
||||||
{
|
|
||||||
if (strstr(addr, ":"))
|
|
||||||
return AF_INET6;
|
return AF_INET6;
|
||||||
else if (!strpbrk(addr, "abcdefghijklmnopqrstu"
|
else if(!strpbrk(addr,
|
||||||
|
"abcdefghijklmnopqrstu"
|
||||||
"vwxyzABCDEFGHIJKLMNOP"
|
"vwxyzABCDEFGHIJKLMNOP"
|
||||||
"QRSTUVWXYZ-"))
|
"QRSTUVWXYZ-"))
|
||||||
return AF_INET;
|
return AF_INET;
|
||||||
|
@ -66,14 +65,12 @@ sys_get_af(const char *addr)
|
||||||
return AF_UNSPEC;
|
return AF_UNSPEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int sys_rand_seeded = 0;
|
static int sys_rand_seeded = 0;
|
||||||
|
|
||||||
static void
|
static void sys_rand_seed(void) {
|
||||||
sys_rand_seed(void) {
|
|
||||||
struct timeval seed;
|
struct timeval seed;
|
||||||
|
|
||||||
if (gettimeofday(&seed, NULL) == -1) {
|
if(gettimeofday(&seed, NULL) == -1) {
|
||||||
srandom((unsigned)time(NULL));
|
srandom((unsigned)time(NULL));
|
||||||
} else {
|
} else {
|
||||||
srandom((unsigned)(seed.tv_sec ^ seed.tv_usec));
|
srandom((unsigned)(seed.tv_sec ^ seed.tv_usec));
|
||||||
|
@ -81,19 +78,16 @@ sys_rand_seed(void) {
|
||||||
sys_rand_seeded = 1;
|
sys_rand_seeded = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t
|
uint16_t sys_rand16(void) {
|
||||||
sys_rand16(void) {
|
if(unlikely(!sys_rand_seeded))
|
||||||
if (unlikely(!sys_rand_seeded))
|
|
||||||
sys_rand_seed();
|
sys_rand_seed();
|
||||||
return random();
|
return random();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32_t sys_rand32(void) {
|
||||||
sys_rand32(void) {
|
if(unlikely(!sys_rand_seeded))
|
||||||
if (unlikely(!sys_rand_seeded))
|
|
||||||
sys_rand_seed();
|
sys_rand_seed();
|
||||||
return random();
|
return random();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* vim: set noet ft=c: */
|
/* vim: set noet ft=c: */
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: ciphersuites.c,v 1.3 2002/08/17 01:33:17 ekr Exp $
|
$Id: ciphersuites.c,v 1.3 2002/08/17 01:33:17 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,209 +44,203 @@
|
||||||
ekr@rtfm.com Tue Mar 30 17:19:56 1999
|
ekr@rtfm.com Tue Mar 30 17:19:56 1999
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <r_common.h>
|
#include <r_common.h>
|
||||||
|
|
||||||
#include "sslciphers.h"
|
#include "sslciphers.h"
|
||||||
|
|
||||||
static SSL_CipherSuite CipherSuites[]={
|
static SSL_CipherSuite CipherSuites[] = {
|
||||||
{1,KEX_RSA,SIG_RSA,ENC_NULL,0,0,0,DIG_MD5,16,0},
|
{1, KEX_RSA, SIG_RSA, ENC_NULL, 0, 0, 0, DIG_MD5, 16, 0},
|
||||||
{2,KEX_RSA,SIG_RSA,ENC_NULL,0,0,0,DIG_SHA,20,0},
|
{2, KEX_RSA, SIG_RSA, ENC_NULL, 0, 0, 0, DIG_SHA, 20, 0},
|
||||||
{3,KEX_RSA,SIG_RSA,ENC_RC4,1,128,40,DIG_MD5,16,1},
|
{3, KEX_RSA, SIG_RSA, ENC_RC4, 1, 128, 40, DIG_MD5, 16, 1},
|
||||||
{4,KEX_RSA,SIG_RSA,ENC_RC4,1,128,128,DIG_MD5,16,0},
|
{4, KEX_RSA, SIG_RSA, ENC_RC4, 1, 128, 128, DIG_MD5, 16, 0},
|
||||||
{5,KEX_RSA,SIG_RSA,ENC_RC4,1,128,128,DIG_SHA,20,0},
|
{5, KEX_RSA, SIG_RSA, ENC_RC4, 1, 128, 128, DIG_SHA, 20, 0},
|
||||||
{6,KEX_RSA,SIG_RSA,ENC_RC2,8,128,40,DIG_SHA,20,1},
|
{6, KEX_RSA, SIG_RSA, ENC_RC2, 8, 128, 40, DIG_SHA, 20, 1},
|
||||||
{7,KEX_RSA,SIG_RSA,ENC_IDEA,8,128,128,DIG_SHA,20,0},
|
{7, KEX_RSA, SIG_RSA, ENC_IDEA, 8, 128, 128, DIG_SHA, 20, 0},
|
||||||
{8,KEX_RSA,SIG_RSA,ENC_DES,8,64,40,DIG_SHA,20,1},
|
{8, KEX_RSA, SIG_RSA, ENC_DES, 8, 64, 40, DIG_SHA, 20, 1},
|
||||||
{9,KEX_RSA,SIG_RSA,ENC_DES,8,64,64,DIG_SHA,20,0},
|
{9, KEX_RSA, SIG_RSA, ENC_DES, 8, 64, 64, DIG_SHA, 20, 0},
|
||||||
{10,KEX_RSA,SIG_RSA,ENC_3DES,8,192,192,DIG_SHA,20,0},
|
{10, KEX_RSA, SIG_RSA, ENC_3DES, 8, 192, 192, DIG_SHA, 20, 0},
|
||||||
{11,KEX_DH,SIG_DSS,ENC_DES,8,64,40,DIG_SHA,20,1},
|
{11, KEX_DH, SIG_DSS, ENC_DES, 8, 64, 40, DIG_SHA, 20, 1},
|
||||||
{12,KEX_DH,SIG_DSS,ENC_DES,8,64,64,DIG_SHA,20,0},
|
{12, KEX_DH, SIG_DSS, ENC_DES, 8, 64, 64, DIG_SHA, 20, 0},
|
||||||
{13,KEX_DH,SIG_DSS,ENC_3DES,8,192,192,DIG_SHA,20,0},
|
{13, KEX_DH, SIG_DSS, ENC_3DES, 8, 192, 192, DIG_SHA, 20, 0},
|
||||||
{14,KEX_DH,SIG_RSA,ENC_DES,8,64,40,DIG_SHA,20,1},
|
{14, KEX_DH, SIG_RSA, ENC_DES, 8, 64, 40, DIG_SHA, 20, 1},
|
||||||
{15,KEX_DH,SIG_RSA,ENC_DES,8,64,64,DIG_SHA,20,0},
|
{15, KEX_DH, SIG_RSA, ENC_DES, 8, 64, 64, DIG_SHA, 20, 0},
|
||||||
{16,KEX_DH,SIG_RSA,ENC_3DES,8,192,192,DIG_SHA,20,0},
|
{16, KEX_DH, SIG_RSA, ENC_3DES, 8, 192, 192, DIG_SHA, 20, 0},
|
||||||
{17,KEX_DH,SIG_DSS,ENC_DES,8,64,40,DIG_SHA,20,1},
|
{17, KEX_DH, SIG_DSS, ENC_DES, 8, 64, 40, DIG_SHA, 20, 1},
|
||||||
{18,KEX_DH,SIG_DSS,ENC_DES,8,64,64,DIG_SHA,20,0},
|
{18, KEX_DH, SIG_DSS, ENC_DES, 8, 64, 64, DIG_SHA, 20, 0},
|
||||||
{19,KEX_DH,SIG_DSS,ENC_3DES,8,192,192,DIG_SHA,20,0},
|
{19, KEX_DH, SIG_DSS, ENC_3DES, 8, 192, 192, DIG_SHA, 20, 0},
|
||||||
{20,KEX_DH,SIG_RSA,ENC_DES,8,64,40,DIG_SHA,20,1},
|
{20, KEX_DH, SIG_RSA, ENC_DES, 8, 64, 40, DIG_SHA, 20, 1},
|
||||||
{21,KEX_DH,SIG_RSA,ENC_DES,8,64,64,DIG_SHA,20,0},
|
{21, KEX_DH, SIG_RSA, ENC_DES, 8, 64, 64, DIG_SHA, 20, 0},
|
||||||
{22,KEX_DH,SIG_RSA,ENC_3DES,8,192,192,DIG_SHA,20,0},
|
{22, KEX_DH, SIG_RSA, ENC_3DES, 8, 192, 192, DIG_SHA, 20, 0},
|
||||||
{23,KEX_DH,SIG_NONE,ENC_RC4,1,128,40,DIG_MD5,16,1},
|
{23, KEX_DH, SIG_NONE, ENC_RC4, 1, 128, 40, DIG_MD5, 16, 1},
|
||||||
{24,KEX_DH,SIG_NONE,ENC_RC4,1,128,128,DIG_MD5,16,0},
|
{24, KEX_DH, SIG_NONE, ENC_RC4, 1, 128, 128, DIG_MD5, 16, 0},
|
||||||
{25,KEX_DH,SIG_NONE,ENC_DES,8,64,40,DIG_MD5,16,1},
|
{25, KEX_DH, SIG_NONE, ENC_DES, 8, 64, 40, DIG_MD5, 16, 1},
|
||||||
{26,KEX_DH,SIG_NONE,ENC_DES,8,64,64,DIG_MD5,16,0},
|
{26, KEX_DH, SIG_NONE, ENC_DES, 8, 64, 64, DIG_MD5, 16, 0},
|
||||||
{27,KEX_DH,SIG_NONE,ENC_3DES,8,192,192,DIG_MD5,16,0},
|
{27, KEX_DH, SIG_NONE, ENC_3DES, 8, 192, 192, DIG_MD5, 16, 0},
|
||||||
// Missing: 44-46
|
// Missing: 44-46
|
||||||
{47,KEX_RSA,SIG_RSA,ENC_AES128,16,128,128,DIG_SHA,20,0},
|
{47, KEX_RSA, SIG_RSA, ENC_AES128, 16, 128, 128, DIG_SHA, 20, 0},
|
||||||
{48,KEX_DH,SIG_DSS,ENC_AES128,16,128,128,DIG_SHA,20,0},
|
{48, KEX_DH, SIG_DSS, ENC_AES128, 16, 128, 128, DIG_SHA, 20, 0},
|
||||||
{49,KEX_DH,SIG_RSA,ENC_AES128,16,128,128,DIG_SHA,20,0},
|
{49, KEX_DH, SIG_RSA, ENC_AES128, 16, 128, 128, DIG_SHA, 20, 0},
|
||||||
{50,KEX_DH,SIG_DSS,ENC_AES128,16,128,128,DIG_SHA,20,0},
|
{50, KEX_DH, SIG_DSS, ENC_AES128, 16, 128, 128, DIG_SHA, 20, 0},
|
||||||
{51,KEX_DH,SIG_RSA,ENC_AES128,16,128,128,DIG_SHA,20,0},
|
{51, KEX_DH, SIG_RSA, ENC_AES128, 16, 128, 128, DIG_SHA, 20, 0},
|
||||||
{52,KEX_DH,SIG_NONE,ENC_AES128,16,128,128,DIG_SHA,20,0},
|
{52, KEX_DH, SIG_NONE, ENC_AES128, 16, 128, 128, DIG_SHA, 20, 0},
|
||||||
{53,KEX_RSA,SIG_RSA,ENC_AES256,16,256,256,DIG_SHA,20,0},
|
{53, KEX_RSA, SIG_RSA, ENC_AES256, 16, 256, 256, DIG_SHA, 20, 0},
|
||||||
{54,KEX_DH,SIG_DSS,ENC_AES256,16,256,256,DIG_SHA,20,0},
|
{54, KEX_DH, SIG_DSS, ENC_AES256, 16, 256, 256, DIG_SHA, 20, 0},
|
||||||
{55,KEX_DH,SIG_RSA,ENC_AES256,16,256,256,DIG_SHA,20,0},
|
{55, KEX_DH, SIG_RSA, ENC_AES256, 16, 256, 256, DIG_SHA, 20, 0},
|
||||||
{56,KEX_DH,SIG_DSS,ENC_AES256,16,256,256,DIG_SHA,20,0},
|
{56, KEX_DH, SIG_DSS, ENC_AES256, 16, 256, 256, DIG_SHA, 20, 0},
|
||||||
{57,KEX_DH,SIG_RSA,ENC_AES256,16,256,256,DIG_SHA,20,0},
|
{57, KEX_DH, SIG_RSA, ENC_AES256, 16, 256, 256, DIG_SHA, 20, 0},
|
||||||
{58,KEX_DH,SIG_NONE,ENC_AES256,16,256,256,DIG_SHA,20,0},
|
{58, KEX_DH, SIG_NONE, ENC_AES256, 16, 256, 256, DIG_SHA, 20, 0},
|
||||||
{59,KEX_RSA,SIG_RSA,ENC_NULL,0,0,0,DIG_SHA256,32,0},
|
{59, KEX_RSA, SIG_RSA, ENC_NULL, 0, 0, 0, DIG_SHA256, 32, 0},
|
||||||
{60,KEX_RSA,SIG_RSA,ENC_AES128,16,128,128,DIG_SHA256,32,0},
|
{60, KEX_RSA, SIG_RSA, ENC_AES128, 16, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{61,KEX_RSA,SIG_RSA,ENC_AES256,16,256,256,DIG_SHA256,32,0},
|
{61, KEX_RSA, SIG_RSA, ENC_AES256, 16, 256, 256, DIG_SHA256, 32, 0},
|
||||||
{62,KEX_DH,SIG_DSS,ENC_AES128,16,128,128,DIG_SHA256,32,0},
|
{62, KEX_DH, SIG_DSS, ENC_AES128, 16, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{63,KEX_DH,SIG_RSA,ENC_AES128,16,128,128,DIG_SHA256,32,0},
|
{63, KEX_DH, SIG_RSA, ENC_AES128, 16, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{64,KEX_DH,SIG_DSS,ENC_AES128,16,128,128,DIG_SHA256,32,0},
|
{64, KEX_DH, SIG_DSS, ENC_AES128, 16, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{65,KEX_RSA,SIG_RSA,ENC_CAMELLIA128,16,128,128,DIG_SHA,20,0},
|
{65, KEX_RSA, SIG_RSA, ENC_CAMELLIA128, 16, 128, 128, DIG_SHA, 20, 0},
|
||||||
{66,KEX_DH,SIG_DSS,ENC_CAMELLIA128,16,128,128,DIG_SHA,20,0},
|
{66, KEX_DH, SIG_DSS, ENC_CAMELLIA128, 16, 128, 128, DIG_SHA, 20, 0},
|
||||||
{67,KEX_DH,SIG_RSA,ENC_CAMELLIA128,16,128,128,DIG_SHA,20,0},
|
{67, KEX_DH, SIG_RSA, ENC_CAMELLIA128, 16, 128, 128, DIG_SHA, 20, 0},
|
||||||
{68,KEX_DH,SIG_DSS,ENC_CAMELLIA128,16,128,128,DIG_SHA,20,0},
|
{68, KEX_DH, SIG_DSS, ENC_CAMELLIA128, 16, 128, 128, DIG_SHA, 20, 0},
|
||||||
{69,KEX_DH,SIG_RSA,ENC_CAMELLIA128,16,128,128,DIG_SHA,20,0},
|
{69, KEX_DH, SIG_RSA, ENC_CAMELLIA128, 16, 128, 128, DIG_SHA, 20, 0},
|
||||||
{70,KEX_DH,SIG_NONE,ENC_CAMELLIA128,16,128,128,DIG_SHA,20,0},
|
{70, KEX_DH, SIG_NONE, ENC_CAMELLIA128, 16, 128, 128, DIG_SHA, 20, 0},
|
||||||
{96,KEX_RSA,SIG_RSA,ENC_RC4,1,128,56,DIG_MD5,16,1},
|
{96, KEX_RSA, SIG_RSA, ENC_RC4, 1, 128, 56, DIG_MD5, 16, 1},
|
||||||
{97,KEX_RSA,SIG_RSA,ENC_RC2,1,128,56,DIG_MD5,16,1},
|
{97, KEX_RSA, SIG_RSA, ENC_RC2, 1, 128, 56, DIG_MD5, 16, 1},
|
||||||
{98,KEX_RSA,SIG_RSA,ENC_DES,8,64,64,DIG_SHA,20,1},
|
{98, KEX_RSA, SIG_RSA, ENC_DES, 8, 64, 64, DIG_SHA, 20, 1},
|
||||||
{99,KEX_DH,SIG_DSS,ENC_DES,8,64,64,DIG_SHA,20,1},
|
{99, KEX_DH, SIG_DSS, ENC_DES, 8, 64, 64, DIG_SHA, 20, 1},
|
||||||
{100,KEX_RSA,SIG_RSA,ENC_RC4,1,128,56,DIG_SHA,20,1},
|
{100, KEX_RSA, SIG_RSA, ENC_RC4, 1, 128, 56, DIG_SHA, 20, 1},
|
||||||
{101,KEX_DH,SIG_DSS,ENC_RC4,1,128,56,DIG_SHA,20,1},
|
{101, KEX_DH, SIG_DSS, ENC_RC4, 1, 128, 56, DIG_SHA, 20, 1},
|
||||||
{102,KEX_DH,SIG_DSS,ENC_RC4,1,128,128,DIG_SHA,20,0},
|
{102, KEX_DH, SIG_DSS, ENC_RC4, 1, 128, 128, DIG_SHA, 20, 0},
|
||||||
{103,KEX_DH,SIG_RSA,ENC_AES128,16,128,128,DIG_SHA256,32,0},
|
{103, KEX_DH, SIG_RSA, ENC_AES128, 16, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{104,KEX_DH,SIG_DSS,ENC_AES256,16,256,256,DIG_SHA256,32,0},
|
{104, KEX_DH, SIG_DSS, ENC_AES256, 16, 256, 256, DIG_SHA256, 32, 0},
|
||||||
{105,KEX_DH,SIG_RSA,ENC_AES256,16,256,256,DIG_SHA256,32,0},
|
{105, KEX_DH, SIG_RSA, ENC_AES256, 16, 256, 256, DIG_SHA256, 32, 0},
|
||||||
{106,KEX_DH,SIG_DSS,ENC_AES256,16,256,256,DIG_SHA256,32,0},
|
{106, KEX_DH, SIG_DSS, ENC_AES256, 16, 256, 256, DIG_SHA256, 32, 0},
|
||||||
{107,KEX_DH,SIG_RSA,ENC_AES256,16,256,256,DIG_SHA256,32,0},
|
{107, KEX_DH, SIG_RSA, ENC_AES256, 16, 256, 256, DIG_SHA256, 32, 0},
|
||||||
{108,KEX_DH,SIG_NONE,ENC_AES128,16,128,128,DIG_SHA256,32,0},
|
{108, KEX_DH, SIG_NONE, ENC_AES128, 16, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{109,KEX_DH,SIG_NONE,ENC_AES256,16,256,256,DIG_SHA256,32,0},
|
{109, KEX_DH, SIG_NONE, ENC_AES256, 16, 256, 256, DIG_SHA256, 32, 0},
|
||||||
{132,KEX_RSA,SIG_RSA,ENC_CAMELLIA256,16,256,256,DIG_SHA,20,0},
|
{132, KEX_RSA, SIG_RSA, ENC_CAMELLIA256, 16, 256, 256, DIG_SHA, 20, 0},
|
||||||
{133,KEX_DH,SIG_DSS,ENC_CAMELLIA256,16,256,256,DIG_SHA,20,0},
|
{133, KEX_DH, SIG_DSS, ENC_CAMELLIA256, 16, 256, 256, DIG_SHA, 20, 0},
|
||||||
{134,KEX_DH,SIG_RSA,ENC_CAMELLIA256,16,256,256,DIG_SHA,20,0},
|
{134, KEX_DH, SIG_RSA, ENC_CAMELLIA256, 16, 256, 256, DIG_SHA, 20, 0},
|
||||||
{135,KEX_DH,SIG_DSS,ENC_CAMELLIA256,16,256,256,DIG_SHA,20,0},
|
{135, KEX_DH, SIG_DSS, ENC_CAMELLIA256, 16, 256, 256, DIG_SHA, 20, 0},
|
||||||
{136,KEX_DH,SIG_RSA,ENC_CAMELLIA256,16,256,256,DIG_SHA,20,0},
|
{136, KEX_DH, SIG_RSA, ENC_CAMELLIA256, 16, 256, 256, DIG_SHA, 20, 0},
|
||||||
{137,KEX_DH,SIG_NONE,ENC_CAMELLIA256,16,256,256,DIG_SHA,20,0},
|
{137, KEX_DH, SIG_NONE, ENC_CAMELLIA256, 16, 256, 256, DIG_SHA, 20, 0},
|
||||||
// Missing: 138-149
|
// Missing: 138-149
|
||||||
{150,KEX_RSA,SIG_RSA,ENC_SEED,16,128,128,DIG_SHA,20,0},
|
{150, KEX_RSA, SIG_RSA, ENC_SEED, 16, 128, 128, DIG_SHA, 20, 0},
|
||||||
{151,KEX_DH,SIG_DSS,ENC_SEED,16,128,128,DIG_SHA,20,0},
|
{151, KEX_DH, SIG_DSS, ENC_SEED, 16, 128, 128, DIG_SHA, 20, 0},
|
||||||
{152,KEX_DH,SIG_RSA,ENC_SEED,16,128,128,DIG_SHA,20,0},
|
{152, KEX_DH, SIG_RSA, ENC_SEED, 16, 128, 128, DIG_SHA, 20, 0},
|
||||||
{153,KEX_DH,SIG_DSS,ENC_SEED,16,128,128,DIG_SHA,20,0},
|
{153, KEX_DH, SIG_DSS, ENC_SEED, 16, 128, 128, DIG_SHA, 20, 0},
|
||||||
{154,KEX_DH,SIG_RSA,ENC_SEED,16,128,128,DIG_SHA,20,0},
|
{154, KEX_DH, SIG_RSA, ENC_SEED, 16, 128, 128, DIG_SHA, 20, 0},
|
||||||
{155,KEX_DH,SIG_NONE,ENC_SEED,16,128,128,DIG_SHA,20,0},
|
{155, KEX_DH, SIG_NONE, ENC_SEED, 16, 128, 128, DIG_SHA, 20, 0},
|
||||||
{156,KEX_RSA,SIG_RSA,ENC_AES128_GCM,4,128,128,DIG_SHA256,32,0},
|
{156, KEX_RSA, SIG_RSA, ENC_AES128_GCM, 4, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{157,KEX_RSA,SIG_RSA,ENC_AES256_GCM,4,256,256,DIG_SHA384,48,0},
|
{157, KEX_RSA, SIG_RSA, ENC_AES256_GCM, 4, 256, 256, DIG_SHA384, 48, 0},
|
||||||
{158,KEX_DH,SIG_RSA,ENC_AES128_GCM,4,128,128,DIG_SHA256,32,0},
|
{158, KEX_DH, SIG_RSA, ENC_AES128_GCM, 4, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{159,KEX_DH,SIG_RSA,ENC_AES256_GCM,4,256,256,DIG_SHA384,48,0},
|
{159, KEX_DH, SIG_RSA, ENC_AES256_GCM, 4, 256, 256, DIG_SHA384, 48, 0},
|
||||||
{160,KEX_DH,SIG_RSA,ENC_AES128_GCM,4,128,128,DIG_SHA256,32,0},
|
{160, KEX_DH, SIG_RSA, ENC_AES128_GCM, 4, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{161,KEX_DH,SIG_RSA,ENC_AES256_GCM,4,256,256,DIG_SHA384,48,0},
|
{161, KEX_DH, SIG_RSA, ENC_AES256_GCM, 4, 256, 256, DIG_SHA384, 48, 0},
|
||||||
{162,KEX_DH,SIG_DSS,ENC_AES128_GCM,4,128,128,DIG_SHA256,32,0},
|
{162, KEX_DH, SIG_DSS, ENC_AES128_GCM, 4, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{163,KEX_DH,SIG_DSS,ENC_AES256_GCM,4,256,256,DIG_SHA384,48,0},
|
{163, KEX_DH, SIG_DSS, ENC_AES256_GCM, 4, 256, 256, DIG_SHA384, 48, 0},
|
||||||
{164,KEX_DH,SIG_DSS,ENC_AES128_GCM,4,128,128,DIG_SHA256,32,0},
|
{164, KEX_DH, SIG_DSS, ENC_AES128_GCM, 4, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{165,KEX_DH,SIG_DSS,ENC_AES256_GCM,4,256,256,DIG_SHA384,48,0},
|
{165, KEX_DH, SIG_DSS, ENC_AES256_GCM, 4, 256, 256, DIG_SHA384, 48, 0},
|
||||||
{166,KEX_DH,SIG_NONE,ENC_AES128_GCM,4,128,128,DIG_SHA256,32,0},
|
{166, KEX_DH, SIG_NONE, ENC_AES128_GCM, 4, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{167,KEX_DH,SIG_NONE,ENC_AES256_GCM,4,256,256,DIG_SHA384,48,0},
|
{167, KEX_DH, SIG_NONE, ENC_AES256_GCM, 4, 256, 256, DIG_SHA384, 48, 0},
|
||||||
// Missing: 168-185
|
// Missing: 168-185
|
||||||
{186,KEX_RSA,SIG_RSA,ENC_CAMELLIA128,16,128,128,DIG_SHA256,32,0},
|
{186, KEX_RSA, SIG_RSA, ENC_CAMELLIA128, 16, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{187,KEX_DH,SIG_DSS,ENC_CAMELLIA128,16,128,128,DIG_SHA256,32,0},
|
{187, KEX_DH, SIG_DSS, ENC_CAMELLIA128, 16, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{188,KEX_DH,SIG_RSA,ENC_CAMELLIA128,16,128,128,DIG_SHA256,32,0},
|
{188, KEX_DH, SIG_RSA, ENC_CAMELLIA128, 16, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{189,KEX_DH,SIG_DSS,ENC_CAMELLIA128,16,128,128,DIG_SHA256,32,0},
|
{189, KEX_DH, SIG_DSS, ENC_CAMELLIA128, 16, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{190,KEX_DH,SIG_RSA,ENC_CAMELLIA128,16,128,128,DIG_SHA256,32,0},
|
{190, KEX_DH, SIG_RSA, ENC_CAMELLIA128, 16, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{191,KEX_DH,SIG_NONE,ENC_CAMELLIA128,16,128,128,DIG_SHA256,32,0},
|
{191, KEX_DH, SIG_NONE, ENC_CAMELLIA128, 16, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{192,KEX_RSA,SIG_RSA,ENC_CAMELLIA256,16,256,256,DIG_SHA256,32,0},
|
{192, KEX_RSA, SIG_RSA, ENC_CAMELLIA256, 16, 256, 256, DIG_SHA256, 32, 0},
|
||||||
{193,KEX_DH,SIG_DSS,ENC_CAMELLIA256,16,256,256,DIG_SHA256,32,0},
|
{193, KEX_DH, SIG_DSS, ENC_CAMELLIA256, 16, 256, 256, DIG_SHA256, 32, 0},
|
||||||
{194,KEX_DH,SIG_RSA,ENC_CAMELLIA256,16,256,256,DIG_SHA256,32,0},
|
{194, KEX_DH, SIG_RSA, ENC_CAMELLIA256, 16, 256, 256, DIG_SHA256, 32, 0},
|
||||||
{195,KEX_DH,SIG_DSS,ENC_CAMELLIA256,16,256,256,DIG_SHA256,32,0},
|
{195, KEX_DH, SIG_DSS, ENC_CAMELLIA256, 16, 256, 256, DIG_SHA256, 32, 0},
|
||||||
{196,KEX_DH,SIG_RSA,ENC_CAMELLIA256,16,256,256,DIG_SHA256,32,0},
|
{196, KEX_DH, SIG_RSA, ENC_CAMELLIA256, 16, 256, 256, DIG_SHA256, 32, 0},
|
||||||
{197,KEX_DH,SIG_NONE,ENC_CAMELLIA256,16,256,256,DIG_SHA256,32,0},
|
{197, KEX_DH, SIG_NONE, ENC_CAMELLIA256, 16, 256, 256, DIG_SHA256, 32, 0},
|
||||||
{4865,KEX_DH,SIG_NONE,ENC_AES128_GCM,16,128,128,DIG_SHA256,32,0},
|
{4865, KEX_DH, SIG_NONE, ENC_AES128_GCM, 16, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{4866,KEX_DH,SIG_NONE,ENC_AES256_GCM,16,256,256,DIG_SHA384,48,0},
|
{4866, KEX_DH, SIG_NONE, ENC_AES256_GCM, 16, 256, 256, DIG_SHA384, 48, 0},
|
||||||
{4867,KEX_DH,SIG_NONE,ENC_CHACHA20_POLY1305,64,256,256,DIG_SHA256,32,0},
|
{4867, KEX_DH, SIG_NONE, ENC_CHACHA20_POLY1305, 64, 256, 256, DIG_SHA256,
|
||||||
{4868,KEX_DH,SIG_NONE,ENC_AES128_CCM,16,128,128,DIG_SHA256,32,0},
|
32, 0},
|
||||||
{4869,KEX_DH,SIG_NONE,ENC_AES128_CCM_8,16,128,128,DIG_SHA256,32,0},
|
{4868, KEX_DH, SIG_NONE, ENC_AES128_CCM, 16, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{49153,KEX_DH,SIG_DSS,ENC_NULL,0,0,0,DIG_SHA,20,0},
|
{4869, KEX_DH, SIG_NONE, ENC_AES128_CCM_8, 16, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{49154,KEX_DH,SIG_DSS,ENC_RC4,1,128,128,DIG_SHA,20,0},
|
{49153, KEX_DH, SIG_DSS, ENC_NULL, 0, 0, 0, DIG_SHA, 20, 0},
|
||||||
{49155,KEX_DH,SIG_DSS,ENC_3DES,8,192,192,DIG_SHA,20,0},
|
{49154, KEX_DH, SIG_DSS, ENC_RC4, 1, 128, 128, DIG_SHA, 20, 0},
|
||||||
{49156,KEX_DH,SIG_DSS,ENC_AES128,16,128,128,DIG_SHA,20,0},
|
{49155, KEX_DH, SIG_DSS, ENC_3DES, 8, 192, 192, DIG_SHA, 20, 0},
|
||||||
{49157,KEX_DH,SIG_DSS,ENC_AES256,16,256,256,DIG_SHA,20,0},
|
{49156, KEX_DH, SIG_DSS, ENC_AES128, 16, 128, 128, DIG_SHA, 20, 0},
|
||||||
{49158,KEX_DH,SIG_DSS,ENC_NULL,0,0,0,DIG_SHA,20,0},
|
{49157, KEX_DH, SIG_DSS, ENC_AES256, 16, 256, 256, DIG_SHA, 20, 0},
|
||||||
{49159,KEX_DH,SIG_DSS,ENC_RC4,1,128,128,DIG_SHA,20,0},
|
{49158, KEX_DH, SIG_DSS, ENC_NULL, 0, 0, 0, DIG_SHA, 20, 0},
|
||||||
{49160,KEX_DH,SIG_DSS,ENC_3DES,8,192,192,DIG_SHA,20,0},
|
{49159, KEX_DH, SIG_DSS, ENC_RC4, 1, 128, 128, DIG_SHA, 20, 0},
|
||||||
{49161,KEX_DH,SIG_DSS,ENC_AES128,16,128,128,DIG_SHA,20,0},
|
{49160, KEX_DH, SIG_DSS, ENC_3DES, 8, 192, 192, DIG_SHA, 20, 0},
|
||||||
{49162,KEX_DH,SIG_DSS,ENC_AES256,16,256,256,DIG_SHA,20,0},
|
{49161, KEX_DH, SIG_DSS, ENC_AES128, 16, 128, 128, DIG_SHA, 20, 0},
|
||||||
{49163,KEX_DH,SIG_RSA,ENC_NULL,0,0,0,DIG_SHA,20,0},
|
{49162, KEX_DH, SIG_DSS, ENC_AES256, 16, 256, 256, DIG_SHA, 20, 0},
|
||||||
{49164,KEX_DH,SIG_RSA,ENC_RC4,1,128,128,DIG_SHA,20,0},
|
{49163, KEX_DH, SIG_RSA, ENC_NULL, 0, 0, 0, DIG_SHA, 20, 0},
|
||||||
{49165,KEX_DH,SIG_RSA,ENC_3DES,8,192,192,DIG_SHA,20,0},
|
{49164, KEX_DH, SIG_RSA, ENC_RC4, 1, 128, 128, DIG_SHA, 20, 0},
|
||||||
{49166,KEX_DH,SIG_RSA,ENC_AES128,16,128,128,DIG_SHA,20,0},
|
{49165, KEX_DH, SIG_RSA, ENC_3DES, 8, 192, 192, DIG_SHA, 20, 0},
|
||||||
{49167,KEX_DH,SIG_RSA,ENC_AES256,16,256,256,DIG_SHA,20,0},
|
{49166, KEX_DH, SIG_RSA, ENC_AES128, 16, 128, 128, DIG_SHA, 20, 0},
|
||||||
{49168,KEX_DH,SIG_RSA,ENC_NULL,0,0,0,DIG_SHA,20,0},
|
{49167, KEX_DH, SIG_RSA, ENC_AES256, 16, 256, 256, DIG_SHA, 20, 0},
|
||||||
{49169,KEX_DH,SIG_RSA,ENC_RC4,1,128,128,DIG_SHA,20,0},
|
{49168, KEX_DH, SIG_RSA, ENC_NULL, 0, 0, 0, DIG_SHA, 20, 0},
|
||||||
{49170,KEX_DH,SIG_RSA,ENC_3DES,8,192,192,DIG_SHA,20,0},
|
{49169, KEX_DH, SIG_RSA, ENC_RC4, 1, 128, 128, DIG_SHA, 20, 0},
|
||||||
{49171,KEX_DH,SIG_RSA,ENC_AES128,16,128,128,DIG_SHA,20,0},
|
{49170, KEX_DH, SIG_RSA, ENC_3DES, 8, 192, 192, DIG_SHA, 20, 0},
|
||||||
{49172,KEX_DH,SIG_RSA,ENC_AES256,16,256,256,DIG_SHA,20,0},
|
{49171, KEX_DH, SIG_RSA, ENC_AES128, 16, 128, 128, DIG_SHA, 20, 0},
|
||||||
{49173,KEX_DH,SIG_NONE,ENC_NULL,0,0,0,DIG_SHA,20,0},
|
{49172, KEX_DH, SIG_RSA, ENC_AES256, 16, 256, 256, DIG_SHA, 20, 0},
|
||||||
{49174,KEX_DH,SIG_NONE,ENC_RC4,1,128,128,DIG_SHA,20,0},
|
{49173, KEX_DH, SIG_NONE, ENC_NULL, 0, 0, 0, DIG_SHA, 20, 0},
|
||||||
{49175,KEX_DH,SIG_NONE,ENC_3DES,8,192,192,DIG_SHA,20,0},
|
{49174, KEX_DH, SIG_NONE, ENC_RC4, 1, 128, 128, DIG_SHA, 20, 0},
|
||||||
{49176,KEX_DH,SIG_NONE,ENC_AES128,16,128,128,DIG_SHA,20,0},
|
{49175, KEX_DH, SIG_NONE, ENC_3DES, 8, 192, 192, DIG_SHA, 20, 0},
|
||||||
{49177,KEX_DH,SIG_NONE,ENC_AES256,16,256,256,DIG_SHA,20,0},
|
{49176, KEX_DH, SIG_NONE, ENC_AES128, 16, 128, 128, DIG_SHA, 20, 0},
|
||||||
{49187,KEX_DH,SIG_DSS,ENC_AES128,16,128,128,DIG_SHA256,32,0},
|
{49177, KEX_DH, SIG_NONE, ENC_AES256, 16, 256, 256, DIG_SHA, 20, 0},
|
||||||
{49188,KEX_DH,SIG_DSS,ENC_AES256,16,256,256,DIG_SHA384,48,0},
|
{49187, KEX_DH, SIG_DSS, ENC_AES128, 16, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{49189,KEX_DH,SIG_DSS,ENC_AES128,16,128,128,DIG_SHA256,32,0},
|
{49188, KEX_DH, SIG_DSS, ENC_AES256, 16, 256, 256, DIG_SHA384, 48, 0},
|
||||||
{49190,KEX_DH,SIG_DSS,ENC_AES256,16,256,256,DIG_SHA384,48,0},
|
{49189, KEX_DH, SIG_DSS, ENC_AES128, 16, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{49191,KEX_DH,SIG_RSA,ENC_AES128,16,128,128,DIG_SHA256,32,0},
|
{49190, KEX_DH, SIG_DSS, ENC_AES256, 16, 256, 256, DIG_SHA384, 48, 0},
|
||||||
{49192,KEX_DH,SIG_RSA,ENC_AES256,16,256,256,DIG_SHA384,48,0},
|
{49191, KEX_DH, SIG_RSA, ENC_AES128, 16, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{49193,KEX_DH,SIG_RSA,ENC_AES128,16,128,128,DIG_SHA256,32,0},
|
{49192, KEX_DH, SIG_RSA, ENC_AES256, 16, 256, 256, DIG_SHA384, 48, 0},
|
||||||
{49194,KEX_DH,SIG_RSA,ENC_AES256,16,256,256,DIG_SHA384,48,0},
|
{49193, KEX_DH, SIG_RSA, ENC_AES128, 16, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{49195,KEX_DH,SIG_DSS,ENC_AES128_GCM,4,128,128,DIG_SHA256,32,0},
|
{49194, KEX_DH, SIG_RSA, ENC_AES256, 16, 256, 256, DIG_SHA384, 48, 0},
|
||||||
{49196,KEX_DH,SIG_DSS,ENC_AES256_GCM,4,256,256,DIG_SHA384,48,0},
|
{49195, KEX_DH, SIG_DSS, ENC_AES128_GCM, 4, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{49197,KEX_DH,SIG_DSS,ENC_AES128_GCM,4,128,128,DIG_SHA256,32,0},
|
{49196, KEX_DH, SIG_DSS, ENC_AES256_GCM, 4, 256, 256, DIG_SHA384, 48, 0},
|
||||||
{49198,KEX_DH,SIG_DSS,ENC_AES256_GCM,4,256,256,DIG_SHA384,48,0},
|
{49197, KEX_DH, SIG_DSS, ENC_AES128_GCM, 4, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{49199,KEX_DH,SIG_RSA,ENC_AES128_GCM,4,128,128,DIG_SHA256,32,0},
|
{49198, KEX_DH, SIG_DSS, ENC_AES256_GCM, 4, 256, 256, DIG_SHA384, 48, 0},
|
||||||
{49200,KEX_DH,SIG_RSA,ENC_AES256_GCM,4,256,256,DIG_SHA384,48,0},
|
{49199, KEX_DH, SIG_RSA, ENC_AES128_GCM, 4, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{49201,KEX_DH,SIG_RSA,ENC_AES128_GCM,4,128,128,DIG_SHA256,32,0},
|
{49200, KEX_DH, SIG_RSA, ENC_AES256_GCM, 4, 256, 256, DIG_SHA384, 48, 0},
|
||||||
{49202,KEX_DH,SIG_RSA,ENC_AES256_GCM,4,256,256,DIG_SHA384,48,0},
|
{49201, KEX_DH, SIG_RSA, ENC_AES128_GCM, 4, 128, 128, DIG_SHA256, 32, 0},
|
||||||
|
{49202, KEX_DH, SIG_RSA, ENC_AES256_GCM, 4, 256, 256, DIG_SHA384, 48, 0},
|
||||||
// Missing: 49203-49211
|
// Missing: 49203-49211
|
||||||
{49266,KEX_DH,SIG_DSS,ENC_CAMELLIA128,16,128,128,DIG_SHA256,32,0},
|
{49266, KEX_DH, SIG_DSS, ENC_CAMELLIA128, 16, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{49267,KEX_DH,SIG_DSS,ENC_CAMELLIA256,16,256,256,DIG_SHA256,48,0},
|
{49267, KEX_DH, SIG_DSS, ENC_CAMELLIA256, 16, 256, 256, DIG_SHA256, 48, 0},
|
||||||
{49268,KEX_DH,SIG_DSS,ENC_CAMELLIA128,16,128,128,DIG_SHA256,32,0},
|
{49268, KEX_DH, SIG_DSS, ENC_CAMELLIA128, 16, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{49269,KEX_DH,SIG_DSS,ENC_CAMELLIA256,16,256,256,DIG_SHA256,48,0},
|
{49269, KEX_DH, SIG_DSS, ENC_CAMELLIA256, 16, 256, 256, DIG_SHA256, 48, 0},
|
||||||
{49270,KEX_DH,SIG_RSA,ENC_CAMELLIA128,16,128,128,DIG_SHA256,32,0},
|
{49270, KEX_DH, SIG_RSA, ENC_CAMELLIA128, 16, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{49271,KEX_DH,SIG_RSA,ENC_CAMELLIA256,16,256,256,DIG_SHA256,48,0},
|
{49271, KEX_DH, SIG_RSA, ENC_CAMELLIA256, 16, 256, 256, DIG_SHA256, 48, 0},
|
||||||
{49272,KEX_DH,SIG_RSA,ENC_CAMELLIA128,16,128,128,DIG_SHA256,32,0},
|
{49272, KEX_DH, SIG_RSA, ENC_CAMELLIA128, 16, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{49273,KEX_DH,SIG_RSA,ENC_CAMELLIA256,16,256,256,DIG_SHA256,48,0},
|
{49273, KEX_DH, SIG_RSA, ENC_CAMELLIA256, 16, 256, 256, DIG_SHA256, 48, 0},
|
||||||
{49274,KEX_RSA,SIG_RSA,ENC_CAMELLIA128,4,128,128,DIG_SHA256,32,0},
|
{49274, KEX_RSA, SIG_RSA, ENC_CAMELLIA128, 4, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{49275,KEX_RSA,SIG_RSA,ENC_CAMELLIA256,4,256,256,DIG_SHA384,48,0},
|
{49275, KEX_RSA, SIG_RSA, ENC_CAMELLIA256, 4, 256, 256, DIG_SHA384, 48, 0},
|
||||||
{49276,KEX_DH,SIG_RSA,ENC_CAMELLIA128,4,128,128,DIG_SHA256,32,0},
|
{49276, KEX_DH, SIG_RSA, ENC_CAMELLIA128, 4, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{49277,KEX_DH,SIG_RSA,ENC_CAMELLIA256,4,256,256,DIG_SHA384,48,0},
|
{49277, KEX_DH, SIG_RSA, ENC_CAMELLIA256, 4, 256, 256, DIG_SHA384, 48, 0},
|
||||||
{49278,KEX_DH,SIG_RSA,ENC_CAMELLIA128,4,128,128,DIG_SHA256,32,0},
|
{49278, KEX_DH, SIG_RSA, ENC_CAMELLIA128, 4, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{49279,KEX_DH,SIG_RSA,ENC_CAMELLIA256,4,256,256,DIG_SHA384,48,0},
|
{49279, KEX_DH, SIG_RSA, ENC_CAMELLIA256, 4, 256, 256, DIG_SHA384, 48, 0},
|
||||||
{49280,KEX_DH,SIG_DSS,ENC_CAMELLIA128,4,128,128,DIG_SHA256,32,0},
|
{49280, KEX_DH, SIG_DSS, ENC_CAMELLIA128, 4, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{49281,KEX_DH,SIG_DSS,ENC_CAMELLIA256,4,256,256,DIG_SHA384,48,0},
|
{49281, KEX_DH, SIG_DSS, ENC_CAMELLIA256, 4, 256, 256, DIG_SHA384, 48, 0},
|
||||||
{49282,KEX_DH,SIG_DSS,ENC_CAMELLIA128,4,128,128,DIG_SHA256,32,0},
|
{49282, KEX_DH, SIG_DSS, ENC_CAMELLIA128, 4, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{49283,KEX_DH,SIG_DSS,ENC_CAMELLIA256,4,256,256,DIG_SHA384,48,0},
|
{49283, KEX_DH, SIG_DSS, ENC_CAMELLIA256, 4, 256, 256, DIG_SHA384, 48, 0},
|
||||||
{49284,KEX_DH,SIG_NONE,ENC_CAMELLIA128,4,128,128,DIG_SHA256,32,0},
|
{49284, KEX_DH, SIG_NONE, ENC_CAMELLIA128, 4, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{49285,KEX_DH,SIG_NONE,ENC_CAMELLIA256,4,256,256,DIG_SHA384,48,0},
|
{49285, KEX_DH, SIG_NONE, ENC_CAMELLIA256, 4, 256, 256, DIG_SHA384, 48, 0},
|
||||||
{49286,KEX_DH,SIG_DSS,ENC_CAMELLIA128,4,128,128,DIG_SHA256,32,0},
|
{49286, KEX_DH, SIG_DSS, ENC_CAMELLIA128, 4, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{49287,KEX_DH,SIG_DSS,ENC_CAMELLIA256,4,256,256,DIG_SHA384,48,0},
|
{49287, KEX_DH, SIG_DSS, ENC_CAMELLIA256, 4, 256, 256, DIG_SHA384, 48, 0},
|
||||||
{49288,KEX_DH,SIG_DSS,ENC_CAMELLIA128,4,128,128,DIG_SHA256,32,0},
|
{49288, KEX_DH, SIG_DSS, ENC_CAMELLIA128, 4, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{49289,KEX_DH,SIG_DSS,ENC_CAMELLIA256,4,256,256,DIG_SHA384,48,0},
|
{49289, KEX_DH, SIG_DSS, ENC_CAMELLIA256, 4, 256, 256, DIG_SHA384, 48, 0},
|
||||||
{49290,KEX_DH,SIG_RSA,ENC_CAMELLIA128,4,128,128,DIG_SHA256,32,0},
|
{49290, KEX_DH, SIG_RSA, ENC_CAMELLIA128, 4, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{49291,KEX_DH,SIG_RSA,ENC_CAMELLIA256,4,256,256,DIG_SHA384,48,0},
|
{49291, KEX_DH, SIG_RSA, ENC_CAMELLIA256, 4, 256, 256, DIG_SHA384, 48, 0},
|
||||||
{49292,KEX_DH,SIG_RSA,ENC_CAMELLIA128,4,128,128,DIG_SHA256,32,0},
|
{49292, KEX_DH, SIG_RSA, ENC_CAMELLIA128, 4, 128, 128, DIG_SHA256, 32, 0},
|
||||||
{49293,KEX_DH,SIG_RSA,ENC_CAMELLIA256,4,256,256,DIG_SHA384,48,0},
|
{49293, KEX_DH, SIG_RSA, ENC_CAMELLIA256, 4, 256, 256, DIG_SHA384, 48, 0},
|
||||||
// Missing: 49294-49307
|
// Missing: 49294-49307
|
||||||
{-1}
|
{-1}};
|
||||||
};
|
|
||||||
|
|
||||||
int
|
int ssl_find_cipher(int num, SSL_CipherSuite **cs) {
|
||||||
ssl_find_cipher (int num, SSL_CipherSuite **cs)
|
|
||||||
{
|
|
||||||
SSL_CipherSuite *c;
|
SSL_CipherSuite *c;
|
||||||
|
|
||||||
for(c=CipherSuites;c->number!=-1;c++){
|
for(c = CipherSuites; c->number != -1; c++) {
|
||||||
if(c->number==num){
|
if(c->number == num) {
|
||||||
*cs=c;
|
*cs = c;
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ERETURN(R_NOT_FOUND);
|
ERETURN(R_NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
3925
ssl/ssl.enums.c
3925
ssl/ssl.enums.c
File diff suppressed because it is too large
Load diff
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: ssl_analyze.c,v 1.8 2002/01/21 18:46:13 ekr Exp $
|
$Id: ssl_analyze.c,v 1.8 2002/01/21 18:46:13 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,7 +44,6 @@
|
||||||
ekr@rtfm.com Fri Jan 8 14:07:05 1999
|
ekr@rtfm.com Fri Jan 8 14:07:05 1999
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <json.h>
|
#include <json.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
@ -57,29 +57,39 @@
|
||||||
UINT4 SSL_print_flags = 1 | P_HT | P_HL;
|
UINT4 SSL_print_flags = 1 | P_HT | P_HL;
|
||||||
|
|
||||||
static int parse_ssl_flags PROTO_LIST((char *str));
|
static int parse_ssl_flags PROTO_LIST((char *str));
|
||||||
static int create_ssl_ctx PROTO_LIST((void *handle,proto_ctx **ctxp));
|
static int create_ssl_ctx PROTO_LIST((void *handle, proto_ctx **ctxp));
|
||||||
static int create_ssl_analyzer PROTO_LIST((void *handle,
|
static int create_ssl_analyzer PROTO_LIST((void *handle,
|
||||||
proto_ctx *ctx,tcp_conn *conn,proto_obj **objp,
|
proto_ctx *ctx,
|
||||||
struct sockaddr_storage *i_addr,u_short i_port,
|
tcp_conn *conn,
|
||||||
struct sockaddr_storage *r_addr,u_short r_port, struct timeval *base_time));
|
proto_obj **objp,
|
||||||
static int destroy_ssl_ctx PROTO_LIST((void *handle,proto_ctx **ctxp));
|
struct sockaddr_storage *i_addr,
|
||||||
static int destroy_ssl_analyzer PROTO_LIST((proto_obj **objp));
|
u_short i_port,
|
||||||
static int read_ssl_record PROTO_LIST((ssl_obj *obj,r_queue *q,segment *seg,
|
struct sockaddr_storage *r_addr,
|
||||||
int offset,segment **lastp,int *offsetp));
|
u_short r_port,
|
||||||
static int read_data PROTO_LIST((r_queue *q,segment *seg,int offset,
|
struct timeval *base_time));
|
||||||
segment **lastp,int *offsetp));
|
static int destroy_ssl_ctx PROTO_LIST((void *handle, proto_ctx **ctxp));
|
||||||
static int data_ssl_analyzer PROTO_LIST((proto_obj *_obj,segment *seg,
|
static int destroy_ssl_analyzer PROTO_LIST((proto_obj * *objp));
|
||||||
|
static int read_ssl_record PROTO_LIST((ssl_obj * obj,
|
||||||
|
r_queue *q,
|
||||||
|
segment *seg,
|
||||||
|
int offset,
|
||||||
|
segment **lastp,
|
||||||
|
int *offsetp));
|
||||||
|
static int read_data PROTO_LIST(
|
||||||
|
(r_queue * q, segment *seg, int offset, segment **lastp, int *offsetp));
|
||||||
|
static int data_ssl_analyzer PROTO_LIST((proto_obj * _obj,
|
||||||
|
segment *seg,
|
||||||
int direction));
|
int direction));
|
||||||
int close_ssl_analyzer PROTO_LIST((proto_obj *_obj,packet *p,int direction));
|
int close_ssl_analyzer PROTO_LIST((proto_obj * _obj, packet *p, int direction));
|
||||||
|
|
||||||
static int create_r_queue PROTO_LIST((r_queue **qp));
|
static int create_r_queue PROTO_LIST((r_queue * *qp));
|
||||||
|
|
||||||
static int free_r_queue PROTO_LIST((r_queue *q));
|
static int free_r_queue PROTO_LIST((r_queue * q));
|
||||||
static int print_ssl_record PROTO_LIST((ssl_obj *obj,int direction,
|
static int print_ssl_record PROTO_LIST(
|
||||||
segment *q,UCHAR *data,int len));
|
(ssl_obj * obj, int direction, segment *q, UCHAR *data, int len));
|
||||||
char *SSL_keyfile=0;
|
char *SSL_keyfile = 0;
|
||||||
char *SSL_password=0;
|
char *SSL_password = 0;
|
||||||
char *SSL_keylogfile=0;
|
char *SSL_keylogfile = 0;
|
||||||
|
|
||||||
#define NEGATE 0x800000
|
#define NEGATE 0x800000
|
||||||
|
|
||||||
|
@ -89,220 +99,167 @@ typedef struct {
|
||||||
UINT4 flag;
|
UINT4 flag;
|
||||||
} flag_struct;
|
} flag_struct;
|
||||||
|
|
||||||
flag_struct flags[]={
|
flag_struct flags[] = {
|
||||||
{
|
{
|
||||||
't',
|
't',
|
||||||
"ts",
|
"ts",
|
||||||
SSL_PRINT_TIMESTAMP,
|
SSL_PRINT_TIMESTAMP,
|
||||||
},
|
},
|
||||||
{
|
{'e', "tsa", SSL_PRINT_TIMESTAMP | SSL_PRINT_TIMESTAMP_ABSOLUTE},
|
||||||
'e',
|
{'x', "x", SSL_PRINT_HEXDUMP},
|
||||||
"tsa",
|
{'X', "X", SSL_PRINT_HEX_ONLY},
|
||||||
SSL_PRINT_TIMESTAMP|SSL_PRINT_TIMESTAMP_ABSOLUTE
|
{'r', "rh", SSL_PRINT_RECORD_HEADER},
|
||||||
},
|
{0, "ht", SSL_PRINT_HANDSHAKE_TYPE},
|
||||||
{
|
{0, "H", SSL_PRINT_HIGHLIGHTS},
|
||||||
'x',
|
{'A', "all", SSL_PRINT_ALL_FIELDS},
|
||||||
"x",
|
{0, "d", SSL_PRINT_DECODE},
|
||||||
SSL_PRINT_HEXDUMP
|
{'y', "nroff", SSL_PRINT_NROFF},
|
||||||
},
|
{'N', "asn", SSL_PRINT_DECODE_ASN1},
|
||||||
{
|
{0, "crypto", SSL_PRINT_CRYPTO},
|
||||||
'X',
|
{'d', "appdata", SSL_PRINT_APP_DATA},
|
||||||
"X",
|
{'q', "quiet", P_HL | NEGATE},
|
||||||
SSL_PRINT_HEX_ONLY
|
{0}};
|
||||||
},
|
|
||||||
{
|
|
||||||
'r',
|
|
||||||
"rh",
|
|
||||||
SSL_PRINT_RECORD_HEADER
|
|
||||||
},
|
|
||||||
{
|
|
||||||
0,
|
|
||||||
"ht",
|
|
||||||
SSL_PRINT_HANDSHAKE_TYPE
|
|
||||||
},
|
|
||||||
{
|
|
||||||
0,
|
|
||||||
"H",
|
|
||||||
SSL_PRINT_HIGHLIGHTS
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'A',
|
|
||||||
"all",
|
|
||||||
SSL_PRINT_ALL_FIELDS
|
|
||||||
},
|
|
||||||
{
|
|
||||||
0,
|
|
||||||
"d",
|
|
||||||
SSL_PRINT_DECODE
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'y',
|
|
||||||
"nroff",
|
|
||||||
SSL_PRINT_NROFF
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'N',
|
|
||||||
"asn",
|
|
||||||
SSL_PRINT_DECODE_ASN1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
0,
|
|
||||||
"crypto",
|
|
||||||
SSL_PRINT_CRYPTO
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'd',
|
|
||||||
"appdata",
|
|
||||||
SSL_PRINT_APP_DATA
|
|
||||||
},
|
|
||||||
{ 'q',
|
|
||||||
"quiet",
|
|
||||||
P_HL | NEGATE
|
|
||||||
},
|
|
||||||
{0}
|
|
||||||
};
|
|
||||||
|
|
||||||
int
|
int parse_ssl_flag(int flag) {
|
||||||
parse_ssl_flag (int flag)
|
|
||||||
{
|
|
||||||
flag_struct *fl;
|
flag_struct *fl;
|
||||||
|
|
||||||
for(fl=flags;fl->name;fl++){
|
for(fl = flags; fl->name; fl++) {
|
||||||
if(fl->ch==flag){
|
if(fl->ch == flag) {
|
||||||
if(fl->flag & NEGATE){
|
if(fl->flag & NEGATE) {
|
||||||
SSL_print_flags &= ~(fl->flag);
|
SSL_print_flags &= ~(fl->flag);
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
SSL_print_flags |= fl->flag;
|
SSL_print_flags |= fl->flag;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int parse_ssl_flags(char *str) {
|
||||||
parse_ssl_flags (char *str)
|
char *x, *y;
|
||||||
{
|
|
||||||
char *x,*y;
|
|
||||||
flag_struct *fl;
|
flag_struct *fl;
|
||||||
int bang;
|
int bang;
|
||||||
|
|
||||||
y=str;
|
y = str;
|
||||||
|
|
||||||
while((x=strtok(y,","))){
|
while((x = strtok(y, ","))) {
|
||||||
y=0;
|
y = 0;
|
||||||
|
|
||||||
if(*x=='!'){
|
if(*x == '!') {
|
||||||
bang=1;
|
bang = 1;
|
||||||
x++;
|
x++;
|
||||||
}
|
} else
|
||||||
|
bang = 0;
|
||||||
|
for(fl = flags; fl->name; fl++) {
|
||||||
|
if(!strcmp(x, fl->name)) {
|
||||||
|
if(!bang)
|
||||||
|
SSL_print_flags |= fl->flag;
|
||||||
else
|
else
|
||||||
bang=0;
|
SSL_print_flags &= ~fl->flag;
|
||||||
for(fl=flags;fl->name;fl++){
|
|
||||||
if(!strcmp(x,fl->name)){
|
|
||||||
if(!bang) SSL_print_flags |= fl->flag;
|
|
||||||
else SSL_print_flags &= ~fl->flag;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!fl->name){
|
if(!fl->name) {
|
||||||
fprintf(stderr,"SSL: Bad flag %s\n",x);
|
fprintf(stderr, "SSL: Bad flag %s\n", x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int create_ssl_ctx(void *handle, proto_ctx **ctxp) {
|
||||||
create_ssl_ctx (void *handle, proto_ctx **ctxp)
|
ssl_decode_ctx *ctx = 0;
|
||||||
{
|
int r, _status;
|
||||||
ssl_decode_ctx *ctx=0;
|
|
||||||
int r,_status;
|
|
||||||
|
|
||||||
if((r=ssl_decode_ctx_create(&ctx,SSL_keyfile,SSL_password,SSL_keylogfile)))
|
if((r = ssl_decode_ctx_create(&ctx, SSL_keyfile, SSL_password,
|
||||||
|
SSL_keylogfile)))
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
|
|
||||||
*ctxp=(proto_ctx *)ctx;
|
*ctxp = (proto_ctx *)ctx;
|
||||||
_status=0;
|
_status = 0;
|
||||||
abort:
|
abort:
|
||||||
return(_status);
|
return (_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int destroy_ssl_ctx(void *handle, proto_ctx **ctxp) {
|
||||||
destroy_ssl_ctx (void *handle, proto_ctx **ctxp)
|
ssl_decode_ctx *ctx = 0;
|
||||||
{
|
ctx = (ssl_decode_ctx *)*ctxp;
|
||||||
ssl_decode_ctx *ctx=0;
|
|
||||||
ctx=(ssl_decode_ctx *) *ctxp;
|
|
||||||
ssl_decode_ctx_destroy(&ctx);
|
ssl_decode_ctx_destroy(&ctx);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int create_ssl_analyzer(void *handle, proto_ctx *ctx, tcp_conn *conn,
|
static int create_ssl_analyzer(void *handle,
|
||||||
proto_obj **objp, struct sockaddr_storage *i_addr, u_short i_port, struct sockaddr_storage *r_addr,
|
proto_ctx *ctx,
|
||||||
u_short r_port, struct timeval *base_time)
|
tcp_conn *conn,
|
||||||
{
|
proto_obj **objp,
|
||||||
int r,_status;
|
struct sockaddr_storage *i_addr,
|
||||||
ssl_obj *obj=0;
|
u_short i_port,
|
||||||
|
struct sockaddr_storage *r_addr,
|
||||||
|
u_short r_port,
|
||||||
|
struct timeval *base_time) {
|
||||||
|
int r, _status;
|
||||||
|
ssl_obj *obj = 0;
|
||||||
|
|
||||||
if(!(obj=(ssl_obj *)calloc(1,sizeof(ssl_obj))))
|
if(!(obj = (ssl_obj *)calloc(1, sizeof(ssl_obj))))
|
||||||
ABORT(R_NO_MEMORY);
|
ABORT(R_NO_MEMORY);
|
||||||
|
|
||||||
obj->ssl_ctx=(ssl_decode_ctx *)ctx;
|
obj->ssl_ctx = (ssl_decode_ctx *)ctx;
|
||||||
obj->conn=conn;
|
obj->conn = conn;
|
||||||
|
|
||||||
if((r=create_r_queue(&obj->r2i_queue)))
|
if((r = create_r_queue(&obj->r2i_queue)))
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
if((r=create_r_queue(&obj->i2r_queue)))
|
if((r = create_r_queue(&obj->i2r_queue)))
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
|
|
||||||
obj->client_name = strndup(conn->i_name, NI_MAXHOST);
|
obj->client_name = strndup(conn->i_name, NI_MAXHOST);
|
||||||
obj->client_ip = strndup(conn->i_num, INET6_ADDRSTRLEN);
|
obj->client_ip = strndup(conn->i_num, INET6_ADDRSTRLEN);
|
||||||
obj->client_port=i_port;
|
obj->client_port = i_port;
|
||||||
|
|
||||||
obj->server_name = strndup(conn->r_name, NI_MAXHOST);
|
obj->server_name = strndup(conn->r_name, NI_MAXHOST);
|
||||||
obj->server_ip = strndup(conn->r_num, INET6_ADDRSTRLEN);
|
obj->server_ip = strndup(conn->r_num, INET6_ADDRSTRLEN);
|
||||||
obj->server_port=r_port;
|
obj->server_port = r_port;
|
||||||
|
|
||||||
obj->i_state=SSL_ST_SENT_NOTHING;
|
obj->i_state = SSL_ST_SENT_NOTHING;
|
||||||
obj->r_state=SSL_ST_HANDSHAKE;
|
obj->r_state = SSL_ST_HANDSHAKE;
|
||||||
|
|
||||||
memcpy(&obj->time_start,base_time,sizeof(struct timeval));
|
memcpy(&obj->time_start, base_time, sizeof(struct timeval));
|
||||||
memcpy(&obj->time_last,base_time,sizeof(struct timeval));
|
memcpy(&obj->time_last, base_time, sizeof(struct timeval));
|
||||||
|
|
||||||
if((r=ssl_decoder_create(&obj->decoder,obj->ssl_ctx)))
|
if((r = ssl_decoder_create(&obj->decoder, obj->ssl_ctx)))
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
|
|
||||||
if (!(obj->extensions=malloc(sizeof(ssl_extensions))))
|
if(!(obj->extensions = malloc(sizeof(ssl_extensions))))
|
||||||
ABORT(R_NO_MEMORY);
|
ABORT(R_NO_MEMORY);
|
||||||
|
|
||||||
*objp=(proto_obj *)obj;
|
*objp = (proto_obj *)obj;
|
||||||
|
|
||||||
_status=0;
|
_status = 0;
|
||||||
|
|
||||||
//check logger...
|
// check logger...
|
||||||
if (logger) _status=logger->vtbl->create(&obj->logger_obj,i_addr,i_port,r_addr,r_port,base_time);
|
if(logger)
|
||||||
|
_status = logger->vtbl->create(&obj->logger_obj, i_addr, i_port, r_addr,
|
||||||
|
r_port, base_time);
|
||||||
|
|
||||||
abort:
|
abort:
|
||||||
if(_status){
|
if(_status) {
|
||||||
destroy_ssl_analyzer((proto_obj **)&obj);
|
destroy_ssl_analyzer((proto_obj **)&obj);
|
||||||
}
|
}
|
||||||
return(_status);
|
return (_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int destroy_ssl_analyzer(proto_obj **objp) {
|
||||||
destroy_ssl_analyzer (proto_obj **objp)
|
|
||||||
{
|
|
||||||
ssl_obj *obj;
|
ssl_obj *obj;
|
||||||
|
|
||||||
if(!objp || !*objp)
|
if(!objp || !*objp)
|
||||||
return(0);
|
return (0);
|
||||||
|
|
||||||
obj=(ssl_obj *)*objp;
|
obj = (ssl_obj *)*objp;
|
||||||
DBG((0,"Destroying SSL analyzer"));
|
DBG((0, "Destroying SSL analyzer"));
|
||||||
|
|
||||||
//check logger...
|
// check logger...
|
||||||
if (logger) logger->vtbl->destroy(&obj->logger_obj);
|
if(logger)
|
||||||
|
logger->vtbl->destroy(&obj->logger_obj);
|
||||||
|
|
||||||
free_r_queue(obj->i2r_queue);
|
free_r_queue(obj->i2r_queue);
|
||||||
free_r_queue(obj->r2i_queue);
|
free_r_queue(obj->r2i_queue);
|
||||||
|
@ -313,276 +270,285 @@ destroy_ssl_analyzer (proto_obj **objp)
|
||||||
free(obj->server_ip);
|
free(obj->server_ip);
|
||||||
free(obj->extensions);
|
free(obj->extensions);
|
||||||
free(*objp);
|
free(*objp);
|
||||||
*objp=0;
|
*objp = 0;
|
||||||
|
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int free_r_queue(r_queue *q) {
|
||||||
static int
|
|
||||||
free_r_queue (r_queue *q)
|
|
||||||
{
|
|
||||||
FREE(q->data);
|
FREE(q->data);
|
||||||
if(q->q) free_tcp_segment_queue(q->q);
|
if(q->q)
|
||||||
|
free_tcp_segment_queue(q->q);
|
||||||
free(q);
|
free(q);
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int create_r_queue(r_queue **qp) {
|
||||||
create_r_queue (r_queue **qp)
|
r_queue *q = 0;
|
||||||
{
|
|
||||||
r_queue *q=0;
|
|
||||||
int _status;
|
int _status;
|
||||||
|
|
||||||
if(!(q=(r_queue *)calloc(1,sizeof(r_queue))))
|
if(!(q = (r_queue *)calloc(1, sizeof(r_queue))))
|
||||||
ABORT(R_NO_MEMORY);
|
ABORT(R_NO_MEMORY);
|
||||||
|
|
||||||
if(!(q->data=(UCHAR *)malloc(SSL_HEADER_SIZE)))
|
if(!(q->data = (UCHAR *)malloc(SSL_HEADER_SIZE)))
|
||||||
ABORT(R_NO_MEMORY);
|
ABORT(R_NO_MEMORY);
|
||||||
q->ptr=q->data;
|
q->ptr = q->data;
|
||||||
q->_allocated=SSL_HEADER_SIZE;
|
q->_allocated = SSL_HEADER_SIZE;
|
||||||
q->len=0;
|
q->len = 0;
|
||||||
|
|
||||||
q->state=SSL_READ_NONE;
|
q->state = SSL_READ_NONE;
|
||||||
*qp=q;
|
*qp = q;
|
||||||
_status=0;
|
_status = 0;
|
||||||
abort:
|
abort:
|
||||||
if(_status){
|
if(_status) {
|
||||||
free_r_queue(q);
|
free_r_queue(q);
|
||||||
}
|
}
|
||||||
return(_status);
|
return (_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int read_ssl_record(ssl_obj *obj,
|
||||||
read_ssl_record (ssl_obj *obj, r_queue *q, segment *seg, int offset, segment **lastp, int *offsetp)
|
r_queue *q,
|
||||||
|
segment *seg,
|
||||||
|
int offset,
|
||||||
|
segment **lastp,
|
||||||
|
int *offsetp)
|
||||||
|
|
||||||
{
|
{
|
||||||
segment *last=seg;
|
segment *last = seg;
|
||||||
int rec_len,r,_status;
|
int rec_len, r, _status;
|
||||||
|
|
||||||
switch(q->state){
|
switch(q->state) {
|
||||||
case SSL_READ_NONE:
|
case SSL_READ_NONE:
|
||||||
if (SSL_HEADER_SIZE<q->len)
|
if(SSL_HEADER_SIZE < q->len)
|
||||||
ABORT(-1);
|
ABORT(-1);
|
||||||
q->read_left=SSL_HEADER_SIZE-q->len;
|
q->read_left = SSL_HEADER_SIZE - q->len;
|
||||||
if((r=read_data(q,seg,offset,&last,&offset)))
|
if((r = read_data(q, seg, offset, &last, &offset)))
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
|
|
||||||
q->state=SSL_READ_HEADER;
|
q->state = SSL_READ_HEADER;
|
||||||
switch(q->data[0]){
|
switch(q->data[0]) {
|
||||||
case 20:
|
case 20:
|
||||||
case 21:
|
case 21:
|
||||||
case 22:
|
case 22:
|
||||||
case 23:
|
case 23:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
DBG((0,"Unknown SSL content type %d for segment %u:%u(%u)",
|
DBG((0, "Unknown SSL content type %d for segment %u:%u(%u)",
|
||||||
q->data[0] & 255,seg->s_seq,seg->s_seq+seg->len,seg->len));
|
q->data[0] & 255, seg->s_seq, seg->s_seq + seg->len, seg->len));
|
||||||
}
|
}
|
||||||
|
|
||||||
rec_len=COMBINE(q->data[3],q->data[4]);
|
rec_len = COMBINE(q->data[3], q->data[4]);
|
||||||
|
|
||||||
/* SSL v3.0 spec says a record may not exceed 2**14 + 2048 == 18432 */
|
/* SSL v3.0 spec says a record may not exceed 2**14 + 2048 == 18432 */
|
||||||
if(rec_len > 18432)
|
if(rec_len > 18432)
|
||||||
ABORT(R_INTERNAL);
|
ABORT(R_INTERNAL);
|
||||||
|
|
||||||
/*Expand the buffer*/
|
/*Expand the buffer*/
|
||||||
if(q->_allocated<(rec_len+SSL_HEADER_SIZE)){
|
if(q->_allocated < (rec_len + SSL_HEADER_SIZE)) {
|
||||||
if(!(q->data=realloc(q->data,rec_len+5)))
|
if(!(q->data = realloc(q->data, rec_len + 5)))
|
||||||
ABORT(R_NO_MEMORY);
|
ABORT(R_NO_MEMORY);
|
||||||
q->_allocated=rec_len+SSL_HEADER_SIZE;
|
q->_allocated = rec_len + SSL_HEADER_SIZE;
|
||||||
q->ptr=q->data+SSL_HEADER_SIZE;
|
q->ptr = q->data + SSL_HEADER_SIZE;
|
||||||
};
|
};
|
||||||
|
|
||||||
q->read_left=rec_len;
|
q->read_left = rec_len;
|
||||||
|
|
||||||
case SSL_READ_HEADER:
|
case SSL_READ_HEADER:
|
||||||
if((r=read_data(q,last,offset,&last,&offset)))
|
if((r = read_data(q, last, offset, &last, &offset)))
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ABORT(R_INTERNAL);
|
ABORT(R_INTERNAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
q->state=SSL_READ_NONE;
|
q->state = SSL_READ_NONE;
|
||||||
/*Whew. If we get here, we've managed to read a whole record*/
|
/*Whew. If we get here, we've managed to read a whole record*/
|
||||||
*lastp=last;
|
*lastp = last;
|
||||||
*offsetp=offset;
|
*offsetp = offset;
|
||||||
|
|
||||||
_status=0;
|
_status = 0;
|
||||||
abort:
|
abort:
|
||||||
return(_status);
|
return (_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int read_data(r_queue *q,
|
||||||
static int
|
segment *seg,
|
||||||
read_data (r_queue *q, segment *seg, int offset, segment **lastp, int *offsetp)
|
int offset,
|
||||||
{
|
segment **lastp,
|
||||||
int tocpy=0,r,_status;
|
int *offsetp) {
|
||||||
|
int tocpy = 0, r, _status;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
int bread=0;
|
int bread = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DBG((0,"read_data %d bytes requested",q->read_left));
|
DBG((0, "read_data %d bytes requested", q->read_left));
|
||||||
|
|
||||||
for(;seg;seg=seg->next,offset=0){
|
for(; seg; seg = seg->next, offset = 0) {
|
||||||
int left;
|
int left;
|
||||||
|
|
||||||
left=seg->len-offset;
|
left = seg->len - offset;
|
||||||
|
|
||||||
tocpy=MIN(q->read_left,left);
|
tocpy = MIN(q->read_left, left);
|
||||||
memcpy(q->ptr,seg->data+offset,tocpy);
|
memcpy(q->ptr, seg->data + offset, tocpy);
|
||||||
q->read_left-=tocpy;
|
q->read_left -= tocpy;
|
||||||
q->ptr+=tocpy;
|
q->ptr += tocpy;
|
||||||
q->len+=tocpy;
|
q->len += tocpy;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
bread+=tocpy;
|
bread += tocpy;
|
||||||
#endif
|
#endif
|
||||||
if(!q->read_left)
|
if(!q->read_left)
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
|
||||||
if(q->read_left){
|
if(q->read_left) {
|
||||||
if((r=copy_tcp_segment_queue(&q->q,seg)))
|
if((r = copy_tcp_segment_queue(&q->q, seg)))
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
return(SSL_NO_DATA);
|
return (SSL_NO_DATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(seg && tocpy==(seg->len - offset)){
|
if(seg && tocpy == (seg->len - offset)) {
|
||||||
*lastp=0;
|
*lastp = 0;
|
||||||
*offsetp=0;
|
*offsetp = 0;
|
||||||
}
|
} else {
|
||||||
else{
|
*lastp = seg;
|
||||||
*lastp=seg;
|
if(seg)
|
||||||
if(seg) *offsetp=tocpy+offset;
|
*offsetp = tocpy + offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(q->read_left<0) abort();
|
if(q->read_left < 0)
|
||||||
|
abort();
|
||||||
|
|
||||||
DBG((0,"read_data %d bytes read",bread));
|
DBG((0, "read_data %d bytes read", bread));
|
||||||
|
|
||||||
_status=0;
|
_status = 0;
|
||||||
abort:
|
abort:
|
||||||
return(_status);
|
return (_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int data_ssl_analyzer(proto_obj *_obj, segment *seg, int direction) {
|
||||||
data_ssl_analyzer (proto_obj *_obj, segment *seg, int direction)
|
int _status, r;
|
||||||
{
|
|
||||||
int _status,r;
|
|
||||||
r_queue *q;
|
r_queue *q;
|
||||||
segment *last,*q_next=NULL,*assembled;
|
segment *last, *q_next = NULL, *assembled;
|
||||||
ssl_obj *ssl=(ssl_obj *)_obj;
|
ssl_obj *ssl = (ssl_obj *)_obj;
|
||||||
int offset=0;
|
int offset = 0;
|
||||||
|
|
||||||
q=direction==DIR_R2I?ssl->r2i_queue:ssl->i2r_queue;
|
q = direction == DIR_R2I ? ssl->r2i_queue : ssl->i2r_queue;
|
||||||
|
|
||||||
/* Handle SSLv2 backwards compat client hello
|
/* Handle SSLv2 backwards compat client hello
|
||||||
This is sloppy because we'll assume that it's
|
This is sloppy because we'll assume that it's
|
||||||
all in one TCP segment -- an assumption we make
|
all in one TCP segment -- an assumption we make
|
||||||
nowhere else in the code
|
nowhere else in the code
|
||||||
*/
|
*/
|
||||||
if(direction==DIR_I2R && ssl->i_state==SSL_ST_SENT_NOTHING){
|
if(direction == DIR_I2R && ssl->i_state == SSL_ST_SENT_NOTHING) {
|
||||||
r=process_v2_hello(ssl,seg);
|
r = process_v2_hello(ssl, seg);
|
||||||
|
|
||||||
if(r==SSL_NO_DATA)
|
if(r == SSL_NO_DATA)
|
||||||
return(0);
|
return (0);
|
||||||
|
|
||||||
if(r==0)
|
if(r == 0)
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ssl->i_state==SSL_ST_SENT_NOTHING){
|
if(ssl->i_state == SSL_ST_SENT_NOTHING) {
|
||||||
|
r = process_beginning_plaintext(ssl, seg, direction);
|
||||||
|
if(r == SSL_NO_DATA)
|
||||||
|
return (0);
|
||||||
|
|
||||||
r=process_beginning_plaintext(ssl,seg,direction);
|
if(r == 0)
|
||||||
if(r==SSL_NO_DATA)
|
return (0);
|
||||||
return(0);
|
|
||||||
|
|
||||||
if(r==0)
|
|
||||||
return(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while(!(r=read_ssl_record(ssl,q,seg,offset,&last,&offset))){
|
while(!(r = read_ssl_record(ssl, q, seg, offset, &last, &offset))) {
|
||||||
if(ssl->i_state==SSL_ST_SENT_NOTHING)
|
if(ssl->i_state == SSL_ST_SENT_NOTHING)
|
||||||
ssl->i_state=SSL_ST_HANDSHAKE;
|
ssl->i_state = SSL_ST_HANDSHAKE;
|
||||||
if(last){
|
if(last) {
|
||||||
q_next=last->next;
|
q_next = last->next;
|
||||||
last->next=0;
|
last->next = 0;
|
||||||
}
|
}
|
||||||
if(q->q_last){
|
if(q->q_last) {
|
||||||
q->q_last->next=seg;
|
q->q_last->next = seg;
|
||||||
assembled=q->q;
|
assembled = q->q;
|
||||||
}
|
} else
|
||||||
else
|
assembled = seg;
|
||||||
assembled=seg;
|
|
||||||
|
|
||||||
ssl->direction=direction;
|
ssl->direction = direction;
|
||||||
|
|
||||||
if((r=print_ssl_record(ssl,direction,assembled,q->data,q->len)))
|
if((r = print_ssl_record(ssl, direction, assembled, q->data, q->len)))
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
|
|
||||||
/*Now reset things, so we can read another record*/
|
/*Now reset things, so we can read another record*/
|
||||||
if(q){
|
if(q) {
|
||||||
if(q->q_last) q->q_last->next=0;
|
if(q->q_last)
|
||||||
|
q->q_last->next = 0;
|
||||||
if(last)
|
if(last)
|
||||||
last->next=q_next;
|
last->next = q_next;
|
||||||
free_tcp_segment_queue(q->q);
|
free_tcp_segment_queue(q->q);
|
||||||
q->q=0;q->q_last=0;q->offset=0;q->len=0;q->ptr=q->data;
|
q->q = 0;
|
||||||
q->state=SSL_READ_NONE;
|
q->q_last = 0;
|
||||||
|
q->offset = 0;
|
||||||
|
q->len = 0;
|
||||||
|
q->ptr = q->data;
|
||||||
|
q->state = SSL_READ_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
seg=last;
|
seg = last;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(r!=SSL_NO_DATA)
|
if(r != SSL_NO_DATA)
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
|
|
||||||
_status=0;
|
_status = 0;
|
||||||
abort:
|
abort:
|
||||||
return(_status);
|
return (_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int print_ssl_header(ssl_obj *obj,
|
||||||
print_ssl_header (ssl_obj *obj, int direction, segment *q, UCHAR *data, int len)
|
int direction,
|
||||||
{
|
segment *q,
|
||||||
int ct=0;
|
UCHAR *data,
|
||||||
|
int len) {
|
||||||
|
int ct = 0;
|
||||||
segment *s;
|
segment *s;
|
||||||
|
|
||||||
ssl_print_record_num(obj);
|
ssl_print_record_num(obj);
|
||||||
|
|
||||||
if(SSL_print_flags & SSL_PRINT_TIMESTAMP){
|
if(SSL_print_flags & SSL_PRINT_TIMESTAMP) {
|
||||||
for(s=q;s;s=s->next) ct++;
|
for(s = q; s; s = s->next)
|
||||||
|
ct++;
|
||||||
|
|
||||||
for(s=q;s;s=s->next){
|
for(s = q; s; s = s->next) {
|
||||||
ssl_print_timestamp(obj,&s->p->ts);
|
ssl_print_timestamp(obj, &s->p->ts);
|
||||||
|
|
||||||
if(s->next)
|
if(s->next)
|
||||||
printf(", ");
|
printf(", ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ssl_print_direction_indicator(obj,direction);
|
ssl_print_direction_indicator(obj, direction);
|
||||||
|
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int print_ssl_record(ssl_obj *obj,
|
||||||
print_ssl_record (ssl_obj *obj, int direction, segment *q, UCHAR *data, int len)
|
int direction,
|
||||||
{
|
segment *q,
|
||||||
|
UCHAR *data,
|
||||||
|
int len) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
obj->cur_json_st = json_object_new_object();
|
obj->cur_json_st = json_object_new_object();
|
||||||
|
|
||||||
if((r=print_ssl_header(obj,direction,q,data,len)))
|
if((r = print_ssl_header(obj, direction, q, data, len)))
|
||||||
ERETURN(r);
|
ERETURN(r);
|
||||||
|
|
||||||
ssl_expand_record(obj,q,direction,data,len);
|
ssl_expand_record(obj, q, direction, data, len);
|
||||||
if(SSL_print_flags & SSL_PRINT_HEXDUMP){
|
if(SSL_print_flags & SSL_PRINT_HEXDUMP) {
|
||||||
Data d;
|
Data d;
|
||||||
|
|
||||||
INIT_DATA(d,data,len);
|
INIT_DATA(d, data, len);
|
||||||
exdump(obj,"Packet data",&d);
|
exdump(obj, "Packet data", &d);
|
||||||
LF;LF;
|
LF;
|
||||||
|
LF;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(SSL_print_flags & SSL_PRINT_JSON)
|
if(SSL_print_flags & SSL_PRINT_JSON)
|
||||||
|
@ -590,48 +556,34 @@ print_ssl_record (ssl_obj *obj, int direction, segment *q, UCHAR *data, int len)
|
||||||
json_object_put(obj->cur_json_st);
|
json_object_put(obj->cur_json_st);
|
||||||
obj->cur_json_st = NULL;
|
obj->cur_json_st = NULL;
|
||||||
|
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int close_ssl_analyzer(proto_obj *_obj, packet *p, int dir) {
|
||||||
close_ssl_analyzer (proto_obj *_obj, packet *p, int dir)
|
ssl_obj *ssl = (ssl_obj *)_obj;
|
||||||
{
|
|
||||||
ssl_obj *ssl=(ssl_obj *)_obj;
|
|
||||||
char *what;
|
char *what;
|
||||||
|
|
||||||
if(p->tcp->th_flags & TH_RST)
|
if(p->tcp->th_flags & TH_RST)
|
||||||
what="RST";
|
what = "RST";
|
||||||
else
|
else
|
||||||
what="FIN";
|
what = "FIN";
|
||||||
|
|
||||||
//check logger...
|
// check logger...
|
||||||
if (logger) logger->vtbl->close(ssl->logger_obj,NULL,0,dir);
|
if(logger)
|
||||||
|
logger->vtbl->close(ssl->logger_obj, NULL, 0, dir);
|
||||||
|
|
||||||
explain(ssl,"%d ",ssl->conn->conn_number);
|
explain(ssl, "%d ", ssl->conn->conn_number);
|
||||||
ssl_print_timestamp(ssl,&p->ts);
|
ssl_print_timestamp(ssl, &p->ts);
|
||||||
ssl_print_direction_indicator(ssl,dir);
|
ssl_print_direction_indicator(ssl, dir);
|
||||||
explain(ssl," TCP %s",what);
|
explain(ssl, " TCP %s", what);
|
||||||
LF;
|
LF;
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct proto_mod_vtbl_ ssl_vtbl = {
|
||||||
static struct proto_mod_vtbl_ ssl_vtbl ={
|
parse_ssl_flags, parse_ssl_flag, create_ssl_ctx,
|
||||||
parse_ssl_flags,
|
create_ssl_analyzer, destroy_ssl_ctx, destroy_ssl_analyzer,
|
||||||
parse_ssl_flag,
|
data_ssl_analyzer, close_ssl_analyzer,
|
||||||
create_ssl_ctx,
|
|
||||||
create_ssl_analyzer,
|
|
||||||
destroy_ssl_ctx,
|
|
||||||
destroy_ssl_analyzer,
|
|
||||||
data_ssl_analyzer,
|
|
||||||
close_ssl_analyzer,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct proto_mod_ ssl_mod = {
|
struct proto_mod_ ssl_mod = {0, &ssl_vtbl};
|
||||||
0,
|
|
||||||
&ssl_vtbl
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: ssl_analyze.h,v 1.3 2000/11/09 18:52:24 ekr Exp $
|
$Id: ssl_analyze.h,v 1.3 2000/11/09 18:52:24 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,29 +44,28 @@
|
||||||
ekr@rtfm.com Tue Jan 12 08:45:44 1999
|
ekr@rtfm.com Tue Jan 12 08:45:44 1999
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _ssl_analyze_h
|
#ifndef _ssl_analyze_h
|
||||||
#define _ssl_analyze_h
|
#define _ssl_analyze_h
|
||||||
|
|
||||||
extern proto_mod ssl_mod;
|
extern proto_mod ssl_mod;
|
||||||
|
|
||||||
/*The type of data this is*/
|
/*The type of data this is*/
|
||||||
#define P_RH (1<<3)
|
#define P_RH (1 << 3)
|
||||||
#define P_HT (1<<4)
|
#define P_HT (1 << 4)
|
||||||
#define P_HL (1<<5)
|
#define P_HL (1 << 5)
|
||||||
#define P_ND (1<<6)
|
#define P_ND (1 << 6)
|
||||||
#define P_DC (1<<7)
|
#define P_DC (1 << 7)
|
||||||
#define P_NR (1<<8)
|
#define P_NR (1 << 8)
|
||||||
#define P_ASN (1<<9)
|
#define P_ASN (1 << 9)
|
||||||
#define P_CR (1<<10)
|
#define P_CR (1 << 10)
|
||||||
#define P_AD (1<<11)
|
#define P_AD (1 << 11)
|
||||||
#define P_TSA (1<<12)
|
#define P_TSA (1 << 12)
|
||||||
#define P_QT (1<<13)
|
#define P_QT (1 << 13)
|
||||||
#define P_HO (1<<14)
|
#define P_HO (1 << 14)
|
||||||
#define P_JS (1<<15)
|
#define P_JS (1 << 15)
|
||||||
|
|
||||||
#define SSL_PRINT_TIMESTAMP (1) /*Timestamp records*/
|
#define SSL_PRINT_TIMESTAMP (1) /*Timestamp records*/
|
||||||
#define SSL_PRINT_HEXDUMP (1<<2) /*Print the whole record in hex*/
|
#define SSL_PRINT_HEXDUMP (1 << 2) /*Print the whole record in hex*/
|
||||||
#define SSL_PRINT_RECORD_HEADER P_RH /*Print the record header*/
|
#define SSL_PRINT_RECORD_HEADER P_RH /*Print the record header*/
|
||||||
#define SSL_PRINT_HANDSHAKE_TYPE P_HT /*Print the handshake type*/
|
#define SSL_PRINT_HANDSHAKE_TYPE P_HT /*Print the handshake type*/
|
||||||
#define SSL_PRINT_HIGHLIGHTS (P_HT | P_HL)
|
#define SSL_PRINT_HIGHLIGHTS (P_HT | P_HL)
|
||||||
|
@ -87,4 +87,3 @@ extern char *SSL_password;
|
||||||
extern char *SSL_keylogfile;
|
extern char *SSL_keylogfile;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
19
ssl/ssl_h.h
19
ssl/ssl_h.h
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: ssl_h.h,v 1.6 2002/08/17 01:33:17 ekr Exp $
|
$Id: ssl_h.h,v 1.6 2002/08/17 01:33:17 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,7 +44,6 @@
|
||||||
ekr@rtfm.com Fri Jan 8 14:09:37 1999
|
ekr@rtfm.com Fri Jan 8 14:09:37 1999
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _ssl_h
|
#ifndef _ssl_h
|
||||||
#define _ssl_h
|
#define _ssl_h
|
||||||
|
|
||||||
|
@ -52,7 +52,6 @@
|
||||||
typedef struct ssl_decode_ctx_ ssl_decode_ctx;
|
typedef struct ssl_decode_ctx_ ssl_decode_ctx;
|
||||||
typedef struct ssl_decoder_ ssl_decoder;
|
typedef struct ssl_decoder_ ssl_decoder;
|
||||||
|
|
||||||
|
|
||||||
typedef struct d_queue_ {
|
typedef struct d_queue_ {
|
||||||
short state; /*What state we're in*/
|
short state; /*What state we're in*/
|
||||||
#define SSL_READ_NONE 1
|
#define SSL_READ_NONE 1
|
||||||
|
@ -100,10 +99,10 @@ typedef struct ssl_obj_ {
|
||||||
|
|
||||||
int process_ciphertext;
|
int process_ciphertext;
|
||||||
|
|
||||||
/*Printing bookkeeping*/
|
/*Printing bookkeeping*/
|
||||||
#define REC_PLAINTEXT 1
|
#define REC_PLAINTEXT 1
|
||||||
#define REC_DECRYPTED_CIPHERTEXT 2
|
#define REC_DECRYPTED_CIPHERTEXT 2
|
||||||
#define REC_CIPHERTEXT 3
|
#define REC_CIPHERTEXT 3
|
||||||
int record_encryption;
|
int record_encryption;
|
||||||
|
|
||||||
int direction; /* The direction we're currently working in*/
|
int direction; /* The direction we're currently working in*/
|
||||||
|
@ -118,7 +117,7 @@ typedef struct ssl_obj_ {
|
||||||
typedef struct decoder_ {
|
typedef struct decoder_ {
|
||||||
int type;
|
int type;
|
||||||
char *name;
|
char *name;
|
||||||
int (*print) PROTO_LIST((ssl_obj *,int direction,segment *seg,Data *data));
|
int(*print) PROTO_LIST((ssl_obj *, int direction, segment *seg, Data *data));
|
||||||
} decoder;
|
} decoder;
|
||||||
|
|
||||||
#define SSL_NO_DATA 1
|
#define SSL_NO_DATA 1
|
||||||
|
@ -130,7 +129,7 @@ typedef struct decoder_ {
|
||||||
#define SSL_BAD_DATA 7
|
#define SSL_BAD_DATA 7
|
||||||
|
|
||||||
/*SSL defines*/
|
/*SSL defines*/
|
||||||
#define COMBINE(a,b) ((a<<8) | b)
|
#define COMBINE(a, b) ((a << 8) | b)
|
||||||
#define SSL_HEADER_SIZE 5
|
#define SSL_HEADER_SIZE 5
|
||||||
|
|
||||||
#define SSLV3_VERSION 0x300
|
#define SSLV3_VERSION 0x300
|
||||||
|
@ -146,6 +145,4 @@ typedef struct decoder_ {
|
||||||
|
|
||||||
#include "ssldecode.h"
|
#include "ssldecode.h"
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
478
ssl/ssl_rec.c
478
ssl/ssl_rec.c
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: ssl_rec.c,v 1.3 2000/11/03 06:38:06 ekr Exp $
|
$Id: ssl_rec.c,v 1.3 2000/11/03 06:38:06 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,8 +44,6 @@
|
||||||
ekr@rtfm.com Wed Aug 18 15:46:57 1999
|
ekr@rtfm.com Wed Aug 18 15:46:57 1999
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "network.h"
|
#include "network.h"
|
||||||
#include "ssl_h.h"
|
#include "ssl_h.h"
|
||||||
#include "sslprint.h"
|
#include "sslprint.h"
|
||||||
|
@ -58,7 +57,6 @@
|
||||||
#include "ssldecode.h"
|
#include "ssldecode.h"
|
||||||
#include "ssl_rec.h"
|
#include "ssl_rec.h"
|
||||||
|
|
||||||
|
|
||||||
struct ssl_rec_decoder_ {
|
struct ssl_rec_decoder_ {
|
||||||
SSL_CipherSuite *cs;
|
SSL_CipherSuite *cs;
|
||||||
Data *mac_key;
|
Data *mac_key;
|
||||||
|
@ -70,156 +68,146 @@ struct ssl_rec_decoder_ {
|
||||||
UINT8 seq;
|
UINT8 seq;
|
||||||
};
|
};
|
||||||
|
|
||||||
char *digests[]={
|
char *digests[] = {"MD5", "SHA1", "SHA224", "SHA256", "SHA384", "SHA512", NULL};
|
||||||
"MD5",
|
|
||||||
"SHA1",
|
|
||||||
"SHA224",
|
|
||||||
"SHA256",
|
|
||||||
"SHA384",
|
|
||||||
"SHA512",
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
char *ciphers[]={
|
char *ciphers[] = {
|
||||||
"DES",
|
"DES", "3DES",
|
||||||
"3DES",
|
"RC4", "RC2",
|
||||||
"RC4",
|
"IDEA", "AES128",
|
||||||
"RC2",
|
"AES256", "CAMELLIA128",
|
||||||
"IDEA",
|
"CAMELLIA256", "SEED",
|
||||||
"AES128",
|
NULL, "aes-128-gcm",
|
||||||
"AES256",
|
"aes-256-gcm", "ChaCha20-Poly1305",
|
||||||
"CAMELLIA128",
|
|
||||||
"CAMELLIA256",
|
|
||||||
"SEED",
|
|
||||||
NULL,
|
|
||||||
"aes-128-gcm",
|
|
||||||
"aes-256-gcm",
|
|
||||||
"ChaCha20-Poly1305",
|
|
||||||
"aes-128-ccm",
|
"aes-128-ccm",
|
||||||
"aes-128-ccm", // for ccm 8, uses the same cipher
|
"aes-128-ccm", // for ccm 8, uses the same cipher
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int tls_check_mac PROTO_LIST((ssl_rec_decoder * d,
|
||||||
|
int ct,
|
||||||
|
int ver,
|
||||||
|
UCHAR *data,
|
||||||
|
UINT4 datalen,
|
||||||
|
UCHAR *iv,
|
||||||
|
UINT4 ivlen,
|
||||||
|
UCHAR *mac));
|
||||||
|
static int fmt_seq PROTO_LIST((UINT4 num, UCHAR *buf));
|
||||||
|
|
||||||
static int tls_check_mac PROTO_LIST((ssl_rec_decoder *d,int ct,
|
int ssl_create_rec_decoder(ssl_rec_decoder **dp,
|
||||||
int ver,UCHAR *data,UINT4 datalen,UCHAR *iv,UINT4 ivlen,UCHAR *mac));
|
ssl_obj *ssl,
|
||||||
static int fmt_seq PROTO_LIST((UINT4 num,UCHAR *buf));
|
UCHAR *mk,
|
||||||
|
UCHAR *sk,
|
||||||
int
|
UCHAR *iv) {
|
||||||
ssl_create_rec_decoder (ssl_rec_decoder **dp, ssl_obj *ssl, UCHAR *mk, UCHAR *sk, UCHAR *iv)
|
int r, _status;
|
||||||
{
|
ssl_rec_decoder *dec = 0;
|
||||||
int r,_status;
|
|
||||||
ssl_rec_decoder *dec=0;
|
|
||||||
#ifdef OPENSSL
|
#ifdef OPENSSL
|
||||||
const EVP_CIPHER *ciph=0;
|
const EVP_CIPHER *ciph = 0;
|
||||||
int iv_len = ssl->version == TLSV13_VERSION?12:ssl->cs->block;
|
int iv_len = ssl->version == TLSV13_VERSION ? 12 : ssl->cs->block;
|
||||||
|
|
||||||
/* Find the SSLeay cipher */
|
/* Find the SSLeay cipher */
|
||||||
if(ssl->cs->enc!=ENC_NULL){
|
if(ssl->cs->enc != ENC_NULL) {
|
||||||
ciph=(EVP_CIPHER *)EVP_get_cipherbyname(ciphers[ssl->cs->enc-0x30]);
|
ciph = (EVP_CIPHER *)EVP_get_cipherbyname(ciphers[ssl->cs->enc - 0x30]);
|
||||||
if(!ciph)
|
if(!ciph)
|
||||||
ABORT(R_INTERNAL);
|
ABORT(R_INTERNAL);
|
||||||
}
|
} else {
|
||||||
else {
|
ciph = EVP_enc_null();
|
||||||
ciph=EVP_enc_null();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!(dec=(ssl_rec_decoder *)calloc(1,sizeof(ssl_rec_decoder))))
|
if(!(dec = (ssl_rec_decoder *)calloc(1, sizeof(ssl_rec_decoder))))
|
||||||
ABORT(R_NO_MEMORY);
|
ABORT(R_NO_MEMORY);
|
||||||
|
|
||||||
dec->cs=ssl->cs;
|
dec->cs = ssl->cs;
|
||||||
|
|
||||||
if((r=r_data_alloc(&dec->mac_key,ssl->cs->dig_len)))
|
if((r = r_data_alloc(&dec->mac_key, ssl->cs->dig_len)))
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
|
|
||||||
if((r=r_data_alloc(&dec->implicit_iv,iv_len)))
|
if((r = r_data_alloc(&dec->implicit_iv, iv_len)))
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
memcpy(dec->implicit_iv->data,iv, iv_len);
|
memcpy(dec->implicit_iv->data, iv, iv_len);
|
||||||
|
|
||||||
if((r=r_data_create(&dec->write_key,sk,ssl->cs->eff_bits/8)))
|
if((r = r_data_create(&dec->write_key, sk, ssl->cs->eff_bits / 8)))
|
||||||
ABORT(r);
|
ABORT(r);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This is necessary for AEAD ciphers, because we must wait to fully initialize the cipher
|
This is necessary for AEAD ciphers, because we must wait to fully
|
||||||
in order to include the implicit IV
|
initialize the cipher in order to include the implicit IV
|
||||||
*/
|
*/
|
||||||
if(IS_AEAD_CIPHER(ssl->cs)){
|
if(IS_AEAD_CIPHER(ssl->cs)) {
|
||||||
sk=NULL;
|
sk = NULL;
|
||||||
iv=NULL;
|
iv = NULL;
|
||||||
}
|
} else
|
||||||
else
|
memcpy(dec->mac_key->data, mk, ssl->cs->dig_len);
|
||||||
memcpy(dec->mac_key->data,mk,ssl->cs->dig_len);
|
|
||||||
|
|
||||||
if(!(dec->evp=EVP_CIPHER_CTX_new()))
|
if(!(dec->evp = EVP_CIPHER_CTX_new()))
|
||||||
ABORT(R_NO_MEMORY);
|
ABORT(R_NO_MEMORY);
|
||||||
EVP_CIPHER_CTX_init(dec->evp);
|
EVP_CIPHER_CTX_init(dec->evp);
|
||||||
EVP_CipherInit(dec->evp,ciph,sk,iv,0);
|
EVP_CipherInit(dec->evp, ciph, sk, iv, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
*dp=dec;
|
*dp = dec;
|
||||||
_status=0;
|
_status = 0;
|
||||||
abort:
|
abort:
|
||||||
if(_status){
|
if(_status) {
|
||||||
ssl_destroy_rec_decoder(&dec);
|
ssl_destroy_rec_decoder(&dec);
|
||||||
}
|
}
|
||||||
return(_status);
|
return (_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int ssl_destroy_rec_decoder(ssl_rec_decoder **dp) {
|
||||||
ssl_destroy_rec_decoder (ssl_rec_decoder **dp)
|
|
||||||
{
|
|
||||||
ssl_rec_decoder *d;
|
ssl_rec_decoder *d;
|
||||||
|
|
||||||
if(!dp || !*dp)
|
if(!dp || !*dp)
|
||||||
return(0);
|
return (0);
|
||||||
d=*dp;
|
d = *dp;
|
||||||
|
|
||||||
r_data_destroy(&d->mac_key);
|
r_data_destroy(&d->mac_key);
|
||||||
r_data_destroy(&d->implicit_iv);
|
r_data_destroy(&d->implicit_iv);
|
||||||
r_data_destroy(&d->write_key);
|
r_data_destroy(&d->write_key);
|
||||||
#ifdef OPENSSL
|
#ifdef OPENSSL
|
||||||
if(d->evp){
|
if(d->evp) {
|
||||||
EVP_CIPHER_CTX_free(d->evp);
|
EVP_CIPHER_CTX_free(d->evp);
|
||||||
}
|
}
|
||||||
free(*dp);
|
free(*dp);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
*dp=0;
|
*dp = 0;
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define MSB(a) ((a >> 8) & 0xff)
|
||||||
|
#define LSB(a) (a & 0xff)
|
||||||
|
|
||||||
#define MSB(a) ((a>>8)&0xff)
|
int tls13_update_rec_key(ssl_rec_decoder *d, UCHAR *newkey, UCHAR *newiv) {
|
||||||
#define LSB(a) (a&0xff)
|
|
||||||
|
|
||||||
int
|
|
||||||
tls13_update_rec_key (ssl_rec_decoder *d, UCHAR *newkey, UCHAR *newiv)
|
|
||||||
{
|
|
||||||
d->write_key->data = newkey;
|
d->write_key->data = newkey;
|
||||||
d->implicit_iv->data = newiv;
|
d->implicit_iv->data = newiv;
|
||||||
d->seq = 0;
|
d->seq = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int tls13_decode_rec_data(ssl_obj *ssl,
|
||||||
tls13_decode_rec_data (ssl_obj *ssl, ssl_rec_decoder *d, int ct, int version, UCHAR *in, int inl, UCHAR *out, int *outl)
|
ssl_rec_decoder *d,
|
||||||
{
|
int ct,
|
||||||
int pad,i;
|
int version,
|
||||||
int r,encpadl,x,_status=0;
|
UCHAR *in,
|
||||||
UCHAR aad[5],aead_nonce[12], *tag;
|
int inl,
|
||||||
int taglen = d->cs->enc==ENC_AES128_CCM_8?8:16;
|
UCHAR *out,
|
||||||
CRDUMP("CipherText",in,inl);
|
int *outl) {
|
||||||
CRDUMPD("KEY",d->write_key);
|
int pad, i;
|
||||||
CRDUMPD("IV",d->implicit_iv);
|
int r, encpadl, x, _status = 0;
|
||||||
if (!IS_AEAD_CIPHER(d->cs)){
|
UCHAR aad[5], aead_nonce[12], *tag;
|
||||||
|
int taglen = d->cs->enc == ENC_AES128_CCM_8 ? 8 : 16;
|
||||||
|
CRDUMP("CipherText", in, inl);
|
||||||
|
CRDUMPD("KEY", d->write_key);
|
||||||
|
CRDUMPD("IV", d->implicit_iv);
|
||||||
|
if(!IS_AEAD_CIPHER(d->cs)) {
|
||||||
fprintf(stderr, "Non aead cipher in tls13\n");
|
fprintf(stderr, "Non aead cipher in tls13\n");
|
||||||
ABORT(-1);
|
ABORT(-1);
|
||||||
}
|
}
|
||||||
memcpy(aead_nonce, d->implicit_iv->data, 12);
|
memcpy(aead_nonce, d->implicit_iv->data, 12);
|
||||||
for (i = 0; i < 8; i++) { // AEAD NONCE according to RFC TLS1.3
|
for(i = 0; i < 8; i++) { // AEAD NONCE according to RFC TLS1.3
|
||||||
aead_nonce[12 - 1 - i] ^= ((d->seq >> (i * 8)) & 0xFF);
|
aead_nonce[12 - 1 - i] ^= ((d->seq >> (i * 8)) & 0xFF);
|
||||||
}
|
}
|
||||||
d->seq++;
|
d->seq++;
|
||||||
CRDUMP("NONCE",aead_nonce,12);
|
CRDUMP("NONCE", aead_nonce, 12);
|
||||||
tag = in+(inl-taglen);
|
tag = in + (inl - taglen);
|
||||||
CRDUMP("Tag", tag, taglen);
|
CRDUMP("Tag", tag, taglen);
|
||||||
|
|
||||||
aad[0] = ct;
|
aad[0] = ct;
|
||||||
|
@ -227,42 +215,46 @@ tls13_decode_rec_data (ssl_obj *ssl, ssl_rec_decoder *d, int ct, int version, UC
|
||||||
aad[2] = 0x03;
|
aad[2] = 0x03;
|
||||||
aad[3] = MSB(inl);
|
aad[3] = MSB(inl);
|
||||||
aad[4] = LSB(inl);
|
aad[4] = LSB(inl);
|
||||||
CRDUMP("AAD",aad,5);
|
CRDUMP("AAD", aad, 5);
|
||||||
inl-=taglen;
|
inl -= taglen;
|
||||||
|
|
||||||
if (!EVP_CIPHER_CTX_ctrl(d->evp, EVP_CTRL_AEAD_SET_IVLEN, 12, NULL)) {
|
if(!EVP_CIPHER_CTX_ctrl(d->evp, EVP_CTRL_AEAD_SET_IVLEN, 12, NULL)) {
|
||||||
fprintf(stderr, "Unable to set ivlen\n");
|
fprintf(stderr, "Unable to set ivlen\n");
|
||||||
ABORT(-1);
|
ABORT(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_CCM_CIPHER(d->cs) && !EVP_CIPHER_CTX_ctrl(d->evp, EVP_CTRL_AEAD_SET_TAG, taglen, tag)) {
|
if(IS_CCM_CIPHER(d->cs) &&
|
||||||
|
!EVP_CIPHER_CTX_ctrl(d->evp, EVP_CTRL_AEAD_SET_TAG, taglen, tag)) {
|
||||||
fprintf(stderr, "Unable to set tag for ccm cipher\n");
|
fprintf(stderr, "Unable to set tag for ccm cipher\n");
|
||||||
ABORT(-1);
|
ABORT(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!EVP_DecryptInit_ex(d->evp,NULL,NULL,d->write_key->data,aead_nonce)){
|
if(!EVP_DecryptInit_ex(d->evp, NULL, NULL, d->write_key->data, aead_nonce)) {
|
||||||
fprintf(stderr,"Unable to init evp1\n");
|
fprintf(stderr, "Unable to init evp1\n");
|
||||||
ABORT(-1);
|
ABORT(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_CCM_CIPHER(d->cs) && !EVP_DecryptUpdate(d->evp,NULL,outl,NULL,inl)){
|
if(IS_CCM_CIPHER(d->cs) &&
|
||||||
fprintf(stderr,"Unable to update data length\n");
|
!EVP_DecryptUpdate(d->evp, NULL, outl, NULL, inl)) {
|
||||||
|
fprintf(stderr, "Unable to update data length\n");
|
||||||
ABORT(-1);
|
ABORT(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!EVP_DecryptUpdate(d->evp,NULL,outl,aad,5)){
|
if(!EVP_DecryptUpdate(d->evp, NULL, outl, aad, 5)) {
|
||||||
fprintf(stderr,"Unable to update aad\n");
|
fprintf(stderr, "Unable to update aad\n");
|
||||||
ABORT(-1);
|
ABORT(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
CRDUMP("Real CipherText", in, inl);
|
CRDUMP("Real CipherText", in, inl);
|
||||||
if (!EVP_DecryptUpdate(d->evp,out,outl,in,inl)){
|
if(!EVP_DecryptUpdate(d->evp, out, outl, in, inl)) {
|
||||||
fprintf(stderr,"Unable to update with CipherText\n");
|
fprintf(stderr, "Unable to update with CipherText\n");
|
||||||
ABORT(-1);
|
ABORT(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IS_CCM_CIPHER(d->cs) && (!EVP_CIPHER_CTX_ctrl(d->evp,EVP_CTRL_GCM_SET_TAG,taglen,tag) || !EVP_DecryptFinal(d->evp,NULL,&x))) {
|
if(!IS_CCM_CIPHER(d->cs) &&
|
||||||
fprintf(stderr,"BAD MAC\n");
|
(!EVP_CIPHER_CTX_ctrl(d->evp, EVP_CTRL_GCM_SET_TAG, taglen, tag) ||
|
||||||
|
!EVP_DecryptFinal(d->evp, NULL, &x))) {
|
||||||
|
fprintf(stderr, "BAD MAC\n");
|
||||||
ABORT(SSL_BAD_MAC);
|
ABORT(SSL_BAD_MAC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,45 +263,47 @@ abort:
|
||||||
return _status;
|
return _status;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int ssl_decode_rec_data(ssl_obj *ssl,
|
||||||
ssl_decode_rec_data (ssl_obj *ssl, ssl_rec_decoder *d, int ct, int version, UCHAR *in, int inl, UCHAR *out, int *outl)
|
ssl_rec_decoder *d,
|
||||||
{
|
int ct,
|
||||||
|
int version,
|
||||||
|
UCHAR *in,
|
||||||
|
int inl,
|
||||||
|
UCHAR *out,
|
||||||
|
int *outl) {
|
||||||
#ifdef OPENSSL
|
#ifdef OPENSSL
|
||||||
int pad;
|
int pad;
|
||||||
int r,encpadl,x;
|
int r, encpadl, x;
|
||||||
UCHAR *mac,aead_tag[13],aead_nonce[12];
|
UCHAR *mac, aead_tag[13], aead_nonce[12];
|
||||||
|
|
||||||
CRDUMP("Ciphertext",in,inl);
|
CRDUMP("Ciphertext", in, inl);
|
||||||
if(IS_AEAD_CIPHER(d->cs)){
|
if(IS_AEAD_CIPHER(d->cs)) {
|
||||||
memcpy(aead_nonce,d->implicit_iv->data,d->implicit_iv->len);
|
memcpy(aead_nonce, d->implicit_iv->data, d->implicit_iv->len);
|
||||||
memcpy(aead_nonce+d->implicit_iv->len,in,12-d->implicit_iv->len);
|
memcpy(aead_nonce + d->implicit_iv->len, in, 12 - d->implicit_iv->len);
|
||||||
in+=12-d->implicit_iv->len;
|
in += 12 - d->implicit_iv->len;
|
||||||
inl-=12-d->implicit_iv->len;
|
inl -= 12 - d->implicit_iv->len;
|
||||||
|
|
||||||
EVP_DecryptInit(d->evp,
|
EVP_DecryptInit(d->evp, NULL, d->write_key->data, aead_nonce);
|
||||||
NULL,
|
|
||||||
d->write_key->data,
|
|
||||||
aead_nonce);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Then tag is always 16 bytes, as per:
|
Then tag is always 16 bytes, as per:
|
||||||
https://tools.ietf.org/html/rfc5116#section-5.2
|
https://tools.ietf.org/html/rfc5116#section-5.2
|
||||||
*/
|
*/
|
||||||
EVP_CIPHER_CTX_ctrl(d->evp,EVP_CTRL_GCM_SET_TAG,16,in+(inl-16));
|
EVP_CIPHER_CTX_ctrl(d->evp, EVP_CTRL_GCM_SET_TAG, 16, in + (inl - 16));
|
||||||
inl-=16;
|
inl -= 16;
|
||||||
|
|
||||||
fmt_seq(d->seq,aead_tag);
|
fmt_seq(d->seq, aead_tag);
|
||||||
d->seq++;
|
d->seq++;
|
||||||
aead_tag[8]=ct;
|
aead_tag[8] = ct;
|
||||||
aead_tag[9]=MSB(version);
|
aead_tag[9] = MSB(version);
|
||||||
aead_tag[10]=LSB(version);
|
aead_tag[10] = LSB(version);
|
||||||
aead_tag[11]=MSB(inl);
|
aead_tag[11] = MSB(inl);
|
||||||
aead_tag[12]=LSB(inl);
|
aead_tag[12] = LSB(inl);
|
||||||
|
|
||||||
EVP_DecryptUpdate(d->evp,NULL,outl,aead_tag,13);
|
EVP_DecryptUpdate(d->evp, NULL, outl, aead_tag, 13);
|
||||||
EVP_DecryptUpdate(d->evp,out,outl,in,inl);
|
EVP_DecryptUpdate(d->evp, out, outl, in, inl);
|
||||||
|
|
||||||
if (!(x=EVP_DecryptFinal(d->evp,NULL,&x)))
|
if(!(x = EVP_DecryptFinal(d->evp, NULL, &x)))
|
||||||
ERETURN(SSL_BAD_MAC);
|
ERETURN(SSL_BAD_MAC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -317,110 +311,106 @@ ssl_decode_rec_data (ssl_obj *ssl, ssl_rec_decoder *d, int ct, int version, UCHA
|
||||||
Encrypt-then-MAC is not used with AEAD ciphers, as per:
|
Encrypt-then-MAC is not used with AEAD ciphers, as per:
|
||||||
https://tools.ietf.org/html/rfc7366#section-3
|
https://tools.ietf.org/html/rfc7366#section-3
|
||||||
*/
|
*/
|
||||||
else if(ssl->extensions->encrypt_then_mac==2){
|
else if(ssl->extensions->encrypt_then_mac == 2) {
|
||||||
*outl=inl;
|
*outl = inl;
|
||||||
|
|
||||||
/* First strip off the MAC */
|
/* First strip off the MAC */
|
||||||
*outl-=d->cs->dig_len;
|
*outl -= d->cs->dig_len;
|
||||||
mac=in+(*outl);
|
mac = in + (*outl);
|
||||||
|
|
||||||
encpadl=*outl;
|
encpadl = *outl;
|
||||||
/* Now decrypt */
|
/* Now decrypt */
|
||||||
EVP_Cipher(d->evp,out,in,*outl);
|
EVP_Cipher(d->evp, out, in, *outl);
|
||||||
CRDUMP("Plaintext",out,*outl);
|
CRDUMP("Plaintext", out, *outl);
|
||||||
|
|
||||||
/* And then strip off the padding*/
|
/* And then strip off the padding*/
|
||||||
if(d->cs->block>1){
|
if(d->cs->block > 1) {
|
||||||
pad=out[*outl-1];
|
pad = out[*outl - 1];
|
||||||
*outl-=(pad+1);
|
*outl -= (pad + 1);
|
||||||
}
|
}
|
||||||
/* TLS 1.1 and beyond: remove explicit IV, only used with
|
/* TLS 1.1 and beyond: remove explicit IV, only used with
|
||||||
* non-stream ciphers. */
|
* non-stream ciphers. */
|
||||||
if (ssl->version>=0x0302 && ssl->cs->block > 1) {
|
if(ssl->version >= 0x0302 && ssl->cs->block > 1) {
|
||||||
UINT4 blk = ssl->cs->block;
|
UINT4 blk = ssl->cs->block;
|
||||||
if (blk <= *outl) {
|
if(blk <= *outl) {
|
||||||
*outl-=blk;
|
*outl -= blk;
|
||||||
memmove(out, out+blk, *outl);
|
memmove(out, out + blk, *outl);
|
||||||
}
|
} else {
|
||||||
else {
|
DBG((0, "Block size greater than Plaintext!"));
|
||||||
DBG((0,"Block size greater than Plaintext!"));
|
|
||||||
ERETURN(SSL_BAD_MAC);
|
ERETURN(SSL_BAD_MAC);
|
||||||
}
|
}
|
||||||
|
|
||||||
if((r=tls_check_mac(d,ct,version,in+blk,encpadl,in,blk,mac)))
|
if((r = tls_check_mac(d, ct, version, in + blk, encpadl, in, blk, mac)))
|
||||||
ERETURN(r);
|
ERETURN(r);
|
||||||
|
|
||||||
}
|
} else if((r = tls_check_mac(d, ct, version, in, encpadl, NULL, 0, mac)))
|
||||||
else
|
|
||||||
if((r=tls_check_mac(d,ct,version,in,encpadl,NULL,0,mac)))
|
|
||||||
ERETURN(r);
|
ERETURN(r);
|
||||||
|
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
/* First decrypt*/
|
/* First decrypt*/
|
||||||
EVP_Cipher(d->evp,out,in,inl);
|
EVP_Cipher(d->evp, out, in, inl);
|
||||||
|
|
||||||
CRDUMP("Plaintext",out,inl);
|
CRDUMP("Plaintext", out, inl);
|
||||||
*outl=inl;
|
*outl = inl;
|
||||||
|
|
||||||
/* Now strip off the padding*/
|
/* Now strip off the padding*/
|
||||||
if(d->cs->block>1){
|
if(d->cs->block > 1) {
|
||||||
pad=out[inl-1];
|
pad = out[inl - 1];
|
||||||
*outl-=(pad+1);
|
*outl -= (pad + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* And the MAC */
|
/* And the MAC */
|
||||||
*outl-=d->cs->dig_len;
|
*outl -= d->cs->dig_len;
|
||||||
mac=out+(*outl);
|
mac = out + (*outl);
|
||||||
CRDUMP("Record data",out,*outl);
|
CRDUMP("Record data", out, *outl);
|
||||||
|
|
||||||
/* Now check the MAC */
|
/* Now check the MAC */
|
||||||
if(ssl->version==0x300){
|
if(ssl->version == 0x300) {
|
||||||
if((r=ssl3_check_mac(d,ct,version,out,*outl,mac)))
|
if((r = ssl3_check_mac(d, ct, version, out, *outl, mac)))
|
||||||
ERETURN(r);
|
ERETURN(r);
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
/* TLS 1.1 and beyond: remove explicit IV, only used with
|
/* TLS 1.1 and beyond: remove explicit IV, only used with
|
||||||
* non-stream ciphers. */
|
* non-stream ciphers. */
|
||||||
if (ssl->version>=0x0302 && ssl->cs->block > 1) {
|
if(ssl->version >= 0x0302 && ssl->cs->block > 1) {
|
||||||
UINT4 blk = ssl->cs->block;
|
UINT4 blk = ssl->cs->block;
|
||||||
if (blk <= *outl) {
|
if(blk <= *outl) {
|
||||||
*outl-=blk;
|
*outl -= blk;
|
||||||
memmove(out, out+blk, *outl);
|
memmove(out, out + blk, *outl);
|
||||||
}
|
} else {
|
||||||
else {
|
DBG((0, "Block size greater than Plaintext!"));
|
||||||
DBG((0,"Block size greater than Plaintext!"));
|
|
||||||
ERETURN(SSL_BAD_MAC);
|
ERETURN(SSL_BAD_MAC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if((r=tls_check_mac(d,ct,version,out,*outl,NULL,0,mac)))
|
if((r = tls_check_mac(d, ct, version, out, *outl, NULL, 0, mac)))
|
||||||
ERETURN(r);
|
ERETURN(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef OPENSSL
|
#ifdef OPENSSL
|
||||||
|
|
||||||
/* This should go to 2^128, but we're never really going to see
|
/* This should go to 2^128, but we're never really going to see
|
||||||
more than 2^64, so we cheat*/
|
more than 2^64, so we cheat*/
|
||||||
static int
|
static int fmt_seq(UINT4 num, UCHAR *buf) {
|
||||||
fmt_seq (UINT4 num, UCHAR *buf)
|
|
||||||
{
|
|
||||||
UINT4 netnum;
|
UINT4 netnum;
|
||||||
|
|
||||||
memset(buf,0,8);
|
memset(buf, 0, 8);
|
||||||
netnum=htonl(num);
|
netnum = htonl(num);
|
||||||
memcpy(buf+4,&netnum,4);
|
memcpy(buf + 4, &netnum, 4);
|
||||||
|
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int tls_check_mac(ssl_rec_decoder *d,
|
||||||
tls_check_mac (ssl_rec_decoder *d, int ct, int ver, UCHAR *data, UINT4 datalen, UCHAR *iv, UINT4 ivlen, UCHAR *mac)
|
int ct,
|
||||||
{
|
int ver,
|
||||||
|
UCHAR *data,
|
||||||
|
UINT4 datalen,
|
||||||
|
UCHAR *iv,
|
||||||
|
UINT4 ivlen,
|
||||||
|
UCHAR *mac) {
|
||||||
HMAC_CTX *hm = HMAC_CTX_new();
|
HMAC_CTX *hm = HMAC_CTX_new();
|
||||||
if(!hm)
|
if(!hm)
|
||||||
ERETURN(R_NO_MEMORY);
|
ERETURN(R_NO_MEMORY);
|
||||||
|
@ -428,90 +418,92 @@ tls_check_mac (ssl_rec_decoder *d, int ct, int ver, UCHAR *data, UINT4 datalen,
|
||||||
UINT4 l;
|
UINT4 l;
|
||||||
UCHAR buf[128];
|
UCHAR buf[128];
|
||||||
|
|
||||||
md=EVP_get_digestbyname(digests[d->cs->dig-0x40]);
|
md = EVP_get_digestbyname(digests[d->cs->dig - 0x40]);
|
||||||
HMAC_Init_ex(hm,d->mac_key->data,d->mac_key->len,md,NULL);
|
HMAC_Init_ex(hm, d->mac_key->data, d->mac_key->len, md, NULL);
|
||||||
|
|
||||||
fmt_seq(d->seq,buf);
|
fmt_seq(d->seq, buf);
|
||||||
d->seq++;
|
d->seq++;
|
||||||
HMAC_Update(hm,buf,8);
|
HMAC_Update(hm, buf, 8);
|
||||||
buf[0]=ct;
|
buf[0] = ct;
|
||||||
HMAC_Update(hm,buf,1);
|
HMAC_Update(hm, buf, 1);
|
||||||
|
|
||||||
buf[0]=MSB(ver);
|
buf[0] = MSB(ver);
|
||||||
buf[1]=LSB(ver);
|
buf[1] = LSB(ver);
|
||||||
HMAC_Update(hm,buf,2);
|
HMAC_Update(hm, buf, 2);
|
||||||
|
|
||||||
buf[0]=MSB(datalen);
|
buf[0] = MSB(datalen);
|
||||||
buf[1]=LSB(datalen);
|
buf[1] = LSB(datalen);
|
||||||
HMAC_Update(hm,buf,2);
|
HMAC_Update(hm, buf, 2);
|
||||||
|
|
||||||
/* for encrypt-then-mac with an explicit IV */
|
/* for encrypt-then-mac with an explicit IV */
|
||||||
if(ivlen && iv){
|
if(ivlen && iv) {
|
||||||
HMAC_Update(hm,iv,ivlen);
|
HMAC_Update(hm, iv, ivlen);
|
||||||
HMAC_Update(hm,data,datalen-ivlen);
|
HMAC_Update(hm, data, datalen - ivlen);
|
||||||
}
|
} else
|
||||||
else
|
HMAC_Update(hm, data, datalen);
|
||||||
HMAC_Update(hm,data,datalen);
|
|
||||||
|
|
||||||
HMAC_Final(hm,buf,&l);
|
HMAC_Final(hm, buf, &l);
|
||||||
if(memcmp(mac,buf,l))
|
if(memcmp(mac, buf, l))
|
||||||
ERETURN(SSL_BAD_MAC);
|
ERETURN(SSL_BAD_MAC);
|
||||||
|
|
||||||
HMAC_CTX_free(hm);
|
HMAC_CTX_free(hm);
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int ssl3_check_mac(ssl_rec_decoder *d,
|
||||||
ssl3_check_mac (ssl_rec_decoder *d, int ct, int ver, UCHAR *data, UINT4 datalen, UCHAR *mac)
|
int ct,
|
||||||
{
|
int ver,
|
||||||
|
UCHAR *data,
|
||||||
|
UINT4 datalen,
|
||||||
|
UCHAR *mac) {
|
||||||
EVP_MD_CTX *mc = EVP_MD_CTX_new();
|
EVP_MD_CTX *mc = EVP_MD_CTX_new();
|
||||||
const EVP_MD *md;
|
const EVP_MD *md;
|
||||||
UINT4 l;
|
UINT4 l;
|
||||||
UCHAR buf[64],dgst[20];
|
UCHAR buf[64], dgst[20];
|
||||||
int pad_ct;
|
int pad_ct;
|
||||||
|
|
||||||
pad_ct=(d->cs->dig==DIG_SHA)?40:48;
|
pad_ct = (d->cs->dig == DIG_SHA) ? 40 : 48;
|
||||||
|
|
||||||
md=EVP_get_digestbyname(digests[d->cs->dig-0x40]);
|
md = EVP_get_digestbyname(digests[d->cs->dig - 0x40]);
|
||||||
EVP_DigestInit(mc,md);
|
EVP_DigestInit(mc, md);
|
||||||
|
|
||||||
EVP_DigestUpdate(mc,d->mac_key->data,d->mac_key->len);
|
EVP_DigestUpdate(mc, d->mac_key->data, d->mac_key->len);
|
||||||
|
|
||||||
memset(buf,0x36,pad_ct);
|
memset(buf, 0x36, pad_ct);
|
||||||
EVP_DigestUpdate(mc,buf,pad_ct);
|
EVP_DigestUpdate(mc, buf, pad_ct);
|
||||||
|
|
||||||
fmt_seq(d->seq,buf);
|
fmt_seq(d->seq, buf);
|
||||||
d->seq++;
|
d->seq++;
|
||||||
EVP_DigestUpdate(mc,buf,8);
|
EVP_DigestUpdate(mc, buf, 8);
|
||||||
|
|
||||||
buf[0]=ct;
|
buf[0] = ct;
|
||||||
EVP_DigestUpdate(mc,buf,1);
|
EVP_DigestUpdate(mc, buf, 1);
|
||||||
|
|
||||||
buf[0]=MSB(datalen);
|
buf[0] = MSB(datalen);
|
||||||
buf[1]=LSB(datalen);
|
buf[1] = LSB(datalen);
|
||||||
EVP_DigestUpdate(mc,buf,2);
|
EVP_DigestUpdate(mc, buf, 2);
|
||||||
|
|
||||||
EVP_DigestUpdate(mc,data,datalen);
|
EVP_DigestUpdate(mc, data, datalen);
|
||||||
|
|
||||||
EVP_DigestFinal(mc,dgst,&l);
|
EVP_DigestFinal(mc, dgst, &l);
|
||||||
|
|
||||||
EVP_DigestInit(mc,md);
|
EVP_DigestInit(mc, md);
|
||||||
|
|
||||||
EVP_DigestUpdate(mc,d->mac_key->data,d->mac_key->len);
|
EVP_DigestUpdate(mc, d->mac_key->data, d->mac_key->len);
|
||||||
|
|
||||||
memset(buf,0x5c,pad_ct);
|
memset(buf, 0x5c, pad_ct);
|
||||||
EVP_DigestUpdate(mc,buf,pad_ct);
|
EVP_DigestUpdate(mc, buf, pad_ct);
|
||||||
|
|
||||||
EVP_DigestUpdate(mc,dgst,l);
|
EVP_DigestUpdate(mc, dgst, l);
|
||||||
|
|
||||||
EVP_DigestFinal(mc,dgst,&l);
|
EVP_DigestFinal(mc, dgst, &l);
|
||||||
|
|
||||||
if(memcmp(mac,dgst,l))
|
if(memcmp(mac, dgst, l))
|
||||||
ERETURN(SSL_BAD_MAC);
|
ERETURN(SSL_BAD_MAC);
|
||||||
|
|
||||||
EVP_MD_CTX_free(mc);
|
EVP_MD_CTX_free(mc);
|
||||||
|
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: ssl_rec.h,v 1.2 2000/10/17 16:10:02 ekr Exp $
|
$Id: ssl_rec.h,v 1.2 2000/10/17 16:10:02 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,24 +44,43 @@
|
||||||
ekr@rtfm.com Wed Aug 18 16:16:23 1999
|
ekr@rtfm.com Wed Aug 18 16:16:23 1999
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _ssl_rec_h
|
#ifndef _ssl_rec_h
|
||||||
#define _ssl_rec_h
|
#define _ssl_rec_h
|
||||||
|
|
||||||
typedef struct ssl_rec_decoder_ ssl_rec_decoder;
|
typedef struct ssl_rec_decoder_ ssl_rec_decoder;
|
||||||
|
|
||||||
int ssl_destroy_rec_decoder PROTO_LIST((ssl_rec_decoder **dp));
|
int ssl_destroy_rec_decoder PROTO_LIST((ssl_rec_decoder * *dp));
|
||||||
int ssl_create_rec_decoder PROTO_LIST((ssl_rec_decoder **dp,
|
int ssl_create_rec_decoder PROTO_LIST(
|
||||||
ssl_obj *ssl,UCHAR *mk,UCHAR *sk,UCHAR *iv));
|
(ssl_rec_decoder * *dp, ssl_obj *ssl, UCHAR *mk, UCHAR *sk, UCHAR *iv));
|
||||||
int ssl_decode_rec_data PROTO_LIST((ssl_obj *ssl,ssl_rec_decoder *d,
|
int ssl_decode_rec_data PROTO_LIST((ssl_obj * ssl,
|
||||||
int ct,int version,UCHAR *in,int inl,UCHAR *out,int *outl));
|
ssl_rec_decoder *d,
|
||||||
int tls13_decode_rec_data PROTO_LIST((ssl_obj *ssl,ssl_rec_decoder *d,int ct,int version,UCHAR *in,int inl,UCHAR *out,int *outl));
|
int ct,
|
||||||
int tls13_update_rec_key PROTO_LIST((ssl_rec_decoder *d,UCHAR *newkey, UCHAR *newiv));
|
int version,
|
||||||
|
UCHAR *in,
|
||||||
|
int inl,
|
||||||
|
UCHAR *out,
|
||||||
|
int *outl));
|
||||||
|
int tls13_decode_rec_data PROTO_LIST((ssl_obj * ssl,
|
||||||
|
ssl_rec_decoder *d,
|
||||||
|
int ct,
|
||||||
|
int version,
|
||||||
|
UCHAR *in,
|
||||||
|
int inl,
|
||||||
|
UCHAR *out,
|
||||||
|
int *outl));
|
||||||
|
int tls13_update_rec_key PROTO_LIST((ssl_rec_decoder * d,
|
||||||
|
UCHAR *newkey,
|
||||||
|
UCHAR *newiv));
|
||||||
|
|
||||||
int ssl3_check_mac(ssl_rec_decoder *d, int ct, int ver, UCHAR *data,
|
int ssl3_check_mac(ssl_rec_decoder *d,
|
||||||
UINT4 datalen, UCHAR *mac);
|
int ct,
|
||||||
|
int ver,
|
||||||
|
UCHAR *data,
|
||||||
|
UINT4 datalen,
|
||||||
|
UCHAR *mac);
|
||||||
|
|
||||||
#define IS_AEAD_CIPHER(cs) (cs->enc==0x3b||cs->enc==0x3c||cs->enc==0x3d||cs->enc==0x3e||cs->enc==0x3f)
|
#define IS_AEAD_CIPHER(cs) \
|
||||||
#define IS_CCM_CIPHER(cs) (cs->enc==0x3e||cs->enc==0x3f)
|
(cs->enc == 0x3b || cs->enc == 0x3c || cs->enc == 0x3d || cs->enc == 0x3e || \
|
||||||
|
cs->enc == 0x3f)
|
||||||
|
#define IS_CCM_CIPHER(cs) (cs->enc == 0x3e || cs->enc == 0x3f)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: sslciphers.h,v 1.3 2002/08/17 01:33:17 ekr Exp $
|
$Id: sslciphers.h,v 1.3 2002/08/17 01:33:17 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,7 +44,6 @@
|
||||||
ekr@rtfm.com Tue Mar 30 18:11:55 1999
|
ekr@rtfm.com Tue Mar 30 18:11:55 1999
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _sslciphers_h
|
#ifndef _sslciphers_h
|
||||||
#define _sslciphers_h
|
#define _sslciphers_h
|
||||||
typedef struct SSL_CipherSuite_ {
|
typedef struct SSL_CipherSuite_ {
|
||||||
|
@ -90,8 +90,6 @@ typedef struct SSL_CipherSuite_ {
|
||||||
#define DIG_SHA384 0x44
|
#define DIG_SHA384 0x44
|
||||||
#define DIG_SHA512 0x45
|
#define DIG_SHA512 0x45
|
||||||
|
|
||||||
int ssl_find_cipher PROTO_LIST((int num,SSL_CipherSuite **cs));
|
int ssl_find_cipher PROTO_LIST((int num, SSL_CipherSuite **cs));
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
1287
ssl/ssldecode.c
1287
ssl/ssldecode.c
File diff suppressed because it is too large
Load diff
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: ssldecode.h,v 1.3 2001/07/20 23:33:16 ekr Exp $
|
$Id: ssldecode.h,v 1.3 2001/07/20 23:33:16 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,40 +44,56 @@
|
||||||
ekr@rtfm.com Thu Apr 1 15:02:02 1999
|
ekr@rtfm.com Thu Apr 1 15:02:02 1999
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _ssldecode_h
|
#ifndef _ssldecode_h
|
||||||
#define _ssldecode_h
|
#define _ssldecode_h
|
||||||
|
|
||||||
#define CRDUMP(a,b,c) P_(P_CR) {Data d; d.data=b; d.len=c; exdump(ssl,a,&d); LF;}
|
#define CRDUMP(a, b, c) \
|
||||||
#define CRDUMPD(a,b) P_(P_CR) {exdump(ssl,a,b);LF;}
|
P_(P_CR) { \
|
||||||
|
Data d; \
|
||||||
|
d.data = b; \
|
||||||
|
d.len = c; \
|
||||||
|
exdump(ssl, a, &d); \
|
||||||
|
LF; \
|
||||||
|
}
|
||||||
|
#define CRDUMPD(a, b) \
|
||||||
|
P_(P_CR) { \
|
||||||
|
exdump(ssl, a, b); \
|
||||||
|
LF; \
|
||||||
|
}
|
||||||
|
|
||||||
int ssl_decode_ctx_create PROTO_LIST((ssl_decode_ctx **ctx,
|
int ssl_decode_ctx_create PROTO_LIST(
|
||||||
char *keyfile,char *password,char *keylogfile));
|
(ssl_decode_ctx * *ctx, char *keyfile, char *password, char *keylogfile));
|
||||||
int ssl_decode_ctx_destroy(ssl_decode_ctx **dp);
|
int ssl_decode_ctx_destroy(ssl_decode_ctx **dp);
|
||||||
int ssl_decoder_destroy PROTO_LIST((ssl_decoder **dp));
|
int ssl_decoder_destroy PROTO_LIST((ssl_decoder * *dp));
|
||||||
int ssl_decoder_create PROTO_LIST((ssl_decoder **dp,ssl_decode_ctx *ctx));
|
int ssl_decoder_create PROTO_LIST((ssl_decoder * *dp, ssl_decode_ctx *ctx));
|
||||||
int ssl_set_client_random PROTO_LIST((ssl_decoder *dp,
|
int ssl_set_client_random PROTO_LIST((ssl_decoder * dp, UCHAR *msg, int len));
|
||||||
UCHAR *msg,int len));
|
int ssl_set_server_random PROTO_LIST((ssl_decoder * dp, UCHAR *msg, int len));
|
||||||
int ssl_set_server_random PROTO_LIST((ssl_decoder *dp,
|
int ssl_set_client_session_id PROTO_LIST((ssl_decoder * dp,
|
||||||
UCHAR *msg,int len));
|
UCHAR *msg,
|
||||||
int ssl_set_client_session_id PROTO_LIST((ssl_decoder *dp,
|
int len));
|
||||||
UCHAR *msg,int len));
|
int ssl_process_server_session_id
|
||||||
int ssl_process_server_session_id PROTO_LIST((ssl_obj *obj,ssl_decoder *dp,
|
PROTO_LIST((ssl_obj * obj, ssl_decoder *dp, UCHAR *msg, int len));
|
||||||
UCHAR *msg,int len));
|
int ssl_process_client_session_id
|
||||||
int ssl_process_client_session_id PROTO_LIST((ssl_obj *obj,ssl_decoder *dp,
|
PROTO_LIST((ssl_obj * obj, ssl_decoder *dp, UCHAR *msg, int len));
|
||||||
UCHAR *msg,int len));
|
int ssl_process_client_key_exchange
|
||||||
int ssl_process_client_key_exchange PROTO_LIST((struct ssl_obj_ *,
|
PROTO_LIST((struct ssl_obj_ *, ssl_decoder *d, UCHAR *msg, int len));
|
||||||
ssl_decoder *d,UCHAR *msg,int len));
|
int ssl_process_change_cipher_spec PROTO_LIST((ssl_obj * ssl,
|
||||||
int ssl_process_change_cipher_spec PROTO_LIST((ssl_obj *ssl,
|
ssl_decoder *d,
|
||||||
ssl_decoder *d,int direction));
|
int direction));
|
||||||
int ssl_update_handshake_messages PROTO_LIST((ssl_obj *ssl,
|
int ssl_update_handshake_messages PROTO_LIST((ssl_obj * ssl, Data *data));
|
||||||
|
int ssl_decode_record PROTO_LIST((ssl_obj * ssl,
|
||||||
|
ssl_decoder *dec,
|
||||||
|
int direction,
|
||||||
|
int ct,
|
||||||
|
int version,
|
||||||
|
Data *d));
|
||||||
|
int ssl_tls13_generate_keying_material PROTO_LIST((ssl_obj * obj,
|
||||||
|
ssl_decoder *dec));
|
||||||
|
int ssl_process_handshake_finished PROTO_LIST((ssl_obj * ssl,
|
||||||
|
ssl_decoder *dec,
|
||||||
Data *data));
|
Data *data));
|
||||||
int ssl_decode_record PROTO_LIST((ssl_obj *ssl,ssl_decoder *dec,int direction,
|
int ssl_tls13_update_keying_material PROTO_LIST((ssl_obj * ssl,
|
||||||
int ct,int version,Data *d));
|
ssl_decoder *dec,
|
||||||
int ssl_tls13_generate_keying_material PROTO_LIST((ssl_obj *obj,ssl_decoder *dec));
|
int dir));
|
||||||
int ssl_process_handshake_finished PROTO_LIST((ssl_obj* ssl,ssl_decoder *dec, Data *data));
|
|
||||||
int ssl_tls13_update_keying_material PROTO_LIST((ssl_obj *ssl,ssl_decoder *dec,int dir));
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
704
ssl/sslprint.c
704
ssl/sslprint.c
File diff suppressed because it is too large
Load diff
139
ssl/sslprint.h
139
ssl/sslprint.h
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: sslprint.h,v 1.3 2000/11/03 06:38:06 ekr Exp $
|
$Id: sslprint.h,v 1.3 2000/11/03 06:38:06 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,66 +44,104 @@
|
||||||
ekr@rtfm.com Wed Feb 10 15:34:14 1999
|
ekr@rtfm.com Wed Feb 10 15:34:14 1999
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _sslprint_h
|
#ifndef _sslprint_h
|
||||||
#define _sslprint_h
|
#define _sslprint_h
|
||||||
|
|
||||||
#include "ssl_analyze.h"
|
#include "ssl_analyze.h"
|
||||||
#include "ssl_h.h"
|
#include "ssl_h.h"
|
||||||
|
|
||||||
int ssl_expand_record PROTO_LIST((ssl_obj *ssl,
|
int ssl_expand_record PROTO_LIST(
|
||||||
segment *q,int direction,UCHAR *data,int len));
|
(ssl_obj * ssl, segment *q, int direction, UCHAR *data, int len));
|
||||||
int ssl_decode_switch PROTO_LIST((ssl_obj *ssl,
|
int ssl_decode_switch PROTO_LIST((ssl_obj * ssl,
|
||||||
decoder *dtable,int value,int dir,segment *seg,Data *data));
|
decoder *dtable,
|
||||||
int ssl_decode_uintX PROTO_LIST((ssl_obj *ssl,char *name,int size,
|
int value,
|
||||||
UINT4 print,Data *data,UINT4 *x));
|
int dir,
|
||||||
int ssl_decode_opaque_array PROTO_LIST((ssl_obj *ssl,char *name,int size,
|
segment *seg,
|
||||||
UINT4 print,Data *data,Data *x));
|
Data *data));
|
||||||
int ssl_decode_enum PROTO_LIST((ssl_obj *ssl,char *name,
|
int ssl_decode_uintX PROTO_LIST(
|
||||||
int size,decoder *decode,UINT4 p,Data *data,
|
(ssl_obj * ssl, char *name, int size, UINT4 print, Data *data, UINT4 *x));
|
||||||
|
int ssl_decode_opaque_array PROTO_LIST(
|
||||||
|
(ssl_obj * ssl, char *name, int size, UINT4 print, Data *data, Data *x));
|
||||||
|
int ssl_decode_enum PROTO_LIST((ssl_obj * ssl,
|
||||||
|
char *name,
|
||||||
|
int size,
|
||||||
|
decoder *decode,
|
||||||
|
UINT4 p,
|
||||||
|
Data *data,
|
||||||
UINT4 *x));
|
UINT4 *x));
|
||||||
int ssl_lookup_enum PROTO_LIST((ssl_obj *ssl,decoder *dtable,
|
int ssl_lookup_enum
|
||||||
UINT4 val,char **ptr));
|
PROTO_LIST((ssl_obj * ssl, decoder *dtable, UINT4 val, char **ptr));
|
||||||
int ssl_print_enum PROTO_LIST((ssl_obj *obj,char *name,
|
int ssl_print_enum
|
||||||
decoder *decode,UINT4 value));
|
PROTO_LIST((ssl_obj * obj, char *name, decoder *decode, UINT4 value));
|
||||||
int ssl_get_enum_str PROTO_LIST((ssl_obj *obj,char *outstr,
|
int ssl_get_enum_str
|
||||||
decoder *decode,UINT4 value));
|
PROTO_LIST((ssl_obj * obj, char *outstr, decoder *decode, UINT4 value));
|
||||||
int print_data PROTO_LIST((ssl_obj *ssl,Data *d));
|
int print_data PROTO_LIST((ssl_obj * ssl, Data *d));
|
||||||
int process_v2_hello PROTO_LIST((ssl_obj *ssl,segment *seg));
|
int process_v2_hello PROTO_LIST((ssl_obj * ssl, segment *seg));
|
||||||
int process_beginning_plaintext PROTO_LIST((ssl_obj *ssl,
|
int process_beginning_plaintext PROTO_LIST((ssl_obj * ssl,
|
||||||
segment *seg,int direction));
|
segment *seg,
|
||||||
int ssl_print_direction_indicator PROTO_LIST((ssl_obj *ssl,int dir));
|
int direction));
|
||||||
int ssl_print_timestamp PROTO_LIST((ssl_obj *ssl,struct timeval *ts));
|
int ssl_print_direction_indicator PROTO_LIST((ssl_obj * ssl, int dir));
|
||||||
int ssl_print_record_num PROTO_LIST((ssl_obj *ssl));
|
int ssl_print_timestamp PROTO_LIST((ssl_obj * ssl, struct timeval *ts));
|
||||||
int ssl_print_cipher_suite PROTO_LIST((ssl_obj *ssl,int version,int p,
|
int ssl_print_record_num PROTO_LIST((ssl_obj * ssl));
|
||||||
UINT4 val));
|
int ssl_print_cipher_suite
|
||||||
|
PROTO_LIST((ssl_obj * ssl, int version, int p, UINT4 val));
|
||||||
|
|
||||||
int explain PROTO_LIST((ssl_obj *ssl,char *format,...));
|
int explain PROTO_LIST((ssl_obj * ssl, char *format, ...));
|
||||||
int exdump PROTO_LIST((ssl_obj *ssl,char *name,Data *data));
|
int exdump PROTO_LIST((ssl_obj * ssl, char *name, Data *data));
|
||||||
int exstr PROTO_LIST((ssl_obj *ssl,char *name,Data *data));
|
int exstr PROTO_LIST((ssl_obj * ssl, char *name, Data *data));
|
||||||
|
|
||||||
|
#define SSL_DECODE_UINT8(a, n, b, c, d) \
|
||||||
|
if((r = ssl_decode_uintX(a, n, 1, b, c, d))) \
|
||||||
|
ERETURN(r)
|
||||||
|
#define SSL_DECODE_UINT16(a, n, b, c, d) \
|
||||||
|
if((r = ssl_decode_uintX(a, n, 2, b, c, d))) \
|
||||||
|
ERETURN(r)
|
||||||
|
#define SSL_DECODE_UINT24(a, n, b, c, d) \
|
||||||
|
if((r = ssl_decode_uintX(a, n, 3, b, c, d))) \
|
||||||
|
ERETURN(r)
|
||||||
|
#define SSL_DECODE_UINT32(a, n, b, c, d) \
|
||||||
|
if((r = ssl_decode_uintX(a, n, 4, b, c, d))) \
|
||||||
|
ERETURN(r)
|
||||||
|
#define SSL_DECODE_OPAQUE_ARRAY(a, n, b, c, d, e) \
|
||||||
|
if((r = ssl_decode_opaque_array(a, n, b, c, d, e))) \
|
||||||
|
ERETURN(r)
|
||||||
|
#define SSL_DECODE_ENUM(a, b, c, d, e, f, g) \
|
||||||
|
if((r = ssl_decode_enum(a, b, c, d, e, f, g))) \
|
||||||
|
ERETURN(r)
|
||||||
|
#define SSL_DECODE_UINT8_ABORT(a, n, b, c, d) \
|
||||||
|
if((r = ssl_decode_uintX(a, n, 1, b, c, d))) \
|
||||||
|
ABORT(r)
|
||||||
|
#define SSL_DECODE_UINT16_ABORT(a, n, b, c, d) \
|
||||||
|
if((r = ssl_decode_uintX(a, n, 2, b, c, d))) \
|
||||||
|
ABORT(r)
|
||||||
|
#define SSL_DECODE_UINT24_ABORT(a, n, b, c, d) \
|
||||||
|
if((r = ssl_decode_uintX(a, n, 3, b, c, d))) \
|
||||||
|
ABORT(r)
|
||||||
|
#define SSL_DECODE_UINT32_ABORT(a, n, b, c, d) \
|
||||||
|
if((r = ssl_decode_uintX(a, n, 4, b, c, d))) \
|
||||||
|
ABORT(r)
|
||||||
|
#define SSL_DECODE_OPAQUE_ARRAY_ABORT(a, n, b, c, d, e) \
|
||||||
|
if((r = ssl_decode_opaque_array(a, n, b, c, d, e))) \
|
||||||
|
ABORT(r)
|
||||||
|
#define SSL_DECODE_ENUM_ABORT(a, b, c, d, e, f, g) \
|
||||||
|
if((r = ssl_decode_enum(a, b, c, d, e, f, g))) \
|
||||||
|
ABORT(r)
|
||||||
|
#define P_(p) if((p == SSL_PRINT_ALL) || (p & SSL_print_flags))
|
||||||
|
|
||||||
#define SSL_DECODE_UINT8(a,n,b,c,d) if((r=ssl_decode_uintX(a,n,1,b,c,d))) ERETURN(r)
|
#define INDENT \
|
||||||
#define SSL_DECODE_UINT16(a,n,b,c,d) if((r=ssl_decode_uintX(a,n,2,b,c,d))) ERETURN(r)
|
if(!(NET_print_flags & NET_PRINT_JSON)) \
|
||||||
#define SSL_DECODE_UINT24(a,n,b,c,d) if((r=ssl_decode_uintX(a,n,3,b,c,d))) ERETURN(r)
|
do { \
|
||||||
#define SSL_DECODE_UINT32(a,n,b,c,d) if((r=ssl_decode_uintX(a,n,4,b,c,d))) ERETURN(r)
|
int i; \
|
||||||
#define SSL_DECODE_OPAQUE_ARRAY(a,n,b,c,d,e) if((r=ssl_decode_opaque_array(a,n,b,c,d,e))) ERETURN(r)
|
for(i = 0; i < (ssl->indent_depth + ssl->indent_name_len); i++) \
|
||||||
#define SSL_DECODE_ENUM(a,b,c,d,e,f,g) if((r=ssl_decode_enum(a,b,c,d,e,f,g))) ERETURN(r)
|
printf("%s", SSL_print_flags &SSL_PRINT_NROFF ? " " : " "); \
|
||||||
#define SSL_DECODE_UINT8_ABORT(a,n,b,c,d) if((r=ssl_decode_uintX(a,n,1,b,c,d))) ABORT(r)
|
} while(0)
|
||||||
#define SSL_DECODE_UINT16_ABORT(a,n,b,c,d) if((r=ssl_decode_uintX(a,n,2,b,c,d))) ABORT(r)
|
#define INDENT_INCR ssl->indent_depth += 2
|
||||||
#define SSL_DECODE_UINT24_ABORT(a,n,b,c,d) if((r=ssl_decode_uintX(a,n,3,b,c,d))) ABORT(r)
|
#define INDENT_POP ssl->indent_depth -= 2
|
||||||
#define SSL_DECODE_UINT32_ABORT(a,n,b,c,d) if((r=ssl_decode_uintX(a,n,4,b,c,d))) ABORT(r)
|
|
||||||
#define SSL_DECODE_OPAQUE_ARRAY_ABORT(a,n,b,c,d,e) if((r=ssl_decode_opaque_array(a,n,b,c,d,e))) ABORT(r)
|
|
||||||
#define SSL_DECODE_ENUM_ABORT(a,b,c,d,e,f,g) if((r=ssl_decode_enum(a,b,c,d,e,f,g))) ABORT(r)
|
|
||||||
#define P_(p) if((p==SSL_PRINT_ALL) || (p & SSL_print_flags))
|
|
||||||
|
|
||||||
#define INDENT if(!(NET_print_flags & NET_PRINT_JSON)) do {int i; for(i=0;i<(ssl->indent_depth + ssl->indent_name_len);i++) printf("%s",SSL_print_flags & SSL_PRINT_NROFF?" ":" ");} while(0)
|
|
||||||
#define INDENT_INCR ssl->indent_depth+=2
|
|
||||||
#define INDENT_POP ssl->indent_depth-=2
|
|
||||||
#define INDENT_NAME(x) ssl->indent_name_len += strlen(x)
|
#define INDENT_NAME(x) ssl->indent_name_len += strlen(x)
|
||||||
#define INDENT_NAME_POP ssl->indent_name_len=0
|
#define INDENT_NAME_POP ssl->indent_name_len = 0
|
||||||
#define LINE_LEFT (80-(ssl->indent_name_len + ssl->indent_depth)
|
#define LINE_LEFT (80-(ssl->indent_name_len + ssl->indent_depth)
|
||||||
#define LF if(!(NET_print_flags & NET_PRINT_JSON)) printf("\n")
|
#define LF \
|
||||||
|
if(!(NET_print_flags & NET_PRINT_JSON)) \
|
||||||
|
printf("\n")
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
186
ssl/sslxprint.c
186
ssl/sslxprint.c
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: sslxprint.c,v 1.3 2000/11/03 06:38:06 ekr Exp $
|
$Id: sslxprint.c,v 1.3 2000/11/03 06:38:06 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,7 +44,6 @@
|
||||||
ekr@rtfm.com Thu Mar 25 21:17:16 1999
|
ekr@rtfm.com Thu Mar 25 21:17:16 1999
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <json.h>
|
#include <json.h>
|
||||||
#include "network.h"
|
#include "network.h"
|
||||||
#include "ssl_h.h"
|
#include "ssl_h.h"
|
||||||
|
@ -57,16 +57,14 @@
|
||||||
|
|
||||||
#define BUFSIZE 1024
|
#define BUFSIZE 1024
|
||||||
|
|
||||||
static int sslx__print_dn PROTO_LIST((ssl_obj *ssl,char *x));
|
static int sslx__print_dn PROTO_LIST((ssl_obj * ssl, char *x));
|
||||||
#ifdef OPENSSL
|
#ifdef OPENSSL
|
||||||
static int sslx__print_serial PROTO_LIST((ssl_obj *ssl,ASN1_INTEGER *a));
|
static int sslx__print_serial PROTO_LIST((ssl_obj * ssl, ASN1_INTEGER *a));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int
|
int sslx_print_certificate(ssl_obj *ssl, Data *data, int pf) {
|
||||||
sslx_print_certificate (ssl_obj *ssl, Data *data, int pf)
|
|
||||||
{
|
|
||||||
#ifdef OPENSSL
|
#ifdef OPENSSL
|
||||||
X509 *x=0;
|
X509 *x = 0;
|
||||||
ASN1_INTEGER *a;
|
ASN1_INTEGER *a;
|
||||||
#endif
|
#endif
|
||||||
UCHAR *d;
|
UCHAR *d;
|
||||||
|
@ -74,7 +72,7 @@ sslx_print_certificate (ssl_obj *ssl, Data *data, int pf)
|
||||||
struct json_object *cert_obj;
|
struct json_object *cert_obj;
|
||||||
|
|
||||||
#ifdef OPENSSL
|
#ifdef OPENSSL
|
||||||
P_(P_ASN){
|
P_(P_ASN) {
|
||||||
char buf[BUFSIZE];
|
char buf[BUFSIZE];
|
||||||
int ext;
|
int ext;
|
||||||
char *b64_cert;
|
char *b64_cert;
|
||||||
|
@ -87,171 +85,167 @@ sslx_print_certificate (ssl_obj *ssl, Data *data, int pf)
|
||||||
|
|
||||||
cert_obj = json_object_new_object();
|
cert_obj = json_object_new_object();
|
||||||
|
|
||||||
d=data->data;
|
d = data->data;
|
||||||
|
|
||||||
if(!(b64_cert=(char *)calloc(1,sizeof(char) * ((((data->len) + 3 - 1)/3) * 4 + 1))))
|
if(!(b64_cert = (char *)calloc(
|
||||||
|
1, sizeof(char) * ((((data->len) + 3 - 1) / 3) * 4 + 1))))
|
||||||
ABORT(R_NO_MEMORY);
|
ABORT(R_NO_MEMORY);
|
||||||
|
|
||||||
EVP_EncodeBlock((unsigned char *)b64_cert, d, data->len);
|
EVP_EncodeBlock((unsigned char *)b64_cert, d, data->len);
|
||||||
json_object_object_add(cert_obj, "cert_der", json_object_new_string(b64_cert));
|
json_object_object_add(cert_obj, "cert_der",
|
||||||
|
json_object_new_string(b64_cert));
|
||||||
free(b64_cert);
|
free(b64_cert);
|
||||||
|
|
||||||
if(!(x=d2i_X509(0,(const unsigned char **) &d,data->len))){
|
if(!(x = d2i_X509(0, (const unsigned char **)&d, data->len))) {
|
||||||
explain(ssl,"Bad certificate");
|
explain(ssl, "Bad certificate");
|
||||||
ABORT(R_BAD_DATA);
|
ABORT(R_BAD_DATA);
|
||||||
}
|
}
|
||||||
X509_NAME_oneline(X509_get_subject_name(x),buf,
|
X509_NAME_oneline(X509_get_subject_name(x), buf, BUFSIZE);
|
||||||
BUFSIZE);
|
explain(ssl, "Subject\n");
|
||||||
explain(ssl,"Subject\n");
|
|
||||||
INDENT_INCR;
|
INDENT_INCR;
|
||||||
json_object_object_add(cert_obj, "cert_subject", json_object_new_string(buf));
|
json_object_object_add(cert_obj, "cert_subject",
|
||||||
sslx__print_dn(ssl,buf);
|
json_object_new_string(buf));
|
||||||
|
sslx__print_dn(ssl, buf);
|
||||||
INDENT_POP;
|
INDENT_POP;
|
||||||
X509_NAME_oneline(X509_get_issuer_name(x),buf,
|
X509_NAME_oneline(X509_get_issuer_name(x), buf, BUFSIZE);
|
||||||
BUFSIZE);
|
explain(ssl, "Issuer\n");
|
||||||
explain(ssl,"Issuer\n");
|
|
||||||
INDENT_INCR;
|
INDENT_INCR;
|
||||||
json_object_object_add(cert_obj, "cert_issuer", json_object_new_string(buf));
|
json_object_object_add(cert_obj, "cert_issuer",
|
||||||
sslx__print_dn(ssl,buf);
|
json_object_new_string(buf));
|
||||||
|
sslx__print_dn(ssl, buf);
|
||||||
INDENT_POP;
|
INDENT_POP;
|
||||||
a=X509_get_serialNumber(x);
|
a = X509_get_serialNumber(x);
|
||||||
explain(ssl,"Serial ");
|
explain(ssl, "Serial ");
|
||||||
if(!(serial_str=(char *)calloc(1,sizeof(char) * (a->length * 3))))
|
if(!(serial_str = (char *)calloc(1, sizeof(char) * (a->length * 3))))
|
||||||
ABORT(R_NO_MEMORY);
|
ABORT(R_NO_MEMORY);
|
||||||
INIT_DATA(data_tmp,a->data,a->length);
|
INIT_DATA(data_tmp, a->data, a->length);
|
||||||
exstr(ssl, serial_str, &data_tmp);
|
exstr(ssl, serial_str, &data_tmp);
|
||||||
json_object_object_add(cert_obj, "cert_serial", json_object_new_string(serial_str));
|
json_object_object_add(cert_obj, "cert_serial",
|
||||||
|
json_object_new_string(serial_str));
|
||||||
free(serial_str);
|
free(serial_str);
|
||||||
sslx__print_serial(ssl,a);
|
sslx__print_serial(ssl, a);
|
||||||
|
|
||||||
ext=X509_get_ext_count(x);
|
ext = X509_get_ext_count(x);
|
||||||
if(ext>0){
|
if(ext > 0) {
|
||||||
int i,j;
|
int i, j;
|
||||||
UCHAR buf[1024];
|
UCHAR buf[1024];
|
||||||
|
|
||||||
explain(ssl,"Extensions\n");
|
explain(ssl, "Extensions\n");
|
||||||
INDENT_INCR;
|
INDENT_INCR;
|
||||||
for(i=0;i<ext;i++){
|
for(i = 0; i < ext; i++) {
|
||||||
X509_EXTENSION *ex;
|
X509_EXTENSION *ex;
|
||||||
ASN1_OBJECT *obj;
|
ASN1_OBJECT *obj;
|
||||||
|
|
||||||
ex=X509_get_ext(x,i);
|
ex = X509_get_ext(x, i);
|
||||||
obj=X509_EXTENSION_get_object(ex);
|
obj = X509_EXTENSION_get_object(ex);
|
||||||
i2t_ASN1_OBJECT((char *)buf,sizeof(buf),obj);
|
i2t_ASN1_OBJECT((char *)buf, sizeof(buf), obj);
|
||||||
|
|
||||||
explain(ssl,"Extension: %s\n",buf);
|
explain(ssl, "Extension: %s\n", buf);
|
||||||
j=X509_EXTENSION_get_critical(ex);
|
j = X509_EXTENSION_get_critical(ex);
|
||||||
if(j){
|
if(j) {
|
||||||
INDENT;
|
INDENT;
|
||||||
explain(ssl,"Critical\n");
|
explain(ssl, "Critical\n");
|
||||||
}
|
}
|
||||||
if(SSL_print_flags & SSL_PRINT_NROFF){
|
if(SSL_print_flags & SSL_PRINT_NROFF) {
|
||||||
if(ssl->process_ciphertext&ssl->direction)
|
if(ssl->process_ciphertext & ssl->direction)
|
||||||
printf("\\f(CI");
|
printf("\\f(CI");
|
||||||
else
|
else
|
||||||
printf("\\fC");
|
printf("\\fC");
|
||||||
|
|
||||||
INDENT_INCR;
|
INDENT_INCR;
|
||||||
INDENT;
|
INDENT;
|
||||||
if(!X509V3_EXT_print_fp(stdout,ex,0,0)){
|
if(!X509V3_EXT_print_fp(stdout, ex, 0, 0)) {
|
||||||
printf("Hex value");
|
printf("Hex value");
|
||||||
}
|
}
|
||||||
INDENT_POP;
|
INDENT_POP;
|
||||||
explain(ssl,"\n");
|
explain(ssl, "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
INDENT_POP;
|
INDENT_POP;
|
||||||
|
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
#endif
|
#endif
|
||||||
P_(pf){
|
P_(pf) { exdump(ssl, "certificate", data); }
|
||||||
exdump(ssl,"certificate",data);
|
|
||||||
}
|
|
||||||
#ifdef OPENSSL
|
#ifdef OPENSSL
|
||||||
}
|
}
|
||||||
|
|
||||||
struct json_object *certs_array;
|
struct json_object *certs_array;
|
||||||
json_object_object_get_ex(jobj, "cert_chain", &certs_array);
|
json_object_object_get_ex(jobj, "cert_chain", &certs_array);
|
||||||
json_object_array_add(certs_array,cert_obj);
|
json_object_array_add(certs_array, cert_obj);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_status=0;
|
_status = 0;
|
||||||
abort:
|
abort:
|
||||||
#ifdef OPENSSL
|
#ifdef OPENSSL
|
||||||
if(x) X509_free(x);
|
if(x)
|
||||||
|
X509_free(x);
|
||||||
#endif
|
#endif
|
||||||
if(_status && cert_obj) json_object_put(cert_obj);
|
if(_status && cert_obj)
|
||||||
return(_status);
|
json_object_put(cert_obj);
|
||||||
}
|
return (_status);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int sslx_print_dn(ssl_obj *ssl, Data *data, int pf) {
|
||||||
sslx_print_dn (ssl_obj *ssl, Data *data, int pf)
|
|
||||||
{
|
|
||||||
UCHAR buf[BUFSIZE];
|
UCHAR buf[BUFSIZE];
|
||||||
int _status;
|
int _status;
|
||||||
UCHAR *d=data->data;
|
UCHAR *d = data->data;
|
||||||
#ifdef OPENSSL
|
#ifdef OPENSSL
|
||||||
X509_NAME *n=0;
|
X509_NAME *n = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
P_(pf){
|
P_(pf){
|
||||||
#ifdef OPENSSL
|
#ifdef OPENSSL
|
||||||
P_(P_ASN){
|
P_(P_ASN){if(!(n = d2i_X509_NAME(0, (const unsigned char **)&d,
|
||||||
if(!(n=d2i_X509_NAME(0,(const unsigned char **) &d,data->len)))
|
data->len))) ABORT(R_BAD_DATA);
|
||||||
ABORT(R_BAD_DATA);
|
X509_NAME_oneline(n, (char *)buf, BUFSIZE);
|
||||||
X509_NAME_oneline(n,(char *)buf,BUFSIZE);
|
sslx__print_dn(ssl, (char *)buf);
|
||||||
sslx__print_dn(ssl,(char *)buf);
|
}
|
||||||
}
|
else {
|
||||||
else{
|
|
||||||
#endif
|
#endif
|
||||||
exdump(ssl,0,data);
|
exdump(ssl, 0, data);
|
||||||
#ifdef OPENSSL
|
#ifdef OPENSSL
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
_status=0;
|
_status = 0;
|
||||||
abort:
|
abort :
|
||||||
#ifdef OPENSSL
|
#ifdef OPENSSL
|
||||||
if(n) X509_NAME_free(n);
|
if(n) X509_NAME_free(n);
|
||||||
#endif
|
#endif
|
||||||
return(_status);
|
return (_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int sslx__print_dn(ssl_obj *ssl, char *x) {
|
||||||
sslx__print_dn (ssl_obj *ssl, char *x)
|
|
||||||
{
|
|
||||||
char *slash;
|
char *slash;
|
||||||
|
|
||||||
if(*x=='/') x++;
|
if(*x == '/')
|
||||||
|
x++;
|
||||||
|
|
||||||
while (x){
|
while(x) {
|
||||||
if((slash=strchr(x,'/'))){
|
if((slash = strchr(x, '/'))) {
|
||||||
*slash=0;
|
*slash = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
explain(ssl,"%s\n",x);
|
explain(ssl, "%s\n", x);
|
||||||
|
|
||||||
x=slash?slash+1:0;
|
x = slash ? slash + 1 : 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef OPENSSL
|
#ifdef OPENSSL
|
||||||
static int
|
static int sslx__print_serial(ssl_obj *ssl, ASN1_INTEGER *a) {
|
||||||
sslx__print_serial (ssl_obj *ssl, ASN1_INTEGER *a)
|
|
||||||
{
|
|
||||||
Data d;
|
Data d;
|
||||||
|
|
||||||
if(a->length==0)
|
if(a->length == 0)
|
||||||
printf("0");
|
printf("0");
|
||||||
|
|
||||||
INIT_DATA(d,a->data,a->length);
|
INIT_DATA(d, a->data, a->length);
|
||||||
exdump(ssl,0,&d);
|
exdump(ssl, 0, &d);
|
||||||
|
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -35,7 +35,8 @@
|
||||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH DAMAGE.
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
$Id: sslxprint.h,v 1.2 2000/10/17 16:10:02 ekr Exp $
|
$Id: sslxprint.h,v 1.2 2000/10/17 16:10:02 ekr Exp $
|
||||||
|
|
||||||
|
@ -43,12 +44,10 @@
|
||||||
ekr@rtfm.com Thu Mar 25 21:23:34 1999
|
ekr@rtfm.com Thu Mar 25 21:23:34 1999
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _sslxprint_h
|
#ifndef _sslxprint_h
|
||||||
#define _sslxprint_h
|
#define _sslxprint_h
|
||||||
|
|
||||||
int sslx_print_certificate PROTO_LIST((ssl_obj *ssl,Data *data,int pf));
|
int sslx_print_certificate PROTO_LIST((ssl_obj * ssl, Data *data, int pf));
|
||||||
int sslx_print_dn PROTO_LIST((ssl_obj *ssl,Data *data,int pf));
|
int sslx_print_dn PROTO_LIST((ssl_obj * ssl, Data *data, int pf));
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue