mirror of
https://github.com/adulau/ssldump.git
synced 2024-11-21 08:57: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
424
base/network.c
424
base/network.c
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,8 +44,6 @@
|
|||
ekr@rtfm.com Tue Dec 29 09:52:54 1998
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <r_common.h>
|
||||
#include "network.h"
|
||||
|
@ -64,248 +63,251 @@
|
|||
UINT4 NET_print_flags;
|
||||
|
||||
struct network_handler_ {
|
||||
proto_mod *mod;
|
||||
proto_ctx *ctx;
|
||||
proto_mod *mod;
|
||||
proto_ctx *ctx;
|
||||
};
|
||||
|
||||
int
|
||||
network_handler_create (proto_mod *mod, n_handler **handlerp)
|
||||
{
|
||||
int r,_status;
|
||||
n_handler *handler=0;
|
||||
|
||||
if(!(handler=(n_handler *)malloc(sizeof(n_handler))))
|
||||
ABORT(R_NO_MEMORY);
|
||||
if(mod->vtbl->create_ctx){
|
||||
if((r=mod->vtbl->create_ctx(mod->handle,&handler->ctx)))
|
||||
ABORT(r);
|
||||
}
|
||||
handler->mod=mod;
|
||||
*handlerp=handler;
|
||||
_status=0;
|
||||
abort:
|
||||
if(_status){
|
||||
network_handler_destroy(mod, &handler);
|
||||
}
|
||||
return(_status);
|
||||
int network_handler_create(proto_mod *mod, n_handler **handlerp) {
|
||||
int r, _status;
|
||||
n_handler *handler = 0;
|
||||
|
||||
if(!(handler = (n_handler *)malloc(sizeof(n_handler))))
|
||||
ABORT(R_NO_MEMORY);
|
||||
if(mod->vtbl->create_ctx) {
|
||||
if((r = mod->vtbl->create_ctx(mod->handle, &handler->ctx)))
|
||||
ABORT(r);
|
||||
}
|
||||
handler->mod = mod;
|
||||
*handlerp = handler;
|
||||
_status = 0;
|
||||
abort:
|
||||
if(_status) {
|
||||
network_handler_destroy(mod, &handler);
|
||||
}
|
||||
return (_status);
|
||||
}
|
||||
|
||||
int network_handler_destroy(proto_mod *mod, n_handler **handlerp) {
|
||||
n_handler *handler = 0;
|
||||
if(!handlerp || !*handlerp)
|
||||
return (0);
|
||||
|
||||
handler = *handlerp;
|
||||
|
||||
mod->vtbl->destroy_ctx(mod->handle, &handler->ctx);
|
||||
free(*handlerp);
|
||||
*handlerp = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int network_process_packet(n_handler *handler,
|
||||
struct timeval *timestamp,
|
||||
UCHAR *data,
|
||||
int length,
|
||||
int af) {
|
||||
int r;
|
||||
int hlen;
|
||||
packet p;
|
||||
u_short off;
|
||||
int proto;
|
||||
|
||||
/*We can pretty much ignore all the options*/
|
||||
memcpy(&p.ts, timestamp, sizeof(struct timeval));
|
||||
p.base = data;
|
||||
p._len = length;
|
||||
p.data = data;
|
||||
p.len = length;
|
||||
p.af = af;
|
||||
|
||||
if(p.len < 20) {
|
||||
if(!(NET_print_flags & NET_PRINT_JSON))
|
||||
printf(
|
||||
"Malformed packet, packet too small to contain IP header, skipping "
|
||||
"...\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
network_handler_destroy (proto_mod *mod, n_handler **handlerp)
|
||||
{
|
||||
n_handler *handler=0;
|
||||
if(!handlerp || !*handlerp)
|
||||
return(0);
|
||||
memset(&p.i_addr.so_st, 0x0, sizeof(struct sockaddr_storage));
|
||||
memset(&p.r_addr.so_st, 0x0, sizeof(struct sockaddr_storage));
|
||||
|
||||
handler = *handlerp;
|
||||
if(af == AF_INET) {
|
||||
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));
|
||||
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));
|
||||
p.r_addr.so_in.sin_family = AF_INET;
|
||||
|
||||
mod->vtbl->destroy_ctx(mod->handle,&handler->ctx);
|
||||
free(*handlerp);
|
||||
*handlerp=0;
|
||||
return(0);
|
||||
}
|
||||
/*Handle, or rather mishandle, fragmentation*/
|
||||
off = ntohs(p.l3_hdr.ip->ip_off);
|
||||
|
||||
int
|
||||
network_process_packet (n_handler *handler, struct timeval *timestamp, UCHAR *data, int length, int af)
|
||||
{
|
||||
int r;
|
||||
int hlen;
|
||||
packet p;
|
||||
u_short off;
|
||||
int proto;
|
||||
|
||||
/*We can pretty much ignore all the options*/
|
||||
memcpy(&p.ts,timestamp,sizeof(struct timeval));
|
||||
p.base=data;
|
||||
p._len=length;
|
||||
p.data=data;
|
||||
p.len=length;
|
||||
p.af=af;
|
||||
if((off & 0x1fff) || /*Later fragment*/
|
||||
(off & 0x2000)) { /*More fragments*/
|
||||
/* fprintf(stderr,"Fragmented packet! rejecting\n"); */
|
||||
return (0);
|
||||
}
|
||||
|
||||
if(p.len < 20) {
|
||||
hlen = p.l3_hdr.ip->ip_hl * 4;
|
||||
p.data += hlen;
|
||||
p.len = ntohs(p.l3_hdr.ip->ip_len);
|
||||
|
||||
if(p.len > length) {
|
||||
if(!(NET_print_flags & NET_PRINT_JSON))
|
||||
printf("Malformed packet, packet too small to contain IP header, skipping ...\n");
|
||||
return(0);
|
||||
printf(
|
||||
"Malformed packet, size from IP header is larger than size "
|
||||
"reported by libpcap, skipping ...\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
memset(&p.i_addr.so_st, 0x0, sizeof(struct sockaddr_storage));
|
||||
memset(&p.r_addr.so_st, 0x0, sizeof(struct sockaddr_storage));
|
||||
if(p.len == 0) {
|
||||
DBG((0,
|
||||
"ip length reported as 0, presumed to be because of 'TCP "
|
||||
"segmentation offload' (TSO)\n"));
|
||||
p.len = p._len;
|
||||
}
|
||||
p.len -= hlen;
|
||||
|
||||
if(af == AF_INET) {
|
||||
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));
|
||||
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));
|
||||
p.r_addr.so_in.sin_family = AF_INET;
|
||||
|
||||
/*Handle, or rather mishandle, fragmentation*/
|
||||
off=ntohs(p.l3_hdr.ip->ip_off);
|
||||
|
||||
if((off & 0x1fff) || /*Later fragment*/
|
||||
(off & 0x2000)){ /*More fragments*/
|
||||
/* fprintf(stderr,"Fragmented packet! rejecting\n"); */
|
||||
return(0);
|
||||
}
|
||||
|
||||
hlen=p.l3_hdr.ip->ip_hl * 4;
|
||||
p.data += hlen;
|
||||
p.len = ntohs(p.l3_hdr.ip->ip_len);
|
||||
|
||||
if(p.len > length) {
|
||||
if(!(NET_print_flags & NET_PRINT_JSON))
|
||||
printf("Malformed packet, size from IP header is larger than size reported by libpcap, skipping ...\n");
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (p.len == 0) {
|
||||
DBG((0,"ip length reported as 0, presumed to be because of 'TCP segmentation offload' (TSO)\n"));
|
||||
p.len = p._len;
|
||||
}
|
||||
p.len -= hlen;
|
||||
|
||||
proto = p.l3_hdr.ip->ip_p;
|
||||
} else {
|
||||
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));
|
||||
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));
|
||||
p.r_addr.so_in6.sin6_family = AF_INET6;
|
||||
// Skip packets with header extensions
|
||||
if(p.l3_hdr.ip6->ip6_ctlun.ip6_un1.ip6_un1_nxt != IPPROTO_TCP) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
hlen=40; // Fixed header size with no extension
|
||||
p.data += hlen;
|
||||
p.len = ntohs(p.l3_hdr.ip6->ip6_ctlun.ip6_un1.ip6_un1_plen);
|
||||
if(p.len > length) {
|
||||
if(!(NET_print_flags & NET_PRINT_JSON))
|
||||
printf("Malformed packet, size from IP header is larger than size reported by libpcap, skipping ...\n");
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (p.len == 0) {
|
||||
DBG((0,"ip length reported as 0, presumed to be because of 'TCP segmentation offload' (TSO)\n"));
|
||||
p.len = p._len;
|
||||
}
|
||||
|
||||
proto = p.l3_hdr.ip6->ip6_ctlun.ip6_un1.ip6_un1_nxt;
|
||||
proto = p.l3_hdr.ip->ip_p;
|
||||
} else {
|
||||
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));
|
||||
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));
|
||||
p.r_addr.so_in6.sin6_family = AF_INET6;
|
||||
// Skip packets with header extensions
|
||||
if(p.l3_hdr.ip6->ip6_ctlun.ip6_un1.ip6_un1_nxt != IPPROTO_TCP) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch(proto){
|
||||
case IPPROTO_TCP:
|
||||
if((r=process_tcp_packet(handler->mod,handler->ctx,&p)))
|
||||
ERETURN(r);
|
||||
break;
|
||||
hlen = 40; // Fixed header size with no extension
|
||||
p.data += hlen;
|
||||
p.len = ntohs(p.l3_hdr.ip6->ip6_ctlun.ip6_un1.ip6_un1_plen);
|
||||
if(p.len > length) {
|
||||
if(!(NET_print_flags & NET_PRINT_JSON))
|
||||
printf(
|
||||
"Malformed packet, size from IP header is larger than size "
|
||||
"reported by libpcap, skipping ...\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
return(0);
|
||||
if(p.len == 0) {
|
||||
DBG((0,
|
||||
"ip length reported as 0, presumed to be because of 'TCP "
|
||||
"segmentation offload' (TSO)\n"));
|
||||
p.len = p._len;
|
||||
}
|
||||
|
||||
proto = p.l3_hdr.ip6->ip6_ctlun.ip6_un1.ip6_un1_nxt;
|
||||
}
|
||||
|
||||
int
|
||||
packet_copy (packet *in, packet **out)
|
||||
{
|
||||
int _status;
|
||||
|
||||
packet *p=0;
|
||||
|
||||
if(!(p=(packet *)calloc(1,sizeof(packet))))
|
||||
ABORT(R_NO_MEMORY);
|
||||
|
||||
memcpy(&p->ts,&in->ts,sizeof(struct timeval));
|
||||
if(!(p->base=(UCHAR *)malloc(in->_len)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
memcpy(p->base,in->base,p->_len=in->_len);
|
||||
|
||||
p->data=p->base + (in->data - in->base);
|
||||
p->len=in->len;
|
||||
|
||||
p->ip=(struct ip *)(p->base + ((UCHAR *)in->ip - in->base));
|
||||
p->tcp=(struct tcphdr *)(p->base + ((UCHAR *)in->tcp - in->base));
|
||||
|
||||
*out=p;
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
if(_status){
|
||||
packet_destroy(p);
|
||||
}
|
||||
return(_status);
|
||||
switch(proto) {
|
||||
case IPPROTO_TCP:
|
||||
if((r = process_tcp_packet(handler->mod, handler->ctx, &p)))
|
||||
ERETURN(r);
|
||||
break;
|
||||
}
|
||||
|
||||
int
|
||||
packet_destroy (packet *p)
|
||||
{
|
||||
if(!p)
|
||||
return(0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
FREE(p->base);
|
||||
FREE(p);
|
||||
return(0);
|
||||
int packet_copy(packet *in, packet **out) {
|
||||
int _status;
|
||||
|
||||
packet *p = 0;
|
||||
|
||||
if(!(p = (packet *)calloc(1, sizeof(packet))))
|
||||
ABORT(R_NO_MEMORY);
|
||||
|
||||
memcpy(&p->ts, &in->ts, sizeof(struct timeval));
|
||||
if(!(p->base = (UCHAR *)malloc(in->_len)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
memcpy(p->base, in->base, p->_len = in->_len);
|
||||
|
||||
p->data = p->base + (in->data - in->base);
|
||||
p->len = in->len;
|
||||
|
||||
p->ip = (struct ip *)(p->base + ((UCHAR *)in->ip - in->base));
|
||||
p->tcp = (struct tcphdr *)(p->base + ((UCHAR *)in->tcp - in->base));
|
||||
|
||||
*out = p;
|
||||
|
||||
_status = 0;
|
||||
abort:
|
||||
if(_status) {
|
||||
packet_destroy(p);
|
||||
}
|
||||
|
||||
int
|
||||
timestamp_diff (struct timeval *t1, struct timeval *t0, struct timeval *diff)
|
||||
{
|
||||
long d;
|
||||
return (_status);
|
||||
}
|
||||
|
||||
if(t0->tv_sec > t1->tv_sec)
|
||||
ERETURN(R_BAD_ARGS);
|
||||
int packet_destroy(packet *p) {
|
||||
if(!p)
|
||||
return (0);
|
||||
|
||||
/*Easy case*/
|
||||
if(t0->tv_usec <= t1->tv_usec){
|
||||
diff->tv_sec=t1->tv_sec - t0->tv_sec;
|
||||
diff->tv_usec=t1->tv_usec - t0->tv_usec;
|
||||
return(0);
|
||||
}
|
||||
FREE(p->base);
|
||||
FREE(p);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*Hard case*/
|
||||
d=t0->tv_usec - t1->tv_usec;
|
||||
if(t1->tv_sec < (t0->tv_sec + 1))
|
||||
ERETURN(R_BAD_ARGS);
|
||||
diff->tv_sec=t1->tv_sec - (t0->tv_sec + 1);
|
||||
diff->tv_usec=1000000 - d;
|
||||
int timestamp_diff(struct timeval *t1,
|
||||
struct timeval *t0,
|
||||
struct timeval *diff) {
|
||||
long d;
|
||||
|
||||
return(0);
|
||||
if(t0->tv_sec > t1->tv_sec)
|
||||
ERETURN(R_BAD_ARGS);
|
||||
|
||||
/*Easy case*/
|
||||
if(t0->tv_usec <= t1->tv_usec) {
|
||||
diff->tv_sec = t1->tv_sec - t0->tv_sec;
|
||||
diff->tv_usec = t1->tv_usec - t0->tv_usec;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*Hard case*/
|
||||
d = t0->tv_usec - t1->tv_usec;
|
||||
if(t1->tv_sec < (t0->tv_sec + 1))
|
||||
ERETURN(R_BAD_ARGS);
|
||||
diff->tv_sec = t1->tv_sec - (t0->tv_sec + 1);
|
||||
diff->tv_usec = 1000000 - d;
|
||||
|
||||
int
|
||||
lookuphostname (struct sockaddr_storage *so_st, char **namep)
|
||||
{
|
||||
int r = 1;
|
||||
*namep = calloc(1, NI_MAXHOST);
|
||||
void *addr = NULL;
|
||||
return (0);
|
||||
}
|
||||
|
||||
if(!(NET_print_flags & NET_PRINT_NO_RESOLVE)) {
|
||||
r = getnameinfo((struct sockaddr *) so_st, sizeof(struct sockaddr_storage), *namep, NI_MAXHOST, NULL, 0, 0);
|
||||
}
|
||||
int lookuphostname(struct sockaddr_storage *so_st, char **namep) {
|
||||
int r = 1;
|
||||
*namep = calloc(1, NI_MAXHOST);
|
||||
void *addr = NULL;
|
||||
|
||||
if(r) {
|
||||
if(so_st->ss_family == AF_INET) {
|
||||
addr = &((struct sockaddr_in *) so_st)->sin_addr;
|
||||
} else {
|
||||
addr = &((struct sockaddr_in6 *) so_st)->sin6_addr;
|
||||
}
|
||||
inet_ntop(so_st->ss_family, addr, *namep, INET6_ADDRSTRLEN);
|
||||
}
|
||||
|
||||
return(0);
|
||||
if(!(NET_print_flags & NET_PRINT_NO_RESOLVE)) {
|
||||
r = getnameinfo((struct sockaddr *)so_st, sizeof(struct sockaddr_storage),
|
||||
*namep, NI_MAXHOST, NULL, 0, 0);
|
||||
}
|
||||
|
||||
int
|
||||
addrtotext (struct sockaddr_storage *so_st, char **namep)
|
||||
{
|
||||
*namep = calloc(1, NI_MAXHOST);
|
||||
void *addr = NULL;
|
||||
|
||||
if(r) {
|
||||
if(so_st->ss_family == AF_INET) {
|
||||
addr = &((struct sockaddr_in *) so_st)->sin_addr;
|
||||
addr = &((struct sockaddr_in *)so_st)->sin_addr;
|
||||
} 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);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int addrtotext(struct sockaddr_storage *so_st, char **namep) {
|
||||
*namep = calloc(1, NI_MAXHOST);
|
||||
void *addr = NULL;
|
||||
|
||||
if(so_st->ss_family == AF_INET) {
|
||||
addr = &((struct sockaddr_in *)so_st)->sin_addr;
|
||||
} else {
|
||||
addr = &((struct sockaddr_in6 *)so_st)->sin6_addr;
|
||||
}
|
||||
inet_ntop(so_st->ss_family, addr, *namep, INET6_ADDRSTRLEN);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,7 +44,6 @@
|
|||
ekr@rtfm.com Tue Dec 29 09:53:50 1998
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _network_h
|
||||
#define _network_h
|
||||
|
||||
|
@ -74,44 +74,47 @@ typedef struct proto_mod_ proto_mod;
|
|||
typedef struct proto_handler_ proto_handler;
|
||||
typedef struct packet_ packet;
|
||||
|
||||
int network_handler_create 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,
|
||||
struct timeval *timestamp,UCHAR *data,int length,int af));
|
||||
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));
|
||||
int lookuphostname PROTO_LIST((struct sockaddr_storage *addr,char **name));
|
||||
int addrtotext PROTO_LIST((struct sockaddr_storage *addr,char **name));
|
||||
int network_handler_create 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,
|
||||
struct timeval *timestamp,
|
||||
UCHAR *data,
|
||||
int length,
|
||||
int af));
|
||||
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));
|
||||
int lookuphostname PROTO_LIST((struct sockaddr_storage * addr, char **name));
|
||||
int addrtotext PROTO_LIST((struct sockaddr_storage * addr, char **name));
|
||||
|
||||
struct packet_ {
|
||||
struct timeval ts;
|
||||
UCHAR *base; /*The base of the packet*/
|
||||
int _len;
|
||||
UCHAR *data; /*The data ptr appropriate to this layer*/
|
||||
int len; /*The length of the data segment*/
|
||||
|
||||
/*These just save us the effort of doing casts to the data
|
||||
segments*/
|
||||
struct ip *ip; /*The IP header*/
|
||||
int af;
|
||||
union {
|
||||
struct ip *ip; /*The IP header*/
|
||||
struct ip6_hdr *ip6; /*The IP header*/
|
||||
} l3_hdr;
|
||||
struct tcphdr *tcp; /*The TCP header*/
|
||||
union {
|
||||
struct sockaddr_storage so_st;
|
||||
struct sockaddr_in so_in;
|
||||
struct sockaddr_in6 so_in6;
|
||||
} i_addr;
|
||||
union {
|
||||
struct sockaddr_storage so_st;
|
||||
struct sockaddr_in so_in;
|
||||
struct sockaddr_in6 so_in6;
|
||||
} r_addr;
|
||||
struct timeval ts;
|
||||
UCHAR *base; /*The base of the packet*/
|
||||
int _len;
|
||||
UCHAR *data; /*The data ptr appropriate to this layer*/
|
||||
int len; /*The length of the data segment*/
|
||||
|
||||
/*These just save us the effort of doing casts to the data
|
||||
segments*/
|
||||
struct ip *ip; /*The IP header*/
|
||||
int af;
|
||||
union {
|
||||
struct ip *ip; /*The IP header*/
|
||||
struct ip6_hdr *ip6; /*The IP header*/
|
||||
} l3_hdr;
|
||||
struct tcphdr *tcp; /*The TCP header*/
|
||||
union {
|
||||
struct sockaddr_storage so_st;
|
||||
struct sockaddr_in so_in;
|
||||
struct sockaddr_in6 so_in6;
|
||||
} i_addr;
|
||||
union {
|
||||
struct sockaddr_storage so_st;
|
||||
struct sockaddr_in so_in;
|
||||
struct sockaddr_in6 so_in6;
|
||||
} r_addr;
|
||||
};
|
||||
|
||||
#include "tcpconn.h"
|
||||
|
@ -119,11 +122,10 @@ struct packet_ {
|
|||
|
||||
extern UINT4 NET_print_flags;
|
||||
|
||||
#define NET_PRINT_TCP_HDR 1
|
||||
#define NET_PRINT_TYPESET 2
|
||||
#define NET_PRINT_ACKS 4
|
||||
#define NET_PRINT_NO_RESOLVE 8
|
||||
#define NET_PRINT_JSON 16
|
||||
#define NET_PRINT_TS 32
|
||||
#define NET_PRINT_TCP_HDR 1
|
||||
#define NET_PRINT_TYPESET 2
|
||||
#define NET_PRINT_ACKS 4
|
||||
#define NET_PRINT_NO_RESOLVE 8
|
||||
#define NET_PRINT_JSON 16
|
||||
#define NET_PRINT_TS 32
|
||||
#endif
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
with the distribution.
|
||||
3. All advertising materials mentioning features or use of this
|
||||
software must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -46,9 +46,6 @@
|
|||
ekr@rtfm.com Tue Dec 29 10:17:41 1998
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include <pcap.h>
|
||||
#include <unistd.h>
|
||||
#ifndef __OpenBSD__
|
||||
|
@ -80,493 +77,491 @@
|
|||
#include "pcap_logger.h"
|
||||
|
||||
#ifndef ETHERTYPE_8021Q
|
||||
# define ETHERTYPE_8021Q 0x8100
|
||||
#define ETHERTYPE_8021Q 0x8100
|
||||
#endif
|
||||
|
||||
char *collapse_args PROTO_LIST((int argc,char **argv));
|
||||
static int pcap_if_type=DLT_NULL;
|
||||
int err_exit PROTO_LIST((char *str,int num));
|
||||
char *collapse_args PROTO_LIST((int argc, char **argv));
|
||||
static int pcap_if_type = DLT_NULL;
|
||||
int err_exit PROTO_LIST((char *str, int num));
|
||||
int usage PROTO_LIST((void));
|
||||
int print_version PROTO_LIST((void));
|
||||
void sig_handler PROTO_LIST((int sig));
|
||||
void pcap_cb PROTO_LIST((u_char *ptr,const struct pcap_pkthdr *hdr,const u_char *data));
|
||||
int main PROTO_LIST((int argc,char **argv));
|
||||
void pcap_cb PROTO_LIST((u_char * ptr,
|
||||
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 conn_freq = 100; // Number of packets after which a connection pool
|
||||
// cleaning is performed
|
||||
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) {0}; // last block of conn_freq packets seen
|
||||
int packet_cnt = 0; // Packet counter used for connection pool cleaning
|
||||
int conn_freq = 100; // Number of packets after which a connection pool
|
||||
// cleaning is performed
|
||||
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){0}; // last block of conn_freq packets seen
|
||||
|
||||
logger_mod *logger=NULL;
|
||||
logger_mod *logger = NULL;
|
||||
|
||||
int
|
||||
err_exit (char *str, int num)
|
||||
{
|
||||
fprintf(stderr,"ERROR: %s\n",str);
|
||||
sig_handler(SIGQUIT);
|
||||
exit(num);
|
||||
}
|
||||
int err_exit(char *str, int num) {
|
||||
fprintf(stderr, "ERROR: %s\n", str);
|
||||
sig_handler(SIGQUIT);
|
||||
exit(num);
|
||||
}
|
||||
|
||||
int
|
||||
usage (void)
|
||||
{
|
||||
fprintf(stderr,"Usage: ssldump [-r dumpfile] [-i interface] [-l sslkeylogfile] [-w outpcapfile]\n");
|
||||
fprintf(stderr," [-k keyfile] [-p password] [-vtaTznsAxVNde]\n");
|
||||
fprintf(stderr," [filter]\n");
|
||||
exit(0);
|
||||
}
|
||||
int usage(void) {
|
||||
fprintf(stderr,
|
||||
"Usage: ssldump [-r dumpfile] [-i interface] [-l sslkeylogfile] [-w "
|
||||
"outpcapfile]\n");
|
||||
fprintf(stderr,
|
||||
" [-k keyfile] [-p password] [-vtaTznsAxVNde]\n");
|
||||
fprintf(stderr, " [filter]\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int
|
||||
print_version (void)
|
||||
{
|
||||
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("Copyright (C) 2015-2023 the aforementioned volunteers\n");
|
||||
printf("Copyright (C) 1998-2001 RTFM, Inc.\n");
|
||||
printf("All rights reserved.\n");
|
||||
#ifdef OPENSSL
|
||||
printf("Compiled with OpenSSL: decryption enabled\n");
|
||||
#endif
|
||||
exit(0);
|
||||
}
|
||||
int print_version(void) {
|
||||
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("Copyright (C) 2015-2023 the aforementioned volunteers\n");
|
||||
printf("Copyright (C) 1998-2001 RTFM, Inc.\n");
|
||||
printf("All rights reserved.\n");
|
||||
#ifdef OPENSSL
|
||||
printf("Compiled with OpenSSL: decryption enabled\n");
|
||||
#endif
|
||||
exit(0);
|
||||
}
|
||||
|
||||
pcap_t *p;
|
||||
proto_mod *mod=&ssl_mod;
|
||||
proto_mod *mod = &ssl_mod;
|
||||
n_handler *n;
|
||||
char *interface_name=0;
|
||||
char *file=0;
|
||||
char *filter=0;
|
||||
void sig_handler(int sig)
|
||||
{
|
||||
int freed_conn = 0;
|
||||
fflush(stdout);
|
||||
if (logger)
|
||||
logger->vtbl->deinit();
|
||||
char *interface_name = 0;
|
||||
char *file = 0;
|
||||
char *filter = 0;
|
||||
void sig_handler(int sig) {
|
||||
int freed_conn = 0;
|
||||
fflush(stdout);
|
||||
if(logger)
|
||||
logger->vtbl->deinit();
|
||||
|
||||
freed_conn = destroy_all_conn();
|
||||
if(freed_conn && !(NET_print_flags & NET_PRINT_JSON))
|
||||
printf("Cleaned %d remaining connection(s) from connection pool\n", freed_conn);
|
||||
freed_conn = destroy_all_conn();
|
||||
if(freed_conn && !(NET_print_flags & NET_PRINT_JSON))
|
||||
printf("Cleaned %d remaining connection(s) from connection pool\n",
|
||||
freed_conn);
|
||||
|
||||
network_handler_destroy(mod, &n);
|
||||
network_handler_destroy(mod, &n);
|
||||
|
||||
if(p)
|
||||
pcap_close(p);
|
||||
if(interface_name)
|
||||
free(interface_name);
|
||||
if(filter)
|
||||
free(filter);
|
||||
if(file)
|
||||
free(file);
|
||||
if(p)
|
||||
pcap_close(p);
|
||||
if(interface_name)
|
||||
free(interface_name);
|
||||
if(filter)
|
||||
free(filter);
|
||||
if(file)
|
||||
free(file);
|
||||
|
||||
exit(sig);
|
||||
}
|
||||
|
||||
void pcap_cb(u_char *ptr, const struct pcap_pkthdr *hdr, const u_char *data)
|
||||
{
|
||||
n_handler *n;
|
||||
int len;
|
||||
struct ether_header *e_hdr=(struct ether_header *)data;
|
||||
int type, cleaned_conn;
|
||||
|
||||
n=(n_handler *)ptr;
|
||||
if(hdr->caplen!=hdr->len) err_exit("Length mismatch",-1);
|
||||
exit(sig);
|
||||
}
|
||||
|
||||
len=hdr->len;
|
||||
|
||||
switch(pcap_if_type){
|
||||
case DLT_RAW:
|
||||
void pcap_cb(u_char *ptr, const struct pcap_pkthdr *hdr, const u_char *data) {
|
||||
n_handler *n;
|
||||
int len;
|
||||
struct ether_header *e_hdr = (struct ether_header *)data;
|
||||
int type, cleaned_conn;
|
||||
|
||||
n = (n_handler *)ptr;
|
||||
if(hdr->caplen != hdr->len)
|
||||
err_exit("Length mismatch", -1);
|
||||
|
||||
len = hdr->len;
|
||||
|
||||
switch(pcap_if_type) {
|
||||
case DLT_RAW:
|
||||
#ifdef DLT_LOOP
|
||||
case DLT_LOOP:
|
||||
case DLT_LOOP:
|
||||
#endif
|
||||
case DLT_NULL:
|
||||
data+=4;
|
||||
len-=4;
|
||||
break;
|
||||
case DLT_EN10MB:
|
||||
if(len < sizeof(struct ether_header)) {
|
||||
if(!(NET_print_flags & NET_PRINT_JSON))
|
||||
printf("Frame size too small to contain Ethernet header, skipping ...\n");
|
||||
return;
|
||||
}
|
||||
case DLT_NULL:
|
||||
data += 4;
|
||||
len -= 4;
|
||||
break;
|
||||
case DLT_EN10MB:
|
||||
if(len < sizeof(struct ether_header)) {
|
||||
if(!(NET_print_flags & NET_PRINT_JSON))
|
||||
printf(
|
||||
"Frame size too small to contain Ethernet header, skipping "
|
||||
"...\n");
|
||||
return;
|
||||
}
|
||||
|
||||
type=ntohs(e_hdr->ether_type);
|
||||
type = ntohs(e_hdr->ether_type);
|
||||
|
||||
data+=sizeof(struct ether_header);
|
||||
len-=sizeof(struct ether_header);
|
||||
data += sizeof(struct ether_header);
|
||||
len -= sizeof(struct ether_header);
|
||||
|
||||
/* if vlans, push past VLAN header (4 bytes) */
|
||||
if(type==ETHERTYPE_8021Q) {
|
||||
type=ntohs(*(u_int16_t *)(data + 2));
|
||||
/* if vlans, push past VLAN header (4 bytes) */
|
||||
if(type == ETHERTYPE_8021Q) {
|
||||
type = ntohs(*(u_int16_t *)(data + 2));
|
||||
|
||||
data+=4;
|
||||
len+=4;
|
||||
}
|
||||
data += 4;
|
||||
len += 4;
|
||||
}
|
||||
|
||||
if(type!=ETHERTYPE_IP && type!=ETHERTYPE_IPV6)
|
||||
return;
|
||||
if(type != ETHERTYPE_IP && type != ETHERTYPE_IPV6)
|
||||
return;
|
||||
|
||||
break;
|
||||
case DLT_IEEE802:
|
||||
data+=22;
|
||||
len-=22;
|
||||
break;
|
||||
case DLT_FDDI:
|
||||
data+=21;
|
||||
len-=21;
|
||||
break;
|
||||
break;
|
||||
case DLT_IEEE802:
|
||||
data += 22;
|
||||
len -= 22;
|
||||
break;
|
||||
case DLT_FDDI:
|
||||
data += 21;
|
||||
len -= 21;
|
||||
break;
|
||||
#ifdef __amigaos__
|
||||
case DLT_MIAMI:
|
||||
data+=16;
|
||||
len-=16;
|
||||
break;
|
||||
case DLT_MIAMI:
|
||||
data += 16;
|
||||
len -= 16;
|
||||
break;
|
||||
#endif
|
||||
case DLT_SLIP:
|
||||
case DLT_SLIP:
|
||||
#ifdef DLT_SLIP_BSDOS
|
||||
case DLT_SLIP_BSDOS:
|
||||
case DLT_SLIP_BSDOS:
|
||||
#endif
|
||||
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__bsdi__) || defined(__APPLE__)
|
||||
data+=16;
|
||||
len-=16;
|
||||
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || \
|
||||
defined(__bsdi__) || defined(__APPLE__)
|
||||
data += 16;
|
||||
len -= 16;
|
||||
#else
|
||||
data+=24;
|
||||
len-=24;
|
||||
data += 24;
|
||||
len -= 24;
|
||||
#endif
|
||||
break;
|
||||
case DLT_PPP:
|
||||
break;
|
||||
case DLT_PPP:
|
||||
#ifdef DLT_PPP_BSDOS
|
||||
case DLT_PPP_BSDOS:
|
||||
case DLT_PPP_BSDOS:
|
||||
#endif
|
||||
#ifdef DLT_PPP_SERIAL
|
||||
case DLT_PPP_SERIAL:
|
||||
case DLT_PPP_SERIAL:
|
||||
#endif
|
||||
#ifdef DLT_PPP_ETHER
|
||||
case DLT_PPP_ETHER:
|
||||
case DLT_PPP_ETHER:
|
||||
#endif
|
||||
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__bsdi__) || defined(__APPLE__)
|
||||
data+=4;
|
||||
len-=4;
|
||||
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || \
|
||||
defined(__bsdi__) || defined(__APPLE__)
|
||||
data += 4;
|
||||
len -= 4;
|
||||
#else
|
||||
#if defined(sun) || defined(__sun)
|
||||
data+=8;
|
||||
len-=8;
|
||||
data += 8;
|
||||
len -= 8;
|
||||
#else
|
||||
data+=24;
|
||||
len-=24;
|
||||
data += 24;
|
||||
len -= 24;
|
||||
#endif
|
||||
#endif
|
||||
break;
|
||||
break;
|
||||
#ifdef DLT_ENC
|
||||
case DLT_ENC:
|
||||
data+=12;
|
||||
len-=12;
|
||||
break;
|
||||
case DLT_ENC:
|
||||
data += 12;
|
||||
len -= 12;
|
||||
break;
|
||||
#endif
|
||||
#ifdef DLT_LINUX_SLL
|
||||
case DLT_LINUX_SLL:
|
||||
data+=16;
|
||||
len-=16;
|
||||
break;
|
||||
case DLT_LINUX_SLL:
|
||||
data += 16;
|
||||
len -= 16;
|
||||
break;
|
||||
#endif
|
||||
#ifdef DLT_IPNET
|
||||
case DLT_IPNET:
|
||||
data+=24;
|
||||
len-=24;
|
||||
break;
|
||||
case DLT_IPNET:
|
||||
data += 24;
|
||||
len -= 24;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
if(type == ETHERTYPE_IPV6)
|
||||
network_process_packet(n,(struct timeval *) &hdr->ts,(u_char *)data,len, AF_INET6);
|
||||
else
|
||||
network_process_packet(n,(struct timeval *) &hdr->ts,(u_char *)data,len, AF_INET);
|
||||
|
||||
if(packet_cnt == conn_freq) {
|
||||
packet_cnt = 0;
|
||||
memcpy(&last_packet_seen_time,&hdr->ts,sizeof(struct timeval));
|
||||
if((cleaned_conn = clean_old_conn()) && !(NET_print_flags & NET_PRINT_JSON))
|
||||
printf("%d inactive connection(s) cleaned from connection pool\n", cleaned_conn);
|
||||
} else {
|
||||
packet_cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
if(type == ETHERTYPE_IPV6)
|
||||
network_process_packet(n, (struct timeval *)&hdr->ts, (u_char *)data, len,
|
||||
AF_INET6);
|
||||
else
|
||||
network_process_packet(n, (struct timeval *)&hdr->ts, (u_char *)data, len,
|
||||
AF_INET);
|
||||
|
||||
if(packet_cnt == conn_freq) {
|
||||
packet_cnt = 0;
|
||||
memcpy(&last_packet_seen_time, &hdr->ts, sizeof(struct timeval));
|
||||
if((cleaned_conn = clean_old_conn()) && !(NET_print_flags & NET_PRINT_JSON))
|
||||
printf("%d inactive connection(s) cleaned from connection pool\n",
|
||||
cleaned_conn);
|
||||
} else {
|
||||
packet_cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct module_def_ {
|
||||
char *name;
|
||||
proto_mod *mod;
|
||||
char *name;
|
||||
proto_mod *mod;
|
||||
} module_def;
|
||||
|
||||
static module_def modules[]={
|
||||
{"SSL",&ssl_mod},
|
||||
{"NULL",&null_mod},
|
||||
static module_def modules[] = {{"SSL", &ssl_mod},
|
||||
{"NULL", &null_mod},
|
||||
#ifdef ENABLE_RECORD
|
||||
{"RECORD",&record_mod},
|
||||
{"RECORD", &record_mod},
|
||||
#endif
|
||||
{0,0}
|
||||
};
|
||||
|
||||
{0, 0}};
|
||||
|
||||
int parse_ssl_flag PROTO_LIST((int c));
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int r;
|
||||
int main(int argc, char **argv) {
|
||||
int r;
|
||||
#ifdef _WIN32
|
||||
__declspec(dllimport) char *optarg;
|
||||
__declspec(dllimport) int optind;
|
||||
__declspec(dllimport) char *optarg;
|
||||
__declspec(dllimport) int optind;
|
||||
#else
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
#endif
|
||||
pcap_if_t *interfaces;
|
||||
bpf_u_int32 localnet,netmask;
|
||||
int c;
|
||||
module_def *m=0;
|
||||
int no_promiscuous=0;
|
||||
int freed_conn=0;
|
||||
|
||||
char errbuf[PCAP_ERRBUF_SIZE];
|
||||
pcap_if_t *interfaces;
|
||||
bpf_u_int32 localnet, netmask;
|
||||
int c;
|
||||
module_def *m = 0;
|
||||
int no_promiscuous = 0;
|
||||
int freed_conn = 0;
|
||||
|
||||
signal(SIGINT,sig_handler);
|
||||
|
||||
while((c=getopt(argc,argv,"vr:F:f:S:jyTt:ai:k:l:w:p:znsAxXhHVNdqem:P"))!=EOF){
|
||||
switch(c){
|
||||
case 'v':
|
||||
print_version();
|
||||
break;
|
||||
case 'f':
|
||||
fprintf(stderr,"-f option replaced by -r. Use that in the future\n");
|
||||
case 'r':
|
||||
file=strdup(optarg);
|
||||
break;
|
||||
case 'S':
|
||||
ssl_mod.vtbl->parse_flags(optarg);
|
||||
break;
|
||||
case 'y':
|
||||
NET_print_flags|=NET_PRINT_TYPESET;
|
||||
/*Kludge*/
|
||||
SSL_print_flags |= SSL_PRINT_NROFF;
|
||||
break;
|
||||
case 'j':
|
||||
NET_print_flags |= NET_PRINT_JSON;
|
||||
SSL_print_flags |= SSL_PRINT_JSON;
|
||||
break;
|
||||
case 'z':
|
||||
NET_print_flags |= NET_PRINT_TS;
|
||||
break;
|
||||
case 'a':
|
||||
NET_print_flags |= NET_PRINT_ACKS;
|
||||
break;
|
||||
case 'A':
|
||||
SSL_print_flags |= SSL_PRINT_ALL_FIELDS;
|
||||
break;
|
||||
case 'T':
|
||||
NET_print_flags |= NET_PRINT_TCP_HDR;
|
||||
break;
|
||||
case 'i':
|
||||
interface_name=strdup(optarg);
|
||||
break;
|
||||
case 'k':
|
||||
SSL_keyfile=strdup(optarg);
|
||||
break;
|
||||
case 'l':
|
||||
SSL_keylogfile=strdup(optarg);
|
||||
break;
|
||||
case 'w':
|
||||
logger=&pcap_mod;
|
||||
if(logger->vtbl->init(optarg)!=0){
|
||||
fprintf(stderr,"Can not open/create out pcap %s\n",
|
||||
optarg);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'p':
|
||||
SSL_password=strdup(optarg);
|
||||
break;
|
||||
case 'P':
|
||||
++no_promiscuous;
|
||||
break;
|
||||
case 'n':
|
||||
NET_print_flags |= NET_PRINT_NO_RESOLVE;
|
||||
break;
|
||||
case 't':
|
||||
conn_ttl=atoi(optarg);
|
||||
break;
|
||||
case 'F':
|
||||
conn_freq=atoi(optarg);
|
||||
break;
|
||||
case 'm':
|
||||
for(m=modules;m->name!=0;m++){
|
||||
if(!strcmp(m->name,optarg)){
|
||||
mod=m->mod;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!m->name){
|
||||
fprintf(stderr,"Request analysis module %s not found\n",
|
||||
optarg);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
usage();
|
||||
printf("Do 'man ssldump' for documentation\n");
|
||||
char errbuf[PCAP_ERRBUF_SIZE];
|
||||
|
||||
signal(SIGINT, sig_handler);
|
||||
|
||||
while((c = getopt(argc, argv, "vr:F:f:S:jyTt:ai:k:l:w:p:znsAxXhHVNdqem:P")) !=
|
||||
EOF) {
|
||||
switch(c) {
|
||||
case 'v':
|
||||
print_version();
|
||||
break;
|
||||
case 'f':
|
||||
fprintf(stderr, "-f option replaced by -r. Use that in the future\n");
|
||||
case 'r':
|
||||
file = strdup(optarg);
|
||||
break;
|
||||
case 'S':
|
||||
ssl_mod.vtbl->parse_flags(optarg);
|
||||
break;
|
||||
case 'y':
|
||||
NET_print_flags |= NET_PRINT_TYPESET;
|
||||
/*Kludge*/
|
||||
SSL_print_flags |= SSL_PRINT_NROFF;
|
||||
break;
|
||||
case 'j':
|
||||
NET_print_flags |= NET_PRINT_JSON;
|
||||
SSL_print_flags |= SSL_PRINT_JSON;
|
||||
break;
|
||||
case 'z':
|
||||
NET_print_flags |= NET_PRINT_TS;
|
||||
break;
|
||||
case 'a':
|
||||
NET_print_flags |= NET_PRINT_ACKS;
|
||||
break;
|
||||
case 'A':
|
||||
SSL_print_flags |= SSL_PRINT_ALL_FIELDS;
|
||||
break;
|
||||
case 'T':
|
||||
NET_print_flags |= NET_PRINT_TCP_HDR;
|
||||
break;
|
||||
case 'i':
|
||||
interface_name = strdup(optarg);
|
||||
break;
|
||||
case 'k':
|
||||
SSL_keyfile = strdup(optarg);
|
||||
break;
|
||||
case 'l':
|
||||
SSL_keylogfile = strdup(optarg);
|
||||
break;
|
||||
case 'w':
|
||||
logger = &pcap_mod;
|
||||
if(logger->vtbl->init(optarg) != 0) {
|
||||
fprintf(stderr, "Can not open/create out pcap %s\n", optarg);
|
||||
exit(1);
|
||||
|
||||
case '?':
|
||||
usage();
|
||||
exit(1);
|
||||
|
||||
/* must be an SSL flag. This is kind of a gross
|
||||
special case */
|
||||
default:
|
||||
parse_ssl_flag(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
argv+=optind;
|
||||
argc-=optind;
|
||||
|
||||
if(!file){
|
||||
if(!interface_name){
|
||||
if(pcap_findalldevs(&interfaces,errbuf)==-1) {
|
||||
fprintf(stderr,"PCAP: %s\n",errbuf);
|
||||
err_exit("Aborting",-1);
|
||||
}
|
||||
interface_name=interfaces->name;
|
||||
if(!interface_name){
|
||||
fprintf(stderr,"PCAP: %s\n",errbuf);
|
||||
err_exit("Aborting",-1);
|
||||
}
|
||||
}
|
||||
if(!(p=pcap_open_live(interface_name,65535,!no_promiscuous,1000,errbuf))){
|
||||
fprintf(stderr,"PCAP: %s\n",errbuf);
|
||||
err_exit("Aborting",-1);
|
||||
}
|
||||
|
||||
if (pcap_lookupnet(interface_name, &localnet, &netmask, errbuf) < 0)
|
||||
fprintf(stderr,"PCAP: %s\n", errbuf);
|
||||
}
|
||||
else{
|
||||
if(!(p=pcap_open_offline(file,errbuf))){
|
||||
fprintf(stderr,"PCAP: %s\n",errbuf);
|
||||
err_exit("Aborting",-1);
|
||||
}
|
||||
|
||||
netmask=0;
|
||||
localnet=0;
|
||||
}
|
||||
|
||||
if(argc!=0)
|
||||
filter=collapse_args(argc,argv);
|
||||
|
||||
if(filter){
|
||||
struct bpf_program fp;
|
||||
|
||||
/* (F5 patch)
|
||||
* reformat filter to include traffic with or without the 802.1q
|
||||
* vlan header. for example, "port 80" becomes:
|
||||
* "( port 80 ) or ( vlan and port 80 )".
|
||||
* note that if the filter includes the literals vlan, tagged, or
|
||||
* untagged, then it is assumed that the user knows what she is
|
||||
* doing, and the filter is not reformatted.
|
||||
*/
|
||||
if ((pcap_datalink(p) == DLT_EN10MB) &&
|
||||
(filter != NULL) &&
|
||||
(strstr(filter,"vlan") == NULL)) {
|
||||
char *tmp_filter;
|
||||
char *fmt = "( (not ether proto 0x8100) and (%s) ) or ( vlan and (%s) )";
|
||||
|
||||
tmp_filter = (char *)malloc((strlen(filter) * 2) + strlen(fmt) + 1);
|
||||
if (tmp_filter == NULL) {
|
||||
fprintf(stderr,"PCAP: malloc failed\n");
|
||||
err_exit("Aborting",-1);
|
||||
break;
|
||||
case 'p':
|
||||
SSL_password = strdup(optarg);
|
||||
break;
|
||||
case 'P':
|
||||
++no_promiscuous;
|
||||
break;
|
||||
case 'n':
|
||||
NET_print_flags |= NET_PRINT_NO_RESOLVE;
|
||||
break;
|
||||
case 't':
|
||||
conn_ttl = atoi(optarg);
|
||||
break;
|
||||
case 'F':
|
||||
conn_freq = atoi(optarg);
|
||||
break;
|
||||
case 'm':
|
||||
for(m = modules; m->name != 0; m++) {
|
||||
if(!strcmp(m->name, optarg)) {
|
||||
mod = m->mod;
|
||||
break;
|
||||
}
|
||||
|
||||
sprintf(tmp_filter,fmt,filter,filter);
|
||||
free(filter);
|
||||
filter = tmp_filter;
|
||||
}
|
||||
if(!m->name) {
|
||||
fprintf(stderr, "Request analysis module %s not found\n", optarg);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
usage();
|
||||
printf("Do 'man ssldump' for documentation\n");
|
||||
exit(1);
|
||||
|
||||
case '?':
|
||||
usage();
|
||||
exit(1);
|
||||
|
||||
/* must be an SSL flag. This is kind of a gross
|
||||
special case */
|
||||
default:
|
||||
parse_ssl_flag(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
|
||||
if(!file) {
|
||||
if(!interface_name) {
|
||||
if(pcap_findalldevs(&interfaces, errbuf) == -1) {
|
||||
fprintf(stderr, "PCAP: %s\n", errbuf);
|
||||
err_exit("Aborting", -1);
|
||||
}
|
||||
interface_name = interfaces->name;
|
||||
if(!interface_name) {
|
||||
fprintf(stderr, "PCAP: %s\n", errbuf);
|
||||
err_exit("Aborting", -1);
|
||||
}
|
||||
}
|
||||
if(!(p = pcap_open_live(interface_name, 65535, !no_promiscuous, 1000,
|
||||
errbuf))) {
|
||||
fprintf(stderr, "PCAP: %s\n", errbuf);
|
||||
err_exit("Aborting", -1);
|
||||
}
|
||||
|
||||
if(pcap_lookupnet(interface_name, &localnet, &netmask, errbuf) < 0)
|
||||
fprintf(stderr, "PCAP: %s\n", errbuf);
|
||||
} else {
|
||||
if(!(p = pcap_open_offline(file, errbuf))) {
|
||||
fprintf(stderr, "PCAP: %s\n", errbuf);
|
||||
err_exit("Aborting", -1);
|
||||
}
|
||||
|
||||
netmask = 0;
|
||||
localnet = 0;
|
||||
}
|
||||
|
||||
if(argc != 0)
|
||||
filter = collapse_args(argc, argv);
|
||||
|
||||
if(filter) {
|
||||
struct bpf_program fp;
|
||||
|
||||
/* (F5 patch)
|
||||
* reformat filter to include traffic with or without the 802.1q
|
||||
* vlan header. for example, "port 80" becomes:
|
||||
* "( port 80 ) or ( vlan and port 80 )".
|
||||
* note that if the filter includes the literals vlan, tagged, or
|
||||
* untagged, then it is assumed that the user knows what she is
|
||||
* doing, and the filter is not reformatted.
|
||||
*/
|
||||
if((pcap_datalink(p) == DLT_EN10MB) && (filter != NULL) &&
|
||||
(strstr(filter, "vlan") == NULL)) {
|
||||
char *tmp_filter;
|
||||
char *fmt = "( (not ether proto 0x8100) and (%s) ) or ( vlan and (%s) )";
|
||||
|
||||
tmp_filter = (char *)malloc((strlen(filter) * 2) + strlen(fmt) + 1);
|
||||
if(tmp_filter == NULL) {
|
||||
fprintf(stderr, "PCAP: malloc failed\n");
|
||||
err_exit("Aborting", -1);
|
||||
}
|
||||
|
||||
if(pcap_compile(p,&fp,filter,0,netmask)<0)
|
||||
verr_exit("PCAP: %s\n",pcap_geterr(p));
|
||||
|
||||
if(pcap_setfilter(p,&fp)<0)
|
||||
verr_exit("PCAP: %s\n",pcap_geterr(p));
|
||||
sprintf(tmp_filter, fmt, filter, filter);
|
||||
free(filter);
|
||||
filter = tmp_filter;
|
||||
}
|
||||
|
||||
pcap_if_type=pcap_datalink(p);
|
||||
if(pcap_compile(p, &fp, filter, 0, netmask) < 0)
|
||||
verr_exit("PCAP: %s\n", pcap_geterr(p));
|
||||
|
||||
if(!(NET_print_flags & NET_PRINT_JSON))
|
||||
if(NET_print_flags & NET_PRINT_TYPESET)
|
||||
printf("\n.nf\n.ps -2\n");
|
||||
|
||||
if((r=network_handler_create(mod,&n)))
|
||||
err_exit("Couldn't create network handler",r);
|
||||
|
||||
pcap_loop(p,-1,pcap_cb,(u_char *)n);
|
||||
|
||||
if(!(NET_print_flags & NET_PRINT_JSON))
|
||||
if(NET_print_flags & NET_PRINT_TYPESET)
|
||||
printf("\n.ps\n.fi\n");
|
||||
|
||||
freed_conn = destroy_all_conn();
|
||||
if(freed_conn && !(NET_print_flags & NET_PRINT_JSON))
|
||||
printf("Cleaned %d remaining connection(s) from connection pool\n", freed_conn);
|
||||
|
||||
network_handler_destroy(mod, &n);
|
||||
pcap_close(p);
|
||||
|
||||
free(n);
|
||||
|
||||
if(filter)
|
||||
free(filter);
|
||||
if(file)
|
||||
free(file);
|
||||
if(interface_name)
|
||||
free(interface_name);
|
||||
if(SSL_keyfile)
|
||||
free(SSL_keyfile);
|
||||
if(SSL_keylogfile)
|
||||
free(SSL_keylogfile);
|
||||
if(SSL_password)
|
||||
free(SSL_password);
|
||||
if (logger)
|
||||
{
|
||||
logger->vtbl->deinit();
|
||||
}
|
||||
|
||||
exit(0);
|
||||
if(pcap_setfilter(p, &fp) < 0)
|
||||
verr_exit("PCAP: %s\n", pcap_geterr(p));
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
collapse_args (int argc, char **argv)
|
||||
{
|
||||
int i,len=0;
|
||||
char *ret;
|
||||
|
||||
if(!argc)
|
||||
return(0);
|
||||
pcap_if_type = pcap_datalink(p);
|
||||
|
||||
for(i=0;i<argc;i++){
|
||||
len+=strlen(argv[i])+1;
|
||||
}
|
||||
if(!(NET_print_flags & NET_PRINT_JSON))
|
||||
if(NET_print_flags & NET_PRINT_TYPESET)
|
||||
printf("\n.nf\n.ps -2\n");
|
||||
|
||||
if(!(ret=(char *)malloc(len)))
|
||||
err_exit("Out of memory",1);
|
||||
if((r = network_handler_create(mod, &n)))
|
||||
err_exit("Couldn't create network handler", r);
|
||||
|
||||
len=0;
|
||||
for(i=0;i<argc;i++){
|
||||
strcpy(ret+len,argv[i]);
|
||||
len+=strlen(argv[i]);
|
||||
pcap_loop(p, -1, pcap_cb, (u_char *)n);
|
||||
|
||||
if(i!=(argc-1))
|
||||
ret[len++]=' ';
|
||||
}
|
||||
if(!(NET_print_flags & NET_PRINT_JSON))
|
||||
if(NET_print_flags & NET_PRINT_TYPESET)
|
||||
printf("\n.ps\n.fi\n");
|
||||
|
||||
return(ret);
|
||||
freed_conn = destroy_all_conn();
|
||||
if(freed_conn && !(NET_print_flags & NET_PRINT_JSON))
|
||||
printf("Cleaned %d remaining connection(s) from connection pool\n",
|
||||
freed_conn);
|
||||
|
||||
network_handler_destroy(mod, &n);
|
||||
pcap_close(p);
|
||||
|
||||
free(n);
|
||||
|
||||
if(filter)
|
||||
free(filter);
|
||||
if(file)
|
||||
free(file);
|
||||
if(interface_name)
|
||||
free(interface_name);
|
||||
if(SSL_keyfile)
|
||||
free(SSL_keyfile);
|
||||
if(SSL_keylogfile)
|
||||
free(SSL_keylogfile);
|
||||
if(SSL_password)
|
||||
free(SSL_password);
|
||||
if(logger) {
|
||||
logger->vtbl->deinit();
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
char *collapse_args(int argc, char **argv) {
|
||||
int i, len = 0;
|
||||
char *ret;
|
||||
|
||||
if(!argc)
|
||||
return (0);
|
||||
|
||||
for(i = 0; i < argc; i++) {
|
||||
len += strlen(argv[i]) + 1;
|
||||
}
|
||||
|
||||
if(!(ret = (char *)malloc(len)))
|
||||
err_exit("Out of memory", 1);
|
||||
|
||||
len = 0;
|
||||
for(i = 0; i < argc; i++) {
|
||||
strcpy(ret + len, argv[i]);
|
||||
len += strlen(argv[i]);
|
||||
|
||||
if(i != (argc - 1))
|
||||
ret[len++] = ' ';
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,45 +44,43 @@
|
|||
ekr@rtfm.com Mon Feb 15 17:23:36 1999
|
||||
*/
|
||||
|
||||
int explain(char *format, ...) {
|
||||
va_list ap;
|
||||
|
||||
int explain(char *format,...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
|
||||
va_start(ap,format);
|
||||
INDENT;
|
||||
|
||||
INDENT;
|
||||
vprintf(format, ap);
|
||||
va_end(ap);
|
||||
return (0);
|
||||
}
|
||||
|
||||
vprintf(format,ap);
|
||||
va_end(ap);
|
||||
return(0);
|
||||
int exdump(name, data) char *name;
|
||||
Data *data;
|
||||
{
|
||||
int i, j;
|
||||
char prefix[100];
|
||||
|
||||
INDENT;
|
||||
|
||||
if(name) {
|
||||
sprintf(prefix, "%s[%d]=\n", name, data->len);
|
||||
printf("%s", prefix);
|
||||
INDENT_INCR;
|
||||
}
|
||||
|
||||
int exdump(name,data)
|
||||
char *name;
|
||||
Data *data;
|
||||
{
|
||||
int i,j;
|
||||
char prefix[100];
|
||||
|
||||
INDENT;
|
||||
|
||||
if(name){
|
||||
sprintf(prefix,"%s[%d]=\n",name,data->len);
|
||||
printf("%s",prefix);
|
||||
INDENT_INCR;
|
||||
}
|
||||
for(i=0;i<data->len;i++){
|
||||
if(!i && (data->len>8)) INDENT;
|
||||
if((data->len>8) && i && !(i%12)){
|
||||
LF;INDENT;
|
||||
}
|
||||
printf("%.2x ",data->data[i]&255);
|
||||
}
|
||||
if(name) INDENT_POP;
|
||||
if(data->len>8 && i%12)
|
||||
for(i = 0; i < data->len; i++) {
|
||||
if(!i && (data->len > 8))
|
||||
INDENT;
|
||||
if((data->len > 8) && i && !(i % 12)) {
|
||||
LF;
|
||||
return(0);
|
||||
INDENT;
|
||||
}
|
||||
printf("%.2x ", data->data[i] & 255);
|
||||
}
|
||||
|
||||
|
||||
if(name)
|
||||
INDENT_POP;
|
||||
if(data->len > 8 && i % 12)
|
||||
LF;
|
||||
return (0);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,14 +44,10 @@
|
|||
ekr@rtfm.com Mon Feb 15 17:23:56 1999
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _print_utils_h
|
||||
#define _print_utils_h
|
||||
|
||||
int explain PROTO_LIST((char *format,...));
|
||||
int exdump PROTO_LIST((char *name,
|
||||
Data *data));
|
||||
|
||||
int explain PROTO_LIST((char *format, ...));
|
||||
int exdump PROTO_LIST((char *name, Data *data));
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,41 +44,40 @@
|
|||
ekr@rtfm.com Thu Jan 7 22:35:23 1999
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "network.h"
|
||||
|
||||
int
|
||||
create_proto_handler (proto_mod *mod, proto_ctx *ctx, proto_handler **handlerp, tcp_conn *conn, struct timeval *first_packet)
|
||||
{
|
||||
int r,_status;
|
||||
proto_handler *handler=0;
|
||||
int create_proto_handler(proto_mod *mod,
|
||||
proto_ctx *ctx,
|
||||
proto_handler **handlerp,
|
||||
tcp_conn *conn,
|
||||
struct timeval *first_packet) {
|
||||
int r, _status;
|
||||
proto_handler *handler = 0;
|
||||
|
||||
if(!(handler=(proto_handler *)calloc(1,sizeof(proto_handler))))
|
||||
ABORT(R_NO_MEMORY);
|
||||
handler->vtbl=mod->vtbl;
|
||||
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)))
|
||||
ABORT(r);
|
||||
if(!(handler = (proto_handler *)calloc(1, sizeof(proto_handler))))
|
||||
ABORT(R_NO_MEMORY);
|
||||
handler->vtbl = mod->vtbl;
|
||||
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)))
|
||||
ABORT(r);
|
||||
|
||||
*handlerp=handler;
|
||||
*handlerp = handler;
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
if(_status){
|
||||
destroy_proto_handler(&handler);
|
||||
}
|
||||
return(_status);
|
||||
_status = 0;
|
||||
abort:
|
||||
if(_status) {
|
||||
destroy_proto_handler(&handler);
|
||||
}
|
||||
return (_status);
|
||||
}
|
||||
|
||||
int
|
||||
destroy_proto_handler (proto_handler **handlerp)
|
||||
{
|
||||
if(!handlerp || !*handlerp)
|
||||
return(0);
|
||||
int destroy_proto_handler(proto_handler **handlerp) {
|
||||
if(!handlerp || !*handlerp)
|
||||
return (0);
|
||||
|
||||
(*handlerp)->vtbl->destroy(&(*handlerp)->obj);
|
||||
free(*handlerp);
|
||||
*handlerp=0;
|
||||
return(0);
|
||||
}
|
||||
(*handlerp)->vtbl->destroy(&(*handlerp)->obj);
|
||||
free(*handlerp);
|
||||
*handlerp = 0;
|
||||
return (0);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,67 +44,76 @@
|
|||
ekr@rtfm.com Thu Dec 24 21:10:05 1998
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _proto_mod_h
|
||||
#define _proto_mod_h
|
||||
|
||||
typedef struct proto_obj_ proto_obj;
|
||||
typedef struct proto_ctx_ proto_ctx;
|
||||
|
||||
#define DIR_I2R 1
|
||||
#define DIR_R2I 2
|
||||
#define DIR_I2R 1
|
||||
#define DIR_R2I 2
|
||||
|
||||
struct proto_mod_vtbl_ {
|
||||
int (*parse_flags) PROTO_LIST((char *str));
|
||||
int (*parse_flag) PROTO_LIST((int flag));
|
||||
int (*create_ctx) PROTO_LIST((void *handle,proto_ctx **ctxp));
|
||||
int (*create) PROTO_LIST((void *handle,proto_ctx *ctx,
|
||||
tcp_conn *conn,
|
||||
proto_obj **objp,
|
||||
struct sockaddr_storage *i_addr,u_short i_port,
|
||||
struct sockaddr_storage *r_addr,u_short r_port,struct timeval *time_base));
|
||||
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));
|
||||
int(*parse_flags) PROTO_LIST((char *str));
|
||||
int(*parse_flag) PROTO_LIST((int flag));
|
||||
int(*create_ctx) PROTO_LIST((void *handle, proto_ctx **ctxp));
|
||||
int(*create) PROTO_LIST((void *handle,
|
||||
proto_ctx *ctx,
|
||||
tcp_conn *conn,
|
||||
proto_obj **objp,
|
||||
struct sockaddr_storage *i_addr,
|
||||
u_short i_port,
|
||||
struct sockaddr_storage *r_addr,
|
||||
u_short r_port,
|
||||
struct timeval *time_base));
|
||||
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_ {
|
||||
void *handle;
|
||||
struct proto_mod_vtbl_ *vtbl;
|
||||
void *handle;
|
||||
struct proto_mod_vtbl_ *vtbl;
|
||||
};
|
||||
|
||||
struct proto_handler_ {
|
||||
proto_obj *obj;
|
||||
struct proto_mod_vtbl_ *vtbl;
|
||||
proto_obj *obj;
|
||||
struct proto_mod_vtbl_ *vtbl;
|
||||
};
|
||||
|
||||
int create_proto_handler PROTO_LIST((proto_mod *mod,proto_ctx *ctx,
|
||||
proto_handler **handlerp,
|
||||
tcp_conn *conn,struct timeval *first_packet));
|
||||
int destroy_proto_handler PROTO_LIST((proto_handler **handlerp));
|
||||
int create_proto_handler PROTO_LIST((proto_mod * mod,
|
||||
proto_ctx *ctx,
|
||||
proto_handler **handlerp,
|
||||
tcp_conn *conn,
|
||||
struct timeval *first_packet));
|
||||
int destroy_proto_handler PROTO_LIST((proto_handler * *handlerp));
|
||||
|
||||
|
||||
//add logger
|
||||
// add logger
|
||||
struct logger_mod_vtbl_ {
|
||||
int (*init) PROTO_LIST((void *data));
|
||||
//deinit must be async signal safe(!!!)
|
||||
int (*deinit) PROTO_LIST(());
|
||||
int (*create) PROTO_LIST((proto_obj **objp, struct sockaddr_storage *i_addr,u_short i_port,
|
||||
struct sockaddr_storage *r_addr,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));
|
||||
int(*init) PROTO_LIST((void *data));
|
||||
// deinit must be async signal safe(!!!)
|
||||
int(*deinit) PROTO_LIST(());
|
||||
int(*create) PROTO_LIST((proto_obj * *objp,
|
||||
struct sockaddr_storage *i_addr,
|
||||
u_short i_port,
|
||||
struct sockaddr_storage *r_addr,
|
||||
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_ {
|
||||
char *name;
|
||||
struct logger_mod_vtbl_ *vtbl;
|
||||
char *name;
|
||||
struct logger_mod_vtbl_ *vtbl;
|
||||
};
|
||||
|
||||
typedef struct logger_mod_ logger_mod;
|
||||
|
||||
extern logger_mod *logger;
|
||||
extern logger_mod *logger;
|
||||
|
||||
#endif
|
||||
|
||||
|
|
314
base/tcpconn.c
314
base/tcpconn.c
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,193 +44,182 @@
|
|||
ekr@rtfm.com Tue Dec 29 15:13:03 1998
|
||||
*/
|
||||
|
||||
|
||||
#include "network.h"
|
||||
#include "tcpconn.h"
|
||||
|
||||
|
||||
typedef struct conn_struct_ {
|
||||
tcp_conn conn;
|
||||
struct conn_struct_ *next;
|
||||
struct conn_struct_ *prev;
|
||||
tcp_conn conn;
|
||||
struct conn_struct_ *next;
|
||||
struct conn_struct_ *prev;
|
||||
} 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 int conn_ttl;
|
||||
|
||||
static int zero_conn PROTO_LIST((tcp_conn *conn));
|
||||
static int zero_conn PROTO_LIST((tcp_conn * conn));
|
||||
|
||||
static int
|
||||
zero_conn (tcp_conn *conn)
|
||||
{
|
||||
memset(conn,0,sizeof(tcp_conn));
|
||||
return(0);
|
||||
}
|
||||
static int zero_conn(tcp_conn *conn) {
|
||||
memset(conn, 0, sizeof(tcp_conn));
|
||||
return (0);
|
||||
}
|
||||
|
||||
int tcp_find_conn(tcp_conn **connp, int *directionp,struct sockaddr_storage *saddr,
|
||||
u_short sport, struct sockaddr_storage *daddr, u_short dport)
|
||||
{
|
||||
conn_struct *conn;
|
||||
int tcp_find_conn(tcp_conn **connp,
|
||||
int *directionp,
|
||||
struct sockaddr_storage *saddr,
|
||||
u_short sport,
|
||||
struct sockaddr_storage *daddr,
|
||||
u_short dport) {
|
||||
conn_struct *conn;
|
||||
|
||||
for(conn=first_conn;conn;conn=conn->next){
|
||||
|
||||
if(sport == conn->conn.i_port && dport==conn->conn.r_port){
|
||||
if(!memcmp(saddr,&conn->conn.i_addr,sizeof(struct sockaddr_storage))
|
||||
&& !memcmp(daddr,&conn->conn.r_addr,sizeof(struct sockaddr_storage)))
|
||||
{
|
||||
*directionp=DIR_I2R;
|
||||
*connp=&(conn->conn);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
if(dport == conn->conn.i_port && sport==conn->conn.r_port){
|
||||
if(!memcmp(saddr,&conn->conn.r_addr,sizeof(struct sockaddr_storage))
|
||||
&& !memcmp(daddr,&conn->conn.i_addr,sizeof(struct sockaddr_storage)))
|
||||
{
|
||||
*directionp=DIR_R2I;
|
||||
*connp=&(conn->conn);
|
||||
return(0);
|
||||
}
|
||||
for(conn = first_conn; conn; conn = conn->next) {
|
||||
if(sport == conn->conn.i_port && dport == conn->conn.r_port) {
|
||||
if(!memcmp(saddr, &conn->conn.i_addr, sizeof(struct sockaddr_storage)) &&
|
||||
!memcmp(daddr, &conn->conn.r_addr, sizeof(struct sockaddr_storage))) {
|
||||
*directionp = DIR_I2R;
|
||||
*connp = &(conn->conn);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
return(R_NOT_FOUND);
|
||||
if(dport == conn->conn.i_port && sport == conn->conn.r_port) {
|
||||
if(!memcmp(saddr, &conn->conn.r_addr, sizeof(struct sockaddr_storage)) &&
|
||||
!memcmp(daddr, &conn->conn.i_addr, sizeof(struct sockaddr_storage))) {
|
||||
*directionp = DIR_R2I;
|
||||
*connp = &(conn->conn);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int tcp_create_conn(tcp_conn **connp,struct sockaddr_storage *i_addr,
|
||||
u_short i_port, struct sockaddr_storage *r_addr, u_short r_port)
|
||||
{
|
||||
conn_struct *conn=0;
|
||||
|
||||
if(!(conn=(conn_struct *)malloc(sizeof(conn_struct))))
|
||||
return(R_NO_MEMORY);
|
||||
|
||||
conn->prev=0;
|
||||
|
||||
zero_conn(&conn->conn);
|
||||
conn->conn.backptr=conn;
|
||||
conn->conn.conn_number=conn_number++;
|
||||
|
||||
memcpy(&conn->conn.i_addr,i_addr,sizeof(struct sockaddr_storage));
|
||||
conn->conn.i_port=i_port;
|
||||
memcpy(&conn->conn.r_addr,r_addr,sizeof(struct sockaddr_storage));
|
||||
conn->conn.r_port=r_port;
|
||||
*connp=&(conn->conn);
|
||||
|
||||
/* Insert at the head of the list */
|
||||
conn->next=first_conn;
|
||||
if(first_conn)
|
||||
first_conn->prev=conn;
|
||||
first_conn=conn;
|
||||
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
tcp_destroy_conn (tcp_conn *conn)
|
||||
{
|
||||
conn_struct *c=conn->backptr;
|
||||
|
||||
/* Detach from the list */
|
||||
if(c->next){
|
||||
c->next->prev=c->prev;
|
||||
}
|
||||
if(c->prev){
|
||||
c->prev->next=c->next;
|
||||
}
|
||||
else {
|
||||
first_conn=c->next;
|
||||
}
|
||||
|
||||
destroy_proto_handler(&conn->analyzer);
|
||||
free_tcp_segment_queue(conn->i2r.oo_queue);
|
||||
free_tcp_segment_queue(conn->r2i.oo_queue);
|
||||
free(conn->i_name);
|
||||
free(conn->r_name);
|
||||
free(conn->i_num);
|
||||
free(conn->r_num);
|
||||
zero_conn(conn);
|
||||
free(conn->backptr);
|
||||
free(conn);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
clean_old_conn (void) {
|
||||
conn_struct *conn;
|
||||
tcp_conn *tcpconn;
|
||||
struct timeval dt;
|
||||
int i = 0;
|
||||
|
||||
if(!last_packet_seen_time.tv_sec)
|
||||
return 0; // Still processing first block of packets
|
||||
|
||||
conn = first_conn;
|
||||
while(conn) {
|
||||
tcpconn = &conn->conn;
|
||||
conn=conn->next;
|
||||
if(timestamp_diff(&last_packet_seen_time, &tcpconn->last_seen_time, &dt))
|
||||
continue;
|
||||
if(dt.tv_sec > conn_ttl) {
|
||||
i++;
|
||||
tcp_destroy_conn(tcpconn);
|
||||
}
|
||||
}
|
||||
return i;
|
||||
return (R_NOT_FOUND);
|
||||
}
|
||||
|
||||
int
|
||||
destroy_all_conn (void) {
|
||||
int i = 0;
|
||||
while(first_conn) {
|
||||
i++;
|
||||
tcp_destroy_conn(&first_conn->conn);
|
||||
}
|
||||
return i;
|
||||
int tcp_create_conn(tcp_conn **connp,
|
||||
struct sockaddr_storage *i_addr,
|
||||
u_short i_port,
|
||||
struct sockaddr_storage *r_addr,
|
||||
u_short r_port) {
|
||||
conn_struct *conn = 0;
|
||||
|
||||
if(!(conn = (conn_struct *)malloc(sizeof(conn_struct))))
|
||||
return (R_NO_MEMORY);
|
||||
|
||||
conn->prev = 0;
|
||||
|
||||
zero_conn(&conn->conn);
|
||||
conn->conn.backptr = conn;
|
||||
conn->conn.conn_number = conn_number++;
|
||||
|
||||
memcpy(&conn->conn.i_addr, i_addr, sizeof(struct sockaddr_storage));
|
||||
conn->conn.i_port = i_port;
|
||||
memcpy(&conn->conn.r_addr, r_addr, sizeof(struct sockaddr_storage));
|
||||
conn->conn.r_port = r_port;
|
||||
*connp = &(conn->conn);
|
||||
|
||||
/* Insert at the head of the list */
|
||||
conn->next = first_conn;
|
||||
if(first_conn)
|
||||
first_conn->prev = conn;
|
||||
first_conn = conn;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
free_tcp_segment_queue (segment *seg)
|
||||
{
|
||||
segment *tmp;
|
||||
int tcp_destroy_conn(tcp_conn *conn) {
|
||||
conn_struct *c = conn->backptr;
|
||||
|
||||
while(seg){
|
||||
tmp=seg->next;
|
||||
packet_destroy(seg->p);
|
||||
free(seg);
|
||||
seg=tmp;
|
||||
}
|
||||
|
||||
return(0);
|
||||
/* Detach from the list */
|
||||
if(c->next) {
|
||||
c->next->prev = c->prev;
|
||||
}
|
||||
if(c->prev) {
|
||||
c->prev->next = c->next;
|
||||
} else {
|
||||
first_conn = c->next;
|
||||
}
|
||||
|
||||
int
|
||||
copy_tcp_segment_queue (segment **out, segment *in)
|
||||
{
|
||||
int r,_status;
|
||||
segment *base=0;
|
||||
|
||||
for(;in;in=in->next){
|
||||
if(!(*out=(segment *)calloc(1,sizeof(segment))))
|
||||
ABORT(R_NO_MEMORY);
|
||||
if(!base) base=*out;
|
||||
destroy_proto_handler(&conn->analyzer);
|
||||
free_tcp_segment_queue(conn->i2r.oo_queue);
|
||||
free_tcp_segment_queue(conn->r2i.oo_queue);
|
||||
free(conn->i_name);
|
||||
free(conn->r_name);
|
||||
free(conn->i_num);
|
||||
free(conn->r_num);
|
||||
zero_conn(conn);
|
||||
free(conn->backptr);
|
||||
free(conn);
|
||||
|
||||
if((r=packet_copy(in->p,&(*out)->p)))
|
||||
ABORT(r);
|
||||
out=&(*out)->next; /* Move the pointer we're assigning to */
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
if(_status){
|
||||
free_tcp_segment_queue(base);
|
||||
int clean_old_conn(void) {
|
||||
conn_struct *conn;
|
||||
tcp_conn *tcpconn;
|
||||
struct timeval dt;
|
||||
int i = 0;
|
||||
|
||||
if(!last_packet_seen_time.tv_sec)
|
||||
return 0; // Still processing first block of packets
|
||||
|
||||
conn = first_conn;
|
||||
while(conn) {
|
||||
tcpconn = &conn->conn;
|
||||
conn = conn->next;
|
||||
if(timestamp_diff(&last_packet_seen_time, &tcpconn->last_seen_time, &dt))
|
||||
continue;
|
||||
if(dt.tv_sec > conn_ttl) {
|
||||
i++;
|
||||
tcp_destroy_conn(tcpconn);
|
||||
}
|
||||
return(_status);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
int destroy_all_conn(void) {
|
||||
int i = 0;
|
||||
while(first_conn) {
|
||||
i++;
|
||||
tcp_destroy_conn(&first_conn->conn);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
int free_tcp_segment_queue(segment *seg) {
|
||||
segment *tmp;
|
||||
|
||||
while(seg) {
|
||||
tmp = seg->next;
|
||||
packet_destroy(seg->p);
|
||||
free(seg);
|
||||
seg = tmp;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int copy_tcp_segment_queue(segment **out, segment *in) {
|
||||
int r, _status;
|
||||
segment *base = 0;
|
||||
|
||||
for(; in; in = in->next) {
|
||||
if(!(*out = (segment *)calloc(1, sizeof(segment))))
|
||||
ABORT(R_NO_MEMORY);
|
||||
if(!base)
|
||||
base = *out;
|
||||
|
||||
if((r = packet_copy(in->p, &(*out)->p)))
|
||||
ABORT(r);
|
||||
out = &(*out)->next; /* Move the pointer we're assigning to */
|
||||
}
|
||||
|
||||
_status = 0;
|
||||
abort:
|
||||
if(_status) {
|
||||
free_tcp_segment_queue(base);
|
||||
}
|
||||
return (_status);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,70 +44,72 @@
|
|||
ekr@rtfm.com Tue Dec 29 13:00:52 1998
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _tcpconn_h
|
||||
#define _tcpconn_h
|
||||
|
||||
typedef struct segment_ {
|
||||
u_char *data;
|
||||
u_int len;
|
||||
tcp_seq s_seq;
|
||||
packet *p;
|
||||
struct segment_ *next;
|
||||
u_char *data;
|
||||
u_int len;
|
||||
tcp_seq s_seq;
|
||||
packet *p;
|
||||
struct segment_ *next;
|
||||
} segment;
|
||||
|
||||
typedef struct stream_data_ {
|
||||
tcp_seq seq;
|
||||
tcp_seq ack;
|
||||
short close;
|
||||
segment *oo_queue;
|
||||
tcp_seq seq;
|
||||
tcp_seq ack;
|
||||
short close;
|
||||
segment *oo_queue;
|
||||
} stream_data;
|
||||
|
||||
typedef struct tcp_conn_ {
|
||||
int conn_number;
|
||||
int state;
|
||||
#define TCP_STATE_SYN1 1
|
||||
#define TCP_STATE_SYN2 2
|
||||
#define TCP_STATE_ACK 3
|
||||
#define TCP_STATE_ESTABLISHED 4
|
||||
#define TCP_STATE_FIN1 5
|
||||
int conn_number;
|
||||
int state;
|
||||
#define TCP_STATE_SYN1 1
|
||||
#define TCP_STATE_SYN2 2
|
||||
#define TCP_STATE_ACK 3
|
||||
#define TCP_STATE_ESTABLISHED 4
|
||||
#define TCP_STATE_FIN1 5
|
||||
#define TCP_STATE_CLOSED 6
|
||||
/*The address which sent the first SYN*/
|
||||
struct sockaddr_storage i_addr;
|
||||
u_short i_port;
|
||||
char *i_name;
|
||||
char *i_num;
|
||||
/*The address which sent the first SYN*/
|
||||
struct sockaddr_storage i_addr;
|
||||
u_short i_port;
|
||||
char *i_name;
|
||||
char *i_num;
|
||||
|
||||
/*The address which sent the second SYN*/
|
||||
struct sockaddr_storage r_addr;
|
||||
u_short r_port;
|
||||
char *r_name;
|
||||
char *r_num;
|
||||
/*The address which sent the second SYN*/
|
||||
struct sockaddr_storage r_addr;
|
||||
u_short r_port;
|
||||
char *r_name;
|
||||
char *r_num;
|
||||
|
||||
stream_data i2r; /*The stream from initiator to responder*/
|
||||
stream_data r2i; /*The stream from responder to initiator*/
|
||||
|
||||
struct timeval start_time;
|
||||
struct timeval last_seen_time;
|
||||
proto_handler *analyzer; /*The analyzer to call with new data*/
|
||||
struct conn_struct_ *backptr;
|
||||
stream_data i2r; /*The stream from initiator to responder*/
|
||||
stream_data r2i; /*The stream from responder to initiator*/
|
||||
|
||||
struct timeval start_time;
|
||||
struct timeval last_seen_time;
|
||||
proto_handler *analyzer; /*The analyzer to call with new data*/
|
||||
struct conn_struct_ *backptr;
|
||||
} tcp_conn;
|
||||
|
||||
int tcp_find_conn PROTO_LIST((tcp_conn **connp,
|
||||
int *directionp,
|
||||
struct sockaddr_storage *src_addr, u_short src_port,
|
||||
struct sockaddr_storage *dst_addr, u_short dst_port));
|
||||
int tcp_find_conn PROTO_LIST((tcp_conn * *connp,
|
||||
int *directionp,
|
||||
struct sockaddr_storage *src_addr,
|
||||
u_short src_port,
|
||||
struct sockaddr_storage *dst_addr,
|
||||
u_short dst_port));
|
||||
|
||||
int tcp_create_conn PROTO_LIST((tcp_conn **connp,
|
||||
struct sockaddr_storage *initiator_addr, u_short initiator_port,
|
||||
struct sockaddr_storage *responder_addr, u_short responder_port));
|
||||
int tcp_create_conn PROTO_LIST((tcp_conn * *connp,
|
||||
struct sockaddr_storage *initiator_addr,
|
||||
u_short initiator_port,
|
||||
struct sockaddr_storage *responder_addr,
|
||||
u_short responder_port));
|
||||
|
||||
int tcp_destroy_conn PROTO_LIST((tcp_conn *conn));
|
||||
int free_tcp_segment_queue PROTO_LIST((segment *seg));
|
||||
int copy_tcp_segment_queue PROTO_LIST((segment **out,segment *in));
|
||||
int tcp_destroy_conn PROTO_LIST((tcp_conn * conn));
|
||||
int free_tcp_segment_queue PROTO_LIST((segment * seg));
|
||||
int copy_tcp_segment_queue PROTO_LIST((segment * *out, segment *in));
|
||||
|
||||
int clean_old_conn(void);
|
||||
int destroy_all_conn(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
749
base/tcppack.c
749
base/tcppack.c
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,164 +44,159 @@
|
|||
ekr@rtfm.com Tue Dec 29 12:43:39 1998
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "network.h"
|
||||
#ifndef _WIN32
|
||||
# include <sys/socket.h>
|
||||
# include <arpa/inet.h>
|
||||
# ifndef LINUX
|
||||
# include <netinet/tcp_seq.h>
|
||||
# else
|
||||
# define SEQ_LT(x,y) ((int)((x)-(y))<0)
|
||||
# endif
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#ifndef LINUX
|
||||
#include <netinet/tcp_seq.h>
|
||||
#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
|
||||
#include <ctype.h>
|
||||
#include "debug.h"
|
||||
#include "tcpconn.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,
|
||||
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));
|
||||
int process_tcp_packet(proto_mod *handler, proto_ctx *ctx, packet *p) {
|
||||
int r, _status;
|
||||
int direction;
|
||||
stream_data *stream;
|
||||
tcp_conn *conn;
|
||||
|
||||
int
|
||||
process_tcp_packet (proto_mod *handler, proto_ctx *ctx, packet *p)
|
||||
{
|
||||
int r,_status;
|
||||
int direction;
|
||||
stream_data *stream;
|
||||
tcp_conn *conn;
|
||||
if(p->len < 20)
|
||||
ABORT(1);
|
||||
|
||||
if(p->len < 20)
|
||||
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,
|
||||
ntohs(p->tcp->th_sport),&p->r_addr.so_st,ntohs(p->tcp->th_dport)))){
|
||||
if(r!=R_NOT_FOUND)
|
||||
ABORT(r);
|
||||
|
||||
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)));
|
||||
return(0);
|
||||
}
|
||||
|
||||
if((r=new_connection(handler,ctx,p,&conn)))
|
||||
ABORT(r);
|
||||
return(0);
|
||||
}
|
||||
|
||||
stream=direction==DIR_R2I?&conn->r2i:&conn->i2r;
|
||||
|
||||
memcpy(&conn->last_seen_time,&p->ts,sizeof(struct timeval));
|
||||
|
||||
switch(conn->state){
|
||||
case TCP_STATE_SYN1:
|
||||
if(direction == DIR_R2I && (p->tcp->th_flags & TH_SYN)) {
|
||||
DBG((0,"SYN2 seq: %u",ntohl(p->tcp->th_seq)));
|
||||
conn->r2i.seq=ntohl(p->tcp->th_seq)+1;
|
||||
conn->r2i.ack=ntohl(p->tcp->th_ack)+1;
|
||||
conn->state=TCP_STATE_ACK;
|
||||
}
|
||||
break;
|
||||
case TCP_STATE_SYN2:
|
||||
if(direction == DIR_I2R && (p->tcp->th_flags & TH_SYN)) {
|
||||
DBG((0,"SYN1 seq: %u",ntohl(p->tcp->th_seq)));
|
||||
conn->i2r.seq=ntohl(p->tcp->th_seq)+1;
|
||||
conn->i2r.ack=ntohl(p->tcp->th_ack)+1;
|
||||
conn->state=TCP_STATE_ACK;
|
||||
}
|
||||
break;
|
||||
case TCP_STATE_ACK:
|
||||
{
|
||||
if(direction != DIR_I2R)
|
||||
break;
|
||||
DBG((0,"ACK seq: %u",ntohl(p->tcp->th_seq)));
|
||||
conn->i2r.ack=ntohl(p->tcp->th_ack)+1;
|
||||
if(!(NET_print_flags & NET_PRINT_JSON)) {
|
||||
if(NET_print_flags & NET_PRINT_TYPESET)
|
||||
printf("\\fC");
|
||||
printf("New TCP connection #%d: %s(%d) <-> %s(%d)\n",
|
||||
conn->conn_number,
|
||||
conn->i_name,conn->i_port,
|
||||
conn->r_name,conn->r_port);
|
||||
if(NET_print_flags & NET_PRINT_TYPESET)
|
||||
printf("\\fR");
|
||||
}
|
||||
conn->state=TCP_STATE_ESTABLISHED;
|
||||
}
|
||||
case TCP_STATE_ESTABLISHED:
|
||||
case TCP_STATE_FIN1:
|
||||
{
|
||||
if(p->tcp->th_flags & TH_SYN)
|
||||
break;
|
||||
if((r=process_data_segment(conn,handler,p,stream,direction)))
|
||||
ABORT(r);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if(conn->state==TCP_STATE_CLOSED)
|
||||
tcp_destroy_conn(conn);
|
||||
|
||||
|
||||
_status=0;
|
||||
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;
|
||||
|
||||
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);
|
||||
DBG((0,"SYN1 seq: %u",ntohl(p->tcp->th_seq)));
|
||||
conn->i2r.seq=ntohl(p->tcp->th_seq)+1;
|
||||
conn->i2r.ack=ntohl(p->tcp->th_ack)+1;
|
||||
conn->state=TCP_STATE_SYN1;
|
||||
} else { // SYN&ACK comes first somehow
|
||||
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))))
|
||||
ABORT(r);
|
||||
DBG((0,"SYN2 seq: %u",ntohl(p->tcp->th_seq)));
|
||||
conn->r2i.seq=ntohl(p->tcp->th_seq)+1;
|
||||
conn->r2i.ack=ntohl(p->tcp->th_ack)+1;
|
||||
conn->state=TCP_STATE_SYN2;
|
||||
}
|
||||
memcpy(&conn->start_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->r_addr,&conn->r_name);
|
||||
addrtotext(&conn->i_addr,&conn->i_num);
|
||||
addrtotext(&conn->r_addr,&conn->r_num);
|
||||
if((r=create_proto_handler(handler,ctx,&conn->analyzer,conn,&p->ts)))
|
||||
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)))) {
|
||||
if(r != R_NOT_FOUND)
|
||||
ABORT(r);
|
||||
|
||||
*connp=conn;
|
||||
_status=0;
|
||||
abort:
|
||||
return(_status);
|
||||
|
||||
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)));
|
||||
return (0);
|
||||
}
|
||||
|
||||
if((r = new_connection(handler, ctx, p, &conn)))
|
||||
ABORT(r);
|
||||
return (0);
|
||||
}
|
||||
|
||||
stream = direction == DIR_R2I ? &conn->r2i : &conn->i2r;
|
||||
|
||||
memcpy(&conn->last_seen_time, &p->ts, sizeof(struct timeval));
|
||||
|
||||
switch(conn->state) {
|
||||
case TCP_STATE_SYN1:
|
||||
if(direction == DIR_R2I && (p->tcp->th_flags & TH_SYN)) {
|
||||
DBG((0, "SYN2 seq: %u", ntohl(p->tcp->th_seq)));
|
||||
conn->r2i.seq = ntohl(p->tcp->th_seq) + 1;
|
||||
conn->r2i.ack = ntohl(p->tcp->th_ack) + 1;
|
||||
conn->state = TCP_STATE_ACK;
|
||||
}
|
||||
break;
|
||||
case TCP_STATE_SYN2:
|
||||
if(direction == DIR_I2R && (p->tcp->th_flags & TH_SYN)) {
|
||||
DBG((0, "SYN1 seq: %u", ntohl(p->tcp->th_seq)));
|
||||
conn->i2r.seq = ntohl(p->tcp->th_seq) + 1;
|
||||
conn->i2r.ack = ntohl(p->tcp->th_ack) + 1;
|
||||
conn->state = TCP_STATE_ACK;
|
||||
}
|
||||
break;
|
||||
case TCP_STATE_ACK: {
|
||||
if(direction != DIR_I2R)
|
||||
break;
|
||||
DBG((0, "ACK seq: %u", ntohl(p->tcp->th_seq)));
|
||||
conn->i2r.ack = ntohl(p->tcp->th_ack) + 1;
|
||||
if(!(NET_print_flags & NET_PRINT_JSON)) {
|
||||
if(NET_print_flags & NET_PRINT_TYPESET)
|
||||
printf("\\fC");
|
||||
printf("New TCP connection #%d: %s(%d) <-> %s(%d)\n", conn->conn_number,
|
||||
conn->i_name, conn->i_port, conn->r_name, conn->r_port);
|
||||
if(NET_print_flags & NET_PRINT_TYPESET)
|
||||
printf("\\fR");
|
||||
}
|
||||
conn->state = TCP_STATE_ESTABLISHED;
|
||||
}
|
||||
case TCP_STATE_ESTABLISHED:
|
||||
case TCP_STATE_FIN1: {
|
||||
if(p->tcp->th_flags & TH_SYN)
|
||||
break;
|
||||
if((r = process_data_segment(conn, handler, p, stream, direction)))
|
||||
ABORT(r);
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if(conn->state == TCP_STATE_CLOSED)
|
||||
tcp_destroy_conn(conn);
|
||||
|
||||
_status = 0;
|
||||
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;
|
||||
|
||||
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);
|
||||
DBG((0, "SYN1 seq: %u", ntohl(p->tcp->th_seq)));
|
||||
conn->i2r.seq = ntohl(p->tcp->th_seq) + 1;
|
||||
conn->i2r.ack = ntohl(p->tcp->th_ack) + 1;
|
||||
conn->state = TCP_STATE_SYN1;
|
||||
} else { // SYN&ACK comes first somehow
|
||||
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))))
|
||||
ABORT(r);
|
||||
DBG((0, "SYN2 seq: %u", ntohl(p->tcp->th_seq)));
|
||||
conn->r2i.seq = ntohl(p->tcp->th_seq) + 1;
|
||||
conn->r2i.ack = ntohl(p->tcp->th_ack) + 1;
|
||||
conn->state = TCP_STATE_SYN2;
|
||||
}
|
||||
memcpy(&conn->start_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->r_addr, &conn->r_name);
|
||||
addrtotext(&conn->i_addr, &conn->i_num);
|
||||
addrtotext(&conn->r_addr, &conn->r_num);
|
||||
if((r = create_proto_handler(handler, ctx, &conn->analyzer, conn, &p->ts)))
|
||||
ABORT(r);
|
||||
|
||||
*connp = conn;
|
||||
_status = 0;
|
||||
abort:
|
||||
return (_status);
|
||||
}
|
||||
|
||||
/*#define STRIM(_seq,s) { \
|
||||
int l;\
|
||||
int off;\
|
||||
|
@ -213,258 +209,253 @@ new_connection (proto_mod *handler, proto_ctx *ctx, packet *p, tcp_conn **connp)
|
|||
if((s)->next) { \
|
||||
if((s)->s_seq >= (s)->next->s_seq) {\
|
||||
l=(s)->next->s_seq - (s)->s_seq; \
|
||||
if((s)->len){\
|
||||
(s)->len-=(l+1); \
|
||||
(s)->s_seq-=(l+1);\
|
||||
}\
|
||||
if((s)->len){\
|
||||
(s)->len-=(l+1); \
|
||||
(s)->s_seq-=(l+1);\
|
||||
}\
|
||||
}\
|
||||
}\
|
||||
}
|
||||
*/
|
||||
|
||||
static int
|
||||
process_data_segment (tcp_conn *conn, proto_mod *handler, packet *p, stream_data *stream, int direction)
|
||||
{
|
||||
int r,_status;
|
||||
tcp_seq seq,right_edge;
|
||||
segment _seg;
|
||||
segment *seg,*nseg=0;
|
||||
long l;
|
||||
static int process_data_segment(tcp_conn *conn,
|
||||
proto_mod *handler,
|
||||
packet *p,
|
||||
stream_data *stream,
|
||||
int direction) {
|
||||
int r, _status;
|
||||
tcp_seq seq, right_edge;
|
||||
segment _seg;
|
||||
segment *seg, *nseg = 0;
|
||||
long l;
|
||||
|
||||
l=p->len - p->tcp->th_off * 4;
|
||||
l = p->len - p->tcp->th_off * 4;
|
||||
|
||||
if(l < 0) {
|
||||
fprintf(stderr,"Malformed packet, computed TCP segment size is negative, skipping ...\n");
|
||||
return(0);
|
||||
}
|
||||
|
||||
if(stream->close){
|
||||
DBG((0,"Rejecting packet received after FIN: %u:%u(%u)",
|
||||
ntohl(p->tcp->th_seq),ntohl(p->tcp->th_seq+l),l));
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*The idea here is to pass all available segments
|
||||
to the analyzer at once. Since we want to preserve
|
||||
the segment packet data, we pass the data as a linked list of
|
||||
segments*/
|
||||
seq=ntohl(p->tcp->th_seq);
|
||||
|
||||
/*Add ACK processing logic here <TODO>*/
|
||||
if(p->tcp->th_flags & TH_ACK){
|
||||
long acknum,acked;
|
||||
|
||||
|
||||
acknum=ntohl(p->tcp->th_ack);
|
||||
acked=acknum-stream->ack;
|
||||
|
||||
if(acked && !l){
|
||||
/*
|
||||
if((r=timestamp_diff(&p->ts,&conn->start_time,&dt)))
|
||||
ERETURN(r);
|
||||
printf("%d%c%4.4d ",dt.tv_sec,'.',dt.tv_usec/100);
|
||||
if(direction == DIR_R2I)
|
||||
printf("S>C ");
|
||||
else
|
||||
printf("C>S ");
|
||||
|
||||
printf("ACK (%d)\n",acked); */
|
||||
}
|
||||
|
||||
stream->ack=acknum;
|
||||
}
|
||||
|
||||
|
||||
DBG((0,"Stream Seq %u ",stream->seq));
|
||||
|
||||
/* Check to see if this packet has been processed already */
|
||||
right_edge=seq + (p->len - (p->tcp->th_off)*4);
|
||||
if(!(p->tcp->th_flags & (TH_RST)) && SEQ_LT(right_edge,stream->seq))
|
||||
return(0);
|
||||
|
||||
if(SEQ_LT(stream->seq,seq)){
|
||||
/* Out of order segment */
|
||||
tcp_seq left_edge;
|
||||
|
||||
for(seg=0;seg;seg=seg?seg->next:stream->oo_queue){
|
||||
if(seg->next->s_seq > seq)
|
||||
break;
|
||||
}
|
||||
|
||||
if(!(nseg=(segment *)calloc(1,sizeof(segment))))
|
||||
ABORT(R_NO_MEMORY);
|
||||
if((r=packet_copy(p,&nseg->p)))
|
||||
ABORT(r);
|
||||
nseg->s_seq=seq;
|
||||
|
||||
/*Insert this segment into the reassembly queue*/
|
||||
if(seg){
|
||||
nseg->next=seg->next;
|
||||
seg->next=nseg;
|
||||
}
|
||||
else{
|
||||
nseg->next=stream->oo_queue;
|
||||
stream->oo_queue=nseg;
|
||||
}
|
||||
|
||||
left_edge=seg?seg->s_seq:stream->seq;
|
||||
STRIM(left_edge,nseg);
|
||||
}
|
||||
else{
|
||||
/*First segment -- just thread the unallocated data on the
|
||||
list so we can pass to the analyzer*/
|
||||
_seg.next=0;
|
||||
_seg.p=p;
|
||||
_seg.s_seq=seq;
|
||||
|
||||
/*Now split the queue. Assemble as many packets as possible
|
||||
and pass them to the analyzer. But process anything with a
|
||||
RST in it immediately and ignore any data that might be in it
|
||||
*/
|
||||
if(_seg.p->tcp->th_flags & (TH_RST)){
|
||||
stream->close=_seg.p->tcp->th_flags & (TH_RST);
|
||||
seg=&_seg;
|
||||
|
||||
conn->state=TCP_STATE_CLOSED;
|
||||
}
|
||||
else{
|
||||
STRIM(stream->seq,&_seg);
|
||||
|
||||
if(_seg.p->tcp->th_flags & (TH_FIN)){
|
||||
stream->close=_seg.p->tcp->th_flags & (TH_FIN);
|
||||
seg=&_seg;
|
||||
}
|
||||
else {
|
||||
for(seg=&_seg;seg->next;seg=seg->next){
|
||||
if(seg->p->tcp->th_flags & (TH_FIN)){
|
||||
stream->close=_seg.p->tcp->th_flags & (TH_FIN);
|
||||
break;
|
||||
}
|
||||
if(seg->len + seg->s_seq != seg->next->s_seq)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*Note that this logic is broken because it doesn't
|
||||
do the CLOSE_WAIT/FIN_WAIT stuff, but it's probably
|
||||
close enough, since this is a higher level protocol analyzer,
|
||||
not a TCP analyzer*/
|
||||
if(seg->p->tcp->th_flags & (TH_FIN) ){
|
||||
if(conn->state == TCP_STATE_ESTABLISHED)
|
||||
conn->state=TCP_STATE_FIN1;
|
||||
else
|
||||
conn->state=TCP_STATE_CLOSED;
|
||||
}
|
||||
|
||||
free_tcp_segment_queue(stream->oo_queue);
|
||||
stream->oo_queue=seg->next;
|
||||
seg->next=0;
|
||||
stream->seq=seg->s_seq + seg->len;
|
||||
|
||||
DBG((0,"Analyzing 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);
|
||||
}
|
||||
}
|
||||
|
||||
if(stream->close){
|
||||
DBG((0,"Closing with 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);
|
||||
}
|
||||
}
|
||||
|
||||
free_tcp_segment_queue(_seg.next);
|
||||
}
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
return(_status);
|
||||
if(l < 0) {
|
||||
fprintf(stderr,
|
||||
"Malformed packet, computed TCP segment size is negative, skipping "
|
||||
"...\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
print_tcp_packet (packet *p)
|
||||
{
|
||||
char *src=0,*dst=0;
|
||||
|
||||
struct timeval *ts = &p->ts;
|
||||
|
||||
if(!(NET_print_flags & NET_PRINT_TCP_HDR))
|
||||
return(0);
|
||||
|
||||
lookuphostname(&p->i_addr.so_st,&src);
|
||||
lookuphostname(&p->r_addr.so_st,&dst);
|
||||
|
||||
if(!(NET_print_flags & NET_PRINT_JSON)) {
|
||||
if(NET_print_flags & NET_PRINT_TS) {
|
||||
printf("%lld%c%4.4lld ", (long long)ts->tv_sec,'.',(long long)ts->tv_usec/100);
|
||||
}
|
||||
printf("TCP: %s(%d) -> %s(%d) ",
|
||||
src,
|
||||
ntohs(p->tcp->th_sport),
|
||||
dst,
|
||||
ntohs(p->tcp->th_dport));
|
||||
|
||||
printf("Seq %u.(%d) ",
|
||||
ntohl(p->tcp->th_seq),
|
||||
p->len - p->tcp->th_off *4);
|
||||
|
||||
if(p->tcp->th_flags & TH_ACK)
|
||||
printf("ACK %u ",ntohl(p->tcp->th_ack));
|
||||
|
||||
if(p->tcp->th_flags & TH_FIN)
|
||||
printf("FIN ");
|
||||
if(p->tcp->th_flags & TH_SYN)
|
||||
printf("SYN ");
|
||||
if(p->tcp->th_flags & TH_RST)
|
||||
printf("RST ");
|
||||
if(p->tcp->th_flags & TH_PUSH)
|
||||
printf("PUSH ");
|
||||
if(p->tcp->th_flags & TH_URG)
|
||||
printf("URG ");
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
free(src);
|
||||
free(dst);
|
||||
return(0);
|
||||
if(stream->close) {
|
||||
DBG((0, "Rejecting packet received after FIN: %u:%u(%u)",
|
||||
ntohl(p->tcp->th_seq), ntohl(p->tcp->th_seq + l), l));
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
STRIM (UINT4 _seq, segment *s)
|
||||
{
|
||||
int l;
|
||||
int off;
|
||||
/*The idea here is to pass all available segments
|
||||
to the analyzer at once. Since we want to preserve
|
||||
the segment packet data, we pass the data as a linked list of
|
||||
segments*/
|
||||
seq = ntohl(p->tcp->th_seq);
|
||||
|
||||
/* Test: this shouldn't damage things at all
|
||||
s->p->data-=4;
|
||||
s->p->len+=4;
|
||||
s->s_seq-=4;
|
||||
/*Add ACK processing logic here <TODO>*/
|
||||
if(p->tcp->th_flags & TH_ACK) {
|
||||
long acknum, acked;
|
||||
|
||||
acknum = ntohl(p->tcp->th_ack);
|
||||
acked = acknum - stream->ack;
|
||||
|
||||
if(acked && !l) {
|
||||
/*
|
||||
if((r=timestamp_diff(&p->ts,&conn->start_time,&dt)))
|
||||
ERETURN(r);
|
||||
printf("%d%c%4.4d ",dt.tv_sec,'.',dt.tv_usec/100);
|
||||
if(direction == DIR_R2I)
|
||||
printf("S>C ");
|
||||
else
|
||||
printf("C>S ");
|
||||
|
||||
printf("ACK (%d)\n",acked); */
|
||||
}
|
||||
|
||||
stream->ack = acknum;
|
||||
}
|
||||
|
||||
DBG((0, "Stream Seq %u ", stream->seq));
|
||||
|
||||
/* Check to see if this packet has been processed already */
|
||||
right_edge = seq + (p->len - (p->tcp->th_off) * 4);
|
||||
if(!(p->tcp->th_flags & (TH_RST)) && SEQ_LT(right_edge, stream->seq))
|
||||
return (0);
|
||||
|
||||
if(SEQ_LT(stream->seq, seq)) {
|
||||
/* Out of order segment */
|
||||
tcp_seq left_edge;
|
||||
|
||||
for(seg = 0; seg; seg = seg ? seg->next : stream->oo_queue) {
|
||||
if(seg->next->s_seq > seq)
|
||||
break;
|
||||
}
|
||||
|
||||
if(!(nseg = (segment *)calloc(1, sizeof(segment))))
|
||||
ABORT(R_NO_MEMORY);
|
||||
if((r = packet_copy(p, &nseg->p)))
|
||||
ABORT(r);
|
||||
nseg->s_seq = seq;
|
||||
|
||||
/*Insert this segment into the reassembly queue*/
|
||||
if(seg) {
|
||||
nseg->next = seg->next;
|
||||
seg->next = nseg;
|
||||
} else {
|
||||
nseg->next = stream->oo_queue;
|
||||
stream->oo_queue = nseg;
|
||||
}
|
||||
|
||||
left_edge = seg ? seg->s_seq : stream->seq;
|
||||
STRIM(left_edge, nseg);
|
||||
} else {
|
||||
/*First segment -- just thread the unallocated data on the
|
||||
list so we can pass to the analyzer*/
|
||||
_seg.next = 0;
|
||||
_seg.p = p;
|
||||
_seg.s_seq = seq;
|
||||
|
||||
/*Now split the queue. Assemble as many packets as possible
|
||||
and pass them to the analyzer. But process anything with a
|
||||
RST in it immediately and ignore any data that might be in it
|
||||
*/
|
||||
|
||||
l=_seq - (s)->s_seq; /* number of bytes to trim
|
||||
from the left of s */
|
||||
off=(s)->p->tcp->th_off*4;
|
||||
if(l>((s)->p->len-off)) ERETURN(R_BAD_DATA);
|
||||
if(_seg.p->tcp->th_flags & (TH_RST)) {
|
||||
stream->close = _seg.p->tcp->th_flags & (TH_RST);
|
||||
seg = &_seg;
|
||||
|
||||
/* Now remove the leading l bytes */
|
||||
(s)->data=(s)->p->data + off + (l) ;
|
||||
(s)->len=(s)->p->len - (off + l);
|
||||
(s)->s_seq += (l);
|
||||
conn->state = TCP_STATE_CLOSED;
|
||||
} else {
|
||||
STRIM(stream->seq, &_seg);
|
||||
|
||||
/* Now trim to the right if necessary */
|
||||
if((s)->next) {
|
||||
if((s)->s_seq >= (s)->next->s_seq) {
|
||||
l=(s)->s_seq - (s)->next->s_seq;
|
||||
|
||||
if((s)->len){
|
||||
(s)->len-=(l+1);
|
||||
}
|
||||
if(_seg.p->tcp->th_flags & (TH_FIN)) {
|
||||
stream->close = _seg.p->tcp->th_flags & (TH_FIN);
|
||||
seg = &_seg;
|
||||
} else {
|
||||
for(seg = &_seg; seg->next; seg = seg->next) {
|
||||
if(seg->p->tcp->th_flags & (TH_FIN)) {
|
||||
stream->close = _seg.p->tcp->th_flags & (TH_FIN);
|
||||
break;
|
||||
}
|
||||
if(seg->len + seg->s_seq != seg->next->s_seq)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*Note that this logic is broken because it doesn't
|
||||
do the CLOSE_WAIT/FIN_WAIT stuff, but it's probably
|
||||
close enough, since this is a higher level protocol analyzer,
|
||||
not a TCP analyzer*/
|
||||
if(seg->p->tcp->th_flags & (TH_FIN)) {
|
||||
if(conn->state == TCP_STATE_ESTABLISHED)
|
||||
conn->state = TCP_STATE_FIN1;
|
||||
else
|
||||
conn->state = TCP_STATE_CLOSED;
|
||||
}
|
||||
|
||||
free_tcp_segment_queue(stream->oo_queue);
|
||||
stream->oo_queue = seg->next;
|
||||
seg->next = 0;
|
||||
stream->seq = seg->s_seq + seg->len;
|
||||
|
||||
DBG((0, "Analyzing 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);
|
||||
}
|
||||
}
|
||||
|
||||
return(0);
|
||||
|
||||
if(stream->close) {
|
||||
DBG((0, "Closing with 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);
|
||||
}
|
||||
}
|
||||
|
||||
free_tcp_segment_queue(_seg.next);
|
||||
}
|
||||
|
||||
_status = 0;
|
||||
abort:
|
||||
return (_status);
|
||||
}
|
||||
|
||||
static int print_tcp_packet(packet *p) {
|
||||
char *src = 0, *dst = 0;
|
||||
|
||||
struct timeval *ts = &p->ts;
|
||||
|
||||
if(!(NET_print_flags & NET_PRINT_TCP_HDR))
|
||||
return (0);
|
||||
|
||||
lookuphostname(&p->i_addr.so_st, &src);
|
||||
lookuphostname(&p->r_addr.so_st, &dst);
|
||||
|
||||
if(!(NET_print_flags & NET_PRINT_JSON)) {
|
||||
if(NET_print_flags & NET_PRINT_TS) {
|
||||
printf("%lld%c%4.4lld ", (long long)ts->tv_sec, '.',
|
||||
(long long)ts->tv_usec / 100);
|
||||
}
|
||||
printf("TCP: %s(%d) -> %s(%d) ", src, ntohs(p->tcp->th_sport), dst,
|
||||
ntohs(p->tcp->th_dport));
|
||||
|
||||
printf("Seq %u.(%d) ", ntohl(p->tcp->th_seq), p->len - p->tcp->th_off * 4);
|
||||
|
||||
if(p->tcp->th_flags & TH_ACK)
|
||||
printf("ACK %u ", ntohl(p->tcp->th_ack));
|
||||
|
||||
if(p->tcp->th_flags & TH_FIN)
|
||||
printf("FIN ");
|
||||
if(p->tcp->th_flags & TH_SYN)
|
||||
printf("SYN ");
|
||||
if(p->tcp->th_flags & TH_RST)
|
||||
printf("RST ");
|
||||
if(p->tcp->th_flags & TH_PUSH)
|
||||
printf("PUSH ");
|
||||
if(p->tcp->th_flags & TH_URG)
|
||||
printf("URG ");
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
free(src);
|
||||
free(dst);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int STRIM(UINT4 _seq, segment *s) {
|
||||
int l;
|
||||
int off;
|
||||
|
||||
/* Test: this shouldn't damage things at all
|
||||
s->p->data-=4;
|
||||
s->p->len+=4;
|
||||
s->s_seq-=4;
|
||||
*/
|
||||
|
||||
l = _seq - (s)->s_seq; /* number of bytes to trim
|
||||
from the left of s */
|
||||
off = (s)->p->tcp->th_off * 4;
|
||||
if(l > ((s)->p->len - off))
|
||||
ERETURN(R_BAD_DATA);
|
||||
|
||||
/* Now remove the leading l bytes */
|
||||
(s)->data = (s)->p->data + off + (l);
|
||||
(s)->len = (s)->p->len - (off + l);
|
||||
(s)->s_seq += (l);
|
||||
|
||||
/* Now trim to the right if necessary */
|
||||
if((s)->next) {
|
||||
if((s)->s_seq >= (s)->next->s_seq) {
|
||||
l = (s)->s_seq - (s)->next->s_seq;
|
||||
|
||||
if((s)->len) {
|
||||
(s)->len -= (l + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,12 +44,9 @@
|
|||
ekr@rtfm.com Wed Jan 6 15:08:30 1999
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _tcppack_h
|
||||
#define _tcppack_h
|
||||
|
||||
int process_tcp_packet PROTO_LIST((proto_mod *mod,proto_ctx *ctx,
|
||||
packet *p));
|
||||
int process_tcp_packet PROTO_LIST((proto_mod * mod, proto_ctx *ctx, packet *p));
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
Associative array code. This code has the advantage that different
|
||||
elements can have different create and destroy operators. Unfortunately,
|
||||
this can waste space.
|
||||
|
||||
|
||||
|
||||
Copyright (C) 1999-2000 RTFM, Inc.
|
||||
All Rights Reserved
|
||||
|
@ -22,7 +22,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -39,7 +39,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -47,37 +48,39 @@
|
|||
ekr@rtfm.com Sun Jan 17 17:57:18 1999
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _r_assoc_h
|
||||
#define _r_assoc_h
|
||||
|
||||
typedef struct r_assoc_ r_assoc;
|
||||
|
||||
int r_assoc_create PROTO_LIST((r_assoc **assocp));
|
||||
int r_assoc_insert PROTO_LIST((r_assoc *assoc,char *key,int len,
|
||||
void *value,int (*copy)(void **new,void *old),
|
||||
int (*destroy)(void *ptr),int how));
|
||||
#define R_ASSOC_REPLACE 0x1
|
||||
#define R_ASSOC_NEW 0x2
|
||||
int r_assoc_create PROTO_LIST((r_assoc * *assocp));
|
||||
int r_assoc_insert PROTO_LIST((r_assoc * assoc,
|
||||
char *key,
|
||||
int len,
|
||||
void *value,
|
||||
int (*copy)(void **new, void *old),
|
||||
int (*destroy)(void *ptr),
|
||||
int how));
|
||||
#define R_ASSOC_REPLACE 0x1
|
||||
#define R_ASSOC_NEW 0x2
|
||||
|
||||
int r_assoc_fetch 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_destroy PROTO_LIST((r_assoc **assocp));
|
||||
int r_assoc_fetch
|
||||
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_destroy PROTO_LIST((r_assoc * *assocp));
|
||||
|
||||
/*We need iterators, but I haven't written them yet*/
|
||||
typedef struct r_assoc_iterator_ {
|
||||
r_assoc *assoc;
|
||||
int prev_chain;
|
||||
struct r_assoc_el_ *prev;
|
||||
int next_chain;
|
||||
struct r_assoc_el_ *next;
|
||||
r_assoc *assoc;
|
||||
int prev_chain;
|
||||
struct r_assoc_el_ *prev;
|
||||
int next_chain;
|
||||
struct r_assoc_el_ *next;
|
||||
} 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,
|
||||
void **val));
|
||||
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, void **val));
|
||||
int r_assoc_iter_delete PROTO_LIST((r_assoc_iterator *));
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -7,20 +7,18 @@
|
|||
ekr@rtfm.com Wed Oct 3 10:43:50 2001
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _r_bitfield_h
|
||||
#define _r_bitfield_h
|
||||
|
||||
typedef struct r_bitfield_ {
|
||||
UINT4 *data;
|
||||
UINT4 len;
|
||||
UINT4 base;
|
||||
UINT4 *data;
|
||||
UINT4 len;
|
||||
UINT4 base;
|
||||
} r_bitfield;
|
||||
|
||||
int r_bitfield_set 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_destroy PROTO_LIST((r_bitfield **setp));
|
||||
int r_bitfield_set 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_destroy PROTO_LIST((r_bitfield * *setp));
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,7 +44,6 @@
|
|||
ekr@rtfm.com Tue Dec 22 10:40:07 1998
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _r_common_h
|
||||
#define _r_common_h
|
||||
|
||||
|
@ -59,7 +59,7 @@
|
|||
#include "r_data.h"
|
||||
|
||||
/*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 */
|
||||
#ifndef HAVE_STRDUP
|
||||
|
@ -67,4 +67,3 @@ char *strdup PROTO_LIST((char *in));
|
|||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,26 +44,30 @@
|
|||
ekr@rtfm.com Wed Feb 10 14:18:19 1999
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _r_data_h
|
||||
#define _r_data_h
|
||||
|
||||
typedef struct Data_ {
|
||||
UCHAR *data;
|
||||
int len;
|
||||
UCHAR *data;
|
||||
int len;
|
||||
} Data;
|
||||
|
||||
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_make PROTO_LIST((Data *dp, UCHAR *d,int l));
|
||||
int r_data_destroy PROTO_LIST((Data **dp));
|
||||
int r_data_copy PROTO_LIST((Data *dst,Data *src));
|
||||
int r_data_zfree PROTO_LIST((Data *d));
|
||||
int r_data_compare PROTO_LIST((Data *d1,Data *d2));
|
||||
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_make PROTO_LIST((Data * dp, UCHAR *d, int l));
|
||||
int r_data_destroy PROTO_LIST((Data * *dp));
|
||||
int r_data_copy PROTO_LIST((Data * dst, Data *src));
|
||||
int r_data_zfree PROTO_LIST((Data * d));
|
||||
int r_data_compare PROTO_LIST((Data * d1, Data *d2));
|
||||
|
||||
#define INIT_DATA(a,b,c) (a).data=b; (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
|
||||
#define INIT_DATA(a, b, c) \
|
||||
(a).data = b; \
|
||||
(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
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,7 +44,6 @@
|
|||
ekr@rtfm.com Tue Dec 22 10:39:14 1998
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _r_defaults_h
|
||||
#define _r_defaults_h
|
||||
|
||||
|
@ -51,9 +51,7 @@
|
|||
#define R_USE_PROTOTYPES 1
|
||||
#endif
|
||||
|
||||
|
||||
/*The needs defines don't belong here*/
|
||||
#define R_NEEDS_STDLIB_H
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,20 +44,18 @@
|
|||
ekr@rtfm.com Tue Dec 22 10:59:49 1998
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _r_errors_h
|
||||
#define _r_errors_h
|
||||
|
||||
#define R_NO_MEMORY 1 /*out of memory*/
|
||||
#define R_NOT_FOUND 2 /*Item not found*/
|
||||
#define R_INTERNAL 3 /*Unspecified internal error*/
|
||||
#define R_ALREADY 4 /*Action already done*/
|
||||
#define R_EOD 5 /*end of data*/
|
||||
#define R_BAD_ARGS 6 /*Bad arguments*/
|
||||
#define R_BAD_DATA 7 /*Bad data*/
|
||||
#define R_WOULDBLOCK 8 /*Operation would block */
|
||||
#define R_NO_MEMORY 1 /*out of memory*/
|
||||
#define R_NOT_FOUND 2 /*Item not found*/
|
||||
#define R_INTERNAL 3 /*Unspecified internal error*/
|
||||
#define R_ALREADY 4 /*Action already done*/
|
||||
#define R_EOD 5 /*end of data*/
|
||||
#define R_BAD_ARGS 6 /*Bad arguments*/
|
||||
#define R_BAD_DATA 7 /*Bad data*/
|
||||
#define R_WOULDBLOCK 8 /*Operation would block */
|
||||
|
||||
int verr_exit PROTO_LIST((char *fmt,...));
|
||||
int verr_exit PROTO_LIST((char *fmt, ...));
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,7 +44,6 @@
|
|||
ekr@rtfm.com Tue Dec 22 11:38:50 1998
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _r_includes_h
|
||||
#define _r_includes_h
|
||||
|
||||
|
@ -59,4 +59,3 @@
|
|||
#include <string.h>
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,27 +44,28 @@
|
|||
ekr@rtfm.com Tue Jan 19 08:36:48 1999
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _r_list_h
|
||||
#define _r_list_h
|
||||
|
||||
typedef struct r_list_ r_list;
|
||||
|
||||
typedef struct r_list_iterator_ {
|
||||
r_list *list;
|
||||
struct r_list_el_ *ptr;
|
||||
r_list *list;
|
||||
struct r_list_el_ *ptr;
|
||||
} r_list_iterator;
|
||||
|
||||
int r_list_create 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_insert PROTO_LIST((r_list *list,void *value,
|
||||
int (*copy)(void **new,void *old),
|
||||
int (*destroy)(void **ptr)));
|
||||
int r_list_append PROTO_LIST((r_list *list,void *value,
|
||||
int (*copy)(void **new,void *old),
|
||||
int (*destroy)(void **ptr)));
|
||||
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_create 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_insert PROTO_LIST((r_list * list,
|
||||
void *value,
|
||||
int (*copy)(void **new, void *old),
|
||||
int (*destroy)(void **ptr)));
|
||||
int r_list_append PROTO_LIST((r_list * list,
|
||||
void *value,
|
||||
int (*copy)(void **new, void *old),
|
||||
int (*destroy)(void **ptr)));
|
||||
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));
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,11 +44,10 @@
|
|||
ekr@rtfm.com Tue Dec 22 10:37:32 1998
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _r_macros_h
|
||||
#define _r_macros_h
|
||||
|
||||
#if (R_USE_PROTOTYPES==1)
|
||||
#if(R_USE_PROTOTYPES == 1)
|
||||
#define PROTO_LIST(a) a
|
||||
#else
|
||||
#define PROTO_LIST(a) ()
|
||||
|
@ -58,34 +58,52 @@
|
|||
#endif
|
||||
|
||||
#ifdef R_TRACE_ERRORS
|
||||
#define REPORT_ERROR_(caller,a) fprintf(stderr,"%s: error %d at %s:%d (function %s)\n", \
|
||||
caller,a,__FILE__,__LINE__,__FUNCTION__)
|
||||
#define REPORT_ERROR_(caller, a) \
|
||||
fprintf(stderr, "%s: error %d at %s:%d (function %s)\n", caller, a, \
|
||||
__FILE__, __LINE__, __FUNCTION__)
|
||||
#else
|
||||
#define REPORT_ERROR_(caller,a)
|
||||
#endif
|
||||
#define REPORT_ERROR_(caller, a)
|
||||
#endif
|
||||
|
||||
#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
|
||||
|
||||
#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
|
||||
|
||||
#ifndef FREE
|
||||
#define FREE(a) if(a) free(a)
|
||||
#define FREE(a) \
|
||||
if(a) \
|
||||
free(a)
|
||||
#endif
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) (((a)>(b))?(b):(a))
|
||||
#define MIN(a, b) (((a) > (b)) ? (b) : (a))
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(a,b) (((b)>(a))?(b):(a))
|
||||
#define MAX(a, b) (((b) > (a)) ? (b) : (a))
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DBG(a) debug a
|
||||
int debug(int class,char *format,...);
|
||||
int debug(int class, char *format, ...);
|
||||
#else
|
||||
#define DBG(a)
|
||||
#endif
|
||||
|
@ -95,18 +113,24 @@ int debug(int class,char *format,...);
|
|||
#endif
|
||||
|
||||
#ifndef RCALLOC
|
||||
#define RCALLOC(a) calloc(1,a)
|
||||
#define RCALLOC(a) calloc(1, a)
|
||||
#endif
|
||||
|
||||
#ifndef RFREE
|
||||
#define RFREE(a) if(a) free(a)
|
||||
#define RFREE(a) \
|
||||
if(a) \
|
||||
free(a)
|
||||
#endif
|
||||
|
||||
#ifndef RREALLOC
|
||||
#define RREALLOC(a,b) realloc(a,b)
|
||||
#define RREALLOC(a, b) realloc(a, b)
|
||||
#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
|
||||
#include <string.h>
|
||||
|
@ -115,11 +139,11 @@ int debug(int class,char *format,...);
|
|||
#ifndef STRNICMP
|
||||
|
||||
#ifdef _WIN32
|
||||
#define STRNICMP(a,b,n) strnicmp(a,b,n)
|
||||
#define STRNICMP(a, b, n) strnicmp(a, b, n)
|
||||
#else
|
||||
#define STRNICMP(a,b,n) strncasecmp(a,b,n)
|
||||
#define STRNICMP(a, b, n) strncasecmp(a, b, n)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,27 +44,24 @@
|
|||
ekr@rtfm.com Tue Feb 23 14:58:36 1999
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _r_thread_h
|
||||
#define _r_thread_h
|
||||
|
||||
typedef void *r_thread;
|
||||
typedef void *r_rwlock;
|
||||
|
||||
int r_thread_fork PROTO_LIST((void (*func)(void *),void *arg,
|
||||
r_thread *tid));
|
||||
int r_thread_fork PROTO_LIST((void (*func)(void *), void *arg, r_thread *tid));
|
||||
int r_thread_destroy PROTO_LIST((r_thread tid));
|
||||
int r_thread_yield PROTO_LIST((void));
|
||||
int r_thread_exit PROTO_LIST((void));
|
||||
int r_thread_wait_last PROTO_LIST((void));
|
||||
|
||||
int r_rwlock_create PROTO_LIST((r_rwlock **lockp));
|
||||
int r_rwlock_destroy PROTO_LIST((r_rwlock **lock));
|
||||
int r_rwlock_lock PROTO_LIST((r_rwlock *lock,int action));
|
||||
int r_rwlock_create PROTO_LIST((r_rwlock * *lockp));
|
||||
int r_rwlock_destroy PROTO_LIST((r_rwlock * *lock));
|
||||
int r_rwlock_lock PROTO_LIST((r_rwlock * lock, int action));
|
||||
|
||||
#define R_RWLOCK_UNLOCK 0
|
||||
#define R_RWLOCK_RLOCK 1
|
||||
#define R_RWLOCK_WLOCK 2
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,7 +44,6 @@
|
|||
ekr@rtfm.com Thu Mar 4 08:45:41 1999
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _r_time_h
|
||||
#define _r_time_h
|
||||
|
||||
|
@ -52,28 +52,29 @@
|
|||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <winsock2.h>
|
||||
#include <winsock2.h>
|
||||
#else
|
||||
/* Cribbed from the autoconf doc */
|
||||
# if TIME_WITH_SYS_TIME
|
||||
# include <sys/time.h>
|
||||
# include <time.h>
|
||||
# else
|
||||
# if HAVE_SYS_TIME_H
|
||||
# include <sys/time.h>
|
||||
# else
|
||||
# include <time.h>
|
||||
# endif
|
||||
# endif
|
||||
#if TIME_WITH_SYS_TIME
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#else
|
||||
#if HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#else
|
||||
#include <time.h>
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int r_timeval_diff PROTO_LIST((struct timeval *t1,struct timeval *t0,
|
||||
struct timeval *diff));
|
||||
int r_timeval_add PROTO_LIST((struct timeval *t1,struct timeval *t2,
|
||||
struct timeval *sum));
|
||||
int r_timeval_diff PROTO_LIST((struct timeval * t1,
|
||||
struct timeval *t0,
|
||||
struct timeval *diff));
|
||||
int r_timeval_add PROTO_LIST((struct timeval * t1,
|
||||
struct timeval *t2,
|
||||
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));
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,7 +44,6 @@
|
|||
ekr@rtfm.com Tue Dec 22 10:36:02 1998
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _r_types_h
|
||||
#define _r_types_h
|
||||
|
||||
|
@ -55,15 +55,15 @@
|
|||
#ifndef SIZEOF_UNSIGNED_INT
|
||||
typedef unsigned int UINT4;
|
||||
#else
|
||||
# if (SIZEOF_UNSIGNED_INT==4)
|
||||
#if(SIZEOF_UNSIGNED_INT == 4)
|
||||
typedef unsigned int UINT4;
|
||||
# elif (SIZEOF_UNSIGNED_SHORT==4)
|
||||
#elif(SIZEOF_UNSIGNED_SHORT == 4)
|
||||
typedef unsigned short UINT4;
|
||||
# elif (SIZEOF_UNSIGNED_LONG==4)
|
||||
#elif(SIZEOF_UNSIGNED_LONG == 4)
|
||||
typedef unsigned long UINT4;
|
||||
# else
|
||||
# error no type for UINT4
|
||||
# endif
|
||||
#else
|
||||
#error no type for UINT4
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -71,19 +71,19 @@ typedef unsigned long UINT4;
|
|||
#ifndef SIZEOF_UNSIGNED_LONG
|
||||
typedef unsigned long UINT8;
|
||||
#else
|
||||
# if (SIZEOF_UNSIGNED_INT==8)
|
||||
#if(SIZEOF_UNSIGNED_INT == 8)
|
||||
typedef unsigned int UINT8;
|
||||
# elif (SIZEOF_UNSIGNED_SHORT==8)
|
||||
#elif(SIZEOF_UNSIGNED_SHORT == 8)
|
||||
typedef unsigned short UINT8;
|
||||
# elif (SIZEOF_UNSIGNED_LONG==8)
|
||||
#elif(SIZEOF_UNSIGNED_LONG == 8)
|
||||
typedef unsigned long UINT8;
|
||||
# elif (SIZEOF_UNSIGNED_LONG_LONG==8)
|
||||
#elif(SIZEOF_UNSIGNED_LONG_LONG == 8)
|
||||
typedef unsigned long long UINT8;
|
||||
# elif defined (_WIN32) && defined (_MSC_VER)
|
||||
#elif defined(_WIN32) && defined(_MSC_VER)
|
||||
typedef unsigned __int64 UINT8;
|
||||
# else
|
||||
# error no type for UINT8
|
||||
# endif
|
||||
#else
|
||||
#error no type for UINT8
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -92,4 +92,3 @@ typedef unsigned char UCHAR;
|
|||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,11 +44,9 @@
|
|||
ekr@rtfm.com Sun Jan 17 17:56:35 1999
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _assoc_h
|
||||
#define _assoc_h
|
||||
|
||||
typedef struct assoc_ assoc;
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,47 +44,34 @@
|
|||
ekr@rtfm.com Wed Jan 6 17:08:58 1999
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include "r_common.h"
|
||||
#include "debug.h"
|
||||
|
||||
int debug(int class,char *format,...)
|
||||
{
|
||||
va_list ap;
|
||||
int debug(int class, char *format, ...) {
|
||||
va_list ap;
|
||||
|
||||
va_start(ap,format);
|
||||
vfprintf(stderr,format,ap);
|
||||
fprintf(stderr,"\n");
|
||||
va_end(ap);
|
||||
return(0);
|
||||
va_start(ap, format);
|
||||
vfprintf(stderr, format, ap);
|
||||
fprintf(stderr, "\n");
|
||||
va_end(ap);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int xdump(char *name, UCHAR *data, int len) {
|
||||
int i;
|
||||
|
||||
if(name) {
|
||||
printf("%s[%d]=\n", name, len);
|
||||
}
|
||||
|
||||
int
|
||||
xdump (char *name, UCHAR *data, int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(name){
|
||||
printf("%s[%d]=\n",name,len);
|
||||
}
|
||||
for(i=0;i<len;i++){
|
||||
|
||||
if((len>8) && i && !(i%12)){
|
||||
printf("\n");
|
||||
}
|
||||
printf("%.2x ",data[i]&255);
|
||||
}
|
||||
if(i%12)
|
||||
for(i = 0; i < len; i++) {
|
||||
if((len > 8) && i && !(i % 12)) {
|
||||
printf("\n");
|
||||
return(0);
|
||||
}
|
||||
printf("%.2x ", data[i] & 255);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if(i % 12)
|
||||
printf("\n");
|
||||
return (0);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,7 +44,6 @@
|
|||
ekr@rtfm.com Wed Jan 6 17:13:00 1999
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _debug_h
|
||||
#define _debug_h
|
||||
|
||||
|
@ -53,9 +53,7 @@
|
|||
#define DBG(a)
|
||||
#endif
|
||||
|
||||
int debug(int class,char *format,...);
|
||||
int xdump PROTO_LIST((char *name,UCHAR *data,
|
||||
int len));
|
||||
int debug(int class, char *format, ...);
|
||||
int xdump PROTO_LIST((char *name, UCHAR *data, int len));
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
The major problem with this code is it's not resizable, though it
|
||||
could be made so.
|
||||
|
||||
|
||||
|
||||
Copyright (C) 1999-2000 RTFM, Inc.
|
||||
All Rights Reserved
|
||||
|
@ -29,7 +29,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -46,7 +46,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -54,360 +55,331 @@
|
|||
ekr@rtfm.com Sun Jan 17 17:57:15 1999
|
||||
*/
|
||||
|
||||
|
||||
#include <r_common.h>
|
||||
#include "r_assoc.h"
|
||||
|
||||
typedef struct r_assoc_el_ {
|
||||
char *key;
|
||||
int key_len;
|
||||
void *data;
|
||||
struct r_assoc_el_ *prev;
|
||||
struct r_assoc_el_ *next;
|
||||
int (*copy) PROTO_LIST((void **new,void *old));
|
||||
int (*destroy) PROTO_LIST((void *ptr));
|
||||
char *key;
|
||||
int key_len;
|
||||
void *data;
|
||||
struct r_assoc_el_ *prev;
|
||||
struct r_assoc_el_ *next;
|
||||
int(*copy) PROTO_LIST((void **new, void *old));
|
||||
int(*destroy) PROTO_LIST((void *ptr));
|
||||
} r_assoc_el;
|
||||
|
||||
|
||||
struct r_assoc_ {
|
||||
int size;
|
||||
int bits;
|
||||
r_assoc_el **chains;
|
||||
int size;
|
||||
int bits;
|
||||
r_assoc_el **chains;
|
||||
};
|
||||
|
||||
#define DEFAULT_TABLE_BITS 5
|
||||
|
||||
static int destroy_assoc_chain PROTO_LIST((r_assoc_el *chain));
|
||||
static int r_assoc_fetch_bucket PROTO_LIST((r_assoc *assoc,
|
||||
char *key,int len,r_assoc_el **bucketp));
|
||||
UINT4 hash_compute PROTO_LIST((char *key,int len,int size));
|
||||
static int copy_assoc_chain PROTO_LIST((r_assoc_el **newp,
|
||||
r_assoc_el *old));
|
||||
static int destroy_assoc_chain PROTO_LIST((r_assoc_el * chain));
|
||||
static int r_assoc_fetch_bucket
|
||||
PROTO_LIST((r_assoc * assoc, char *key, int len, r_assoc_el **bucketp));
|
||||
UINT4 hash_compute PROTO_LIST((char *key, int len, int size));
|
||||
static int copy_assoc_chain PROTO_LIST((r_assoc_el * *newp, r_assoc_el *old));
|
||||
|
||||
int
|
||||
r_assoc_create (r_assoc **assocp)
|
||||
{
|
||||
r_assoc *assoc=0;
|
||||
int _status;
|
||||
|
||||
if(!(assoc=(r_assoc *)calloc(sizeof(r_assoc),1)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
assoc->size=(1<<DEFAULT_TABLE_BITS);
|
||||
assoc->bits=DEFAULT_TABLE_BITS;
|
||||
|
||||
if(!(assoc->chains=(r_assoc_el **)calloc(sizeof(r_assoc_el *),
|
||||
assoc->size)))
|
||||
int r_assoc_create(r_assoc **assocp) {
|
||||
r_assoc *assoc = 0;
|
||||
int _status;
|
||||
|
||||
if(!(assoc = (r_assoc *)calloc(sizeof(r_assoc), 1)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
assoc->size = (1 << DEFAULT_TABLE_BITS);
|
||||
assoc->bits = DEFAULT_TABLE_BITS;
|
||||
|
||||
if(!(assoc->chains =
|
||||
(r_assoc_el **)calloc(sizeof(r_assoc_el *), assoc->size)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
|
||||
*assocp = assoc;
|
||||
|
||||
_status = 0;
|
||||
abort:
|
||||
if(_status) {
|
||||
r_assoc_destroy(&assoc);
|
||||
}
|
||||
return (_status);
|
||||
}
|
||||
|
||||
int r_assoc_destroy(r_assoc **assocp) {
|
||||
r_assoc *assoc;
|
||||
int i;
|
||||
|
||||
if(!assocp || !*assocp)
|
||||
return (0);
|
||||
|
||||
assoc = *assocp;
|
||||
for(i = 0; i < assoc->size; i++)
|
||||
destroy_assoc_chain(assoc->chains[i]);
|
||||
|
||||
free(assoc->chains);
|
||||
free(assoc);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int destroy_assoc_chain(r_assoc_el *chain) {
|
||||
r_assoc_el *nxt;
|
||||
|
||||
while(chain) {
|
||||
nxt = chain->next;
|
||||
|
||||
if(chain->destroy)
|
||||
chain->destroy(chain->data);
|
||||
|
||||
free(chain->key);
|
||||
|
||||
free(chain);
|
||||
chain = nxt;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int copy_assoc_chain(r_assoc_el **newp, r_assoc_el *old) {
|
||||
r_assoc_el *new = 0, *ptr, *tmp;
|
||||
int r, _status;
|
||||
|
||||
if(!old) {
|
||||
*newp = 0;
|
||||
return (0);
|
||||
}
|
||||
for(; old; old = old->next) {
|
||||
if(!(tmp = (r_assoc_el *)calloc(sizeof(r_assoc_el), 1)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
|
||||
*assocp=assoc;
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
if(_status){
|
||||
r_assoc_destroy(&assoc);
|
||||
if(!new) {
|
||||
new = tmp;
|
||||
ptr = new;
|
||||
} else {
|
||||
ptr->next = tmp;
|
||||
tmp->prev = ptr;
|
||||
ptr = tmp;
|
||||
}
|
||||
return(_status);
|
||||
|
||||
ptr->destroy = old->destroy;
|
||||
ptr->copy = old->copy;
|
||||
|
||||
if(old->copy) {
|
||||
if((r = old->copy(&ptr->data, old->data)))
|
||||
ABORT(r);
|
||||
} else
|
||||
ptr->data = old->data;
|
||||
|
||||
if(!(ptr->key = (char *)malloc(old->key_len)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
memcpy(ptr->key, old->key, ptr->key_len = old->key_len);
|
||||
}
|
||||
|
||||
int
|
||||
r_assoc_destroy (r_assoc **assocp)
|
||||
{
|
||||
r_assoc *assoc;
|
||||
int i;
|
||||
|
||||
if(!assocp || !*assocp)
|
||||
return(0);
|
||||
*newp = new;
|
||||
|
||||
assoc=*assocp;
|
||||
for(i=0;i<assoc->size;i++)
|
||||
destroy_assoc_chain(assoc->chains[i]);
|
||||
_status = 0;
|
||||
abort:
|
||||
if(_status) {
|
||||
destroy_assoc_chain(new);
|
||||
}
|
||||
return (_status);
|
||||
}
|
||||
|
||||
free(assoc->chains);
|
||||
free(assoc);
|
||||
static int r_assoc_fetch_bucket(r_assoc *assoc,
|
||||
char *key,
|
||||
int len,
|
||||
r_assoc_el **bucketp) {
|
||||
UINT4 hash_value;
|
||||
r_assoc_el *bucket;
|
||||
|
||||
return(0);
|
||||
hash_value = hash_compute(key, len, assoc->bits);
|
||||
|
||||
for(bucket = assoc->chains[hash_value]; bucket; bucket = bucket->next) {
|
||||
if(bucket->key_len == len && !memcmp(bucket->key, key, len)) {
|
||||
*bucketp = bucket;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
destroy_assoc_chain (r_assoc_el *chain)
|
||||
{
|
||||
r_assoc_el *nxt;
|
||||
|
||||
while(chain){
|
||||
nxt=chain->next;
|
||||
return (R_NOT_FOUND);
|
||||
}
|
||||
|
||||
if(chain->destroy)
|
||||
chain->destroy(chain->data);
|
||||
int r_assoc_fetch(r_assoc *assoc, char *key, int len, void **datap) {
|
||||
r_assoc_el *bucket;
|
||||
int r;
|
||||
|
||||
free(chain->key);
|
||||
|
||||
free(chain);
|
||||
chain=nxt;
|
||||
}
|
||||
|
||||
return(0);
|
||||
if((r = r_assoc_fetch_bucket(assoc, key, len, &bucket))) {
|
||||
if(r != R_NOT_FOUND)
|
||||
ERETURN(r);
|
||||
return (r);
|
||||
}
|
||||
|
||||
static int
|
||||
copy_assoc_chain (r_assoc_el **newp, r_assoc_el *old)
|
||||
{
|
||||
r_assoc_el *new=0,*ptr,*tmp;
|
||||
int r,_status;
|
||||
*datap = bucket->data;
|
||||
return (0);
|
||||
}
|
||||
|
||||
if(!old) {
|
||||
*newp=0;
|
||||
return(0);
|
||||
}
|
||||
for(;old;old=old->next){
|
||||
if(!(tmp=(r_assoc_el *)calloc(sizeof(r_assoc_el),1)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
|
||||
if(!new){
|
||||
new=tmp;
|
||||
ptr=new;
|
||||
}
|
||||
else{
|
||||
ptr->next=tmp;
|
||||
tmp->prev=ptr;
|
||||
ptr=tmp;
|
||||
}
|
||||
int r_assoc_insert(r_assoc *assoc,
|
||||
char *key,
|
||||
int len,
|
||||
void *data,
|
||||
int(*copy) PROTO_LIST((void **new, void *old)),
|
||||
int(*destroy) PROTO_LIST((void *ptr)),
|
||||
int how) {
|
||||
r_assoc_el *bucket, *new_bucket = 0;
|
||||
int r, _status;
|
||||
|
||||
ptr->destroy=old->destroy;
|
||||
ptr->copy=old->copy;
|
||||
|
||||
if(old->copy){
|
||||
if((r=old->copy(&ptr->data,old->data)))
|
||||
ABORT(r);
|
||||
}
|
||||
else
|
||||
ptr->data=old->data;
|
||||
|
||||
if(!(ptr->key=(char *)malloc(old->key_len)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
memcpy(ptr->key,old->key,ptr->key_len=old->key_len);
|
||||
}
|
||||
|
||||
*newp=new;
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
if(_status){
|
||||
destroy_assoc_chain(new);
|
||||
}
|
||||
return(_status);
|
||||
}
|
||||
|
||||
static int
|
||||
r_assoc_fetch_bucket (r_assoc *assoc, char *key, int len, r_assoc_el **bucketp)
|
||||
{
|
||||
if((r = r_assoc_fetch_bucket(assoc, key, len, &bucket))) {
|
||||
/*Note that we compute the hash value twice*/
|
||||
UINT4 hash_value;
|
||||
r_assoc_el *bucket;
|
||||
|
||||
hash_value=hash_compute(key,len,assoc->bits);
|
||||
|
||||
for(bucket=assoc->chains[hash_value];bucket;bucket=bucket->next){
|
||||
if(bucket->key_len == len && !memcmp(bucket->key,key,len)){
|
||||
*bucketp=bucket;
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
if(r != R_NOT_FOUND)
|
||||
ABORT(r);
|
||||
hash_value = hash_compute(key, len, assoc->bits);
|
||||
|
||||
return(R_NOT_FOUND);
|
||||
}
|
||||
|
||||
int
|
||||
r_assoc_fetch (r_assoc *assoc, char *key, int len, void **datap)
|
||||
{
|
||||
r_assoc_el *bucket;
|
||||
int r;
|
||||
|
||||
if((r=r_assoc_fetch_bucket(assoc,key,len,&bucket))){
|
||||
if(r!=R_NOT_FOUND)
|
||||
ERETURN(r);
|
||||
return(r);
|
||||
}
|
||||
|
||||
*datap=bucket->data;
|
||||
return(0);
|
||||
}
|
||||
|
||||
int r_assoc_insert(
|
||||
r_assoc *assoc,
|
||||
char *key,
|
||||
int len,
|
||||
void *data,
|
||||
int (*copy) PROTO_LIST((void **new,void *old)),
|
||||
int (*destroy) PROTO_LIST((void *ptr)),
|
||||
int how)
|
||||
{
|
||||
r_assoc_el *bucket,*new_bucket=0;
|
||||
int r,_status;
|
||||
|
||||
if((r=r_assoc_fetch_bucket(assoc,key,len,&bucket))){
|
||||
/*Note that we compute the hash value twice*/
|
||||
UINT4 hash_value;
|
||||
|
||||
if(r!=R_NOT_FOUND)
|
||||
ABORT(r);
|
||||
hash_value=hash_compute(key,len,assoc->bits);
|
||||
|
||||
if(!(new_bucket=(r_assoc_el *)calloc(sizeof(r_assoc_el),1)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
if(!(new_bucket->key=(char *)malloc(len)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
memcpy(new_bucket->key,key,len);
|
||||
new_bucket->key_len=len;
|
||||
|
||||
/*Insert at the list head. Is FIFO a good algorithm?*/
|
||||
if(assoc->chains[hash_value])
|
||||
assoc->chains[hash_value]->prev=new_bucket;
|
||||
new_bucket->next=assoc->chains[hash_value];
|
||||
assoc->chains[hash_value]=new_bucket;
|
||||
bucket=new_bucket;
|
||||
}
|
||||
else{
|
||||
if(!(how&R_ASSOC_REPLACE))
|
||||
ABORT(R_ALREADY);
|
||||
|
||||
if(bucket->destroy)
|
||||
bucket->destroy(bucket->data);
|
||||
}
|
||||
|
||||
bucket->data=data;
|
||||
bucket->copy=copy;
|
||||
bucket->destroy=destroy;
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
if(_status && new_bucket){
|
||||
free(new_bucket->key);
|
||||
free(new_bucket);
|
||||
}
|
||||
return(_status);
|
||||
}
|
||||
|
||||
int
|
||||
r_assoc_copy (r_assoc **newp, r_assoc *old)
|
||||
{
|
||||
int r,_status,i;
|
||||
r_assoc *new;
|
||||
|
||||
if(!(new=(r_assoc *)calloc(sizeof(r_assoc),1)))
|
||||
if(!(new_bucket = (r_assoc_el *)calloc(sizeof(r_assoc_el), 1)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
new->size=old->size;
|
||||
new->bits=old->bits;
|
||||
|
||||
if(!(new->chains=(r_assoc_el **)calloc(sizeof(r_assoc_el),old->size)))
|
||||
if(!(new_bucket->key = (char *)malloc(len)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
for(i=0;i<new->size;i++){
|
||||
if((r=copy_assoc_chain(new->chains+i,old->chains[i])))
|
||||
ABORT(R_NO_MEMORY);
|
||||
}
|
||||
*newp=new;
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
if(_status){
|
||||
r_assoc_destroy(&new);
|
||||
}
|
||||
return(_status);
|
||||
memcpy(new_bucket->key, key, len);
|
||||
new_bucket->key_len = len;
|
||||
|
||||
/*Insert at the list head. Is FIFO a good algorithm?*/
|
||||
if(assoc->chains[hash_value])
|
||||
assoc->chains[hash_value]->prev = new_bucket;
|
||||
new_bucket->next = assoc->chains[hash_value];
|
||||
assoc->chains[hash_value] = new_bucket;
|
||||
bucket = new_bucket;
|
||||
} else {
|
||||
if(!(how & R_ASSOC_REPLACE))
|
||||
ABORT(R_ALREADY);
|
||||
|
||||
if(bucket->destroy)
|
||||
bucket->destroy(bucket->data);
|
||||
}
|
||||
|
||||
int
|
||||
r_assoc_init_iter (r_assoc *assoc, r_assoc_iterator *iter)
|
||||
{
|
||||
int i;
|
||||
|
||||
iter->assoc=assoc;
|
||||
iter->prev_chain=-1;
|
||||
iter->prev=0;
|
||||
bucket->data = data;
|
||||
bucket->copy = copy;
|
||||
bucket->destroy = destroy;
|
||||
|
||||
iter->next_chain=assoc->size;
|
||||
iter->next=0;
|
||||
|
||||
for(i=0;i<assoc->size;i++){
|
||||
if(assoc->chains[i]!=0){
|
||||
iter->next_chain=i;
|
||||
iter->next=assoc->chains[i];
|
||||
break;
|
||||
_status = 0;
|
||||
abort:
|
||||
if(_status && new_bucket) {
|
||||
free(new_bucket->key);
|
||||
free(new_bucket);
|
||||
}
|
||||
return (_status);
|
||||
}
|
||||
|
||||
int r_assoc_copy(r_assoc **newp, r_assoc *old) {
|
||||
int r, _status, i;
|
||||
r_assoc *new;
|
||||
|
||||
if(!(new = (r_assoc *)calloc(sizeof(r_assoc), 1)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
new->size = old->size;
|
||||
new->bits = old->bits;
|
||||
|
||||
if(!(new->chains = (r_assoc_el **)calloc(sizeof(r_assoc_el), old->size)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
for(i = 0; i < new->size; i++) {
|
||||
if((r = copy_assoc_chain(new->chains + i, old->chains[i])))
|
||||
ABORT(R_NO_MEMORY);
|
||||
}
|
||||
*newp = new;
|
||||
|
||||
_status = 0;
|
||||
abort:
|
||||
if(_status) {
|
||||
r_assoc_destroy(&new);
|
||||
}
|
||||
return (_status);
|
||||
}
|
||||
|
||||
int r_assoc_init_iter(r_assoc *assoc, r_assoc_iterator *iter) {
|
||||
int i;
|
||||
|
||||
iter->assoc = assoc;
|
||||
iter->prev_chain = -1;
|
||||
iter->prev = 0;
|
||||
|
||||
iter->next_chain = assoc->size;
|
||||
iter->next = 0;
|
||||
|
||||
for(i = 0; i < assoc->size; i++) {
|
||||
if(assoc->chains[i] != 0) {
|
||||
iter->next_chain = i;
|
||||
iter->next = assoc->chains[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int r_assoc_iter(r_assoc_iterator *iter, void **key, int *keyl, void **val) {
|
||||
int i;
|
||||
r_assoc_el *ret;
|
||||
|
||||
if(!iter->next)
|
||||
return (R_EOD);
|
||||
ret = iter->next;
|
||||
|
||||
*key = ret->key;
|
||||
*keyl = ret->key_len;
|
||||
*val = ret->data;
|
||||
|
||||
/* Now increment */
|
||||
iter->prev_chain = iter->next_chain;
|
||||
iter->prev = iter->next;
|
||||
|
||||
/* More on this chain */
|
||||
if(iter->next->next) {
|
||||
iter->next = iter->next->next;
|
||||
} else {
|
||||
iter->next = 0;
|
||||
|
||||
/* FInd the next occupied chain*/
|
||||
for(i = iter->next_chain; i < iter->assoc->size; i++) {
|
||||
if(iter->assoc->chains[i]) {
|
||||
iter->next_chain = i;
|
||||
iter->next = iter->assoc->chains[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
r_assoc_iter (r_assoc_iterator *iter, void **key, int *keyl, void **val)
|
||||
{
|
||||
int i;
|
||||
r_assoc_el *ret;
|
||||
|
||||
if(!iter->next)
|
||||
return(R_EOD);
|
||||
ret=iter->next;
|
||||
|
||||
*key=ret->key;
|
||||
*keyl=ret->key_len;
|
||||
*val=ret->data;
|
||||
|
||||
/* Now increment */
|
||||
iter->prev_chain=iter->next_chain;
|
||||
iter->prev=iter->next;
|
||||
|
||||
/* More on this chain */
|
||||
if(iter->next->next){
|
||||
iter->next=iter->next->next;
|
||||
}
|
||||
else{
|
||||
iter->next=0;
|
||||
|
||||
/* FInd the next occupied chain*/
|
||||
for(i=iter->next_chain;i<iter->assoc->size;i++){
|
||||
if(iter->assoc->chains[i]){
|
||||
iter->next_chain=i;
|
||||
iter->next=iter->assoc->chains[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Delete the last returned value*/
|
||||
int
|
||||
r_assoc_iter_delete (r_assoc_iterator *iter)
|
||||
{
|
||||
/* First unhook it from the list*/
|
||||
if(!iter->prev->prev){
|
||||
/* First element*/
|
||||
iter->assoc->chains[iter->prev_chain]=iter->prev->next;
|
||||
}
|
||||
else{
|
||||
iter->prev->prev->next=iter->prev->next;
|
||||
}
|
||||
|
||||
if(iter->prev->next){
|
||||
iter->prev->next->prev=iter->prev->prev;
|
||||
}
|
||||
|
||||
iter->prev->destroy(iter->prev->data);
|
||||
free(iter->prev->data);
|
||||
free(iter->prev);
|
||||
return(0);
|
||||
int r_assoc_iter_delete(r_assoc_iterator *iter) {
|
||||
/* First unhook it from the list*/
|
||||
if(!iter->prev->prev) {
|
||||
/* First element*/
|
||||
iter->assoc->chains[iter->prev_chain] = iter->prev->next;
|
||||
} else {
|
||||
iter->prev->prev->next = iter->prev->next;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(iter->prev->next) {
|
||||
iter->prev->next->prev = iter->prev->prev;
|
||||
}
|
||||
|
||||
iter->prev->destroy(iter->prev->data);
|
||||
free(iter->prev->data);
|
||||
free(iter->prev);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*This is a hack from AMS. Supposedly, it's pretty good for strings, even
|
||||
though it doesn't take into account all the data*/
|
||||
UINT4
|
||||
hash_compute (char *key, int len, int bits)
|
||||
{
|
||||
UINT4 h=0;
|
||||
UINT4
|
||||
hash_compute(char *key, int len, int bits) {
|
||||
UINT4 h = 0;
|
||||
|
||||
h=key[0] +(key[len-1] * len);
|
||||
h = key[0] + (key[len - 1] * len);
|
||||
|
||||
h &= (1<<bits) - 1;
|
||||
|
||||
return(h);
|
||||
}
|
||||
h &= (1 << bits) - 1;
|
||||
|
||||
return (h);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,95 +44,85 @@
|
|||
ekr@rtfm.com Sun Jan 17 21:09:22 1999
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <r_common.h>
|
||||
#include <r_assoc.h>
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
char test_vector[1024],*v;
|
||||
int rnd,ct,r;
|
||||
r_assoc *assoc,*new_assoc;
|
||||
int main(void) {
|
||||
char test_vector[1024], *v;
|
||||
int rnd, ct, r;
|
||||
r_assoc *assoc, *new_assoc;
|
||||
|
||||
if(r=r_assoc_create(&assoc)){
|
||||
fprintf(stderr,"Couldn't create\n");
|
||||
if(r = r_assoc_create(&assoc)) {
|
||||
fprintf(stderr, "Couldn't create\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
srand(getpid());
|
||||
|
||||
v = test_vector;
|
||||
for(ct = 0; ct < 256; ct++) {
|
||||
v[0] = ct & 255;
|
||||
v[1] = (ct >> 8) & 255;
|
||||
v[2] = (ct >> 16) & 255;
|
||||
v[3] = (ct >> 24) & 255;
|
||||
|
||||
if(r = r_assoc_insert(assoc, v, 4, v, 0, 0, R_ASSOC_REPLACE)) {
|
||||
fprintf(stderr, "Couldn't insert %d\n", ct);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
srand(getpid());
|
||||
v += 4;
|
||||
}
|
||||
|
||||
v=test_vector;
|
||||
for(ct=0;ct<256;ct++){
|
||||
v[0]=ct & 255;
|
||||
v[1]=(ct>>8) & 255;
|
||||
v[2]=(ct>>16) & 255;
|
||||
v[3]=(ct>>24) & 255;
|
||||
fetch_test(assoc);
|
||||
|
||||
|
||||
if(r=r_assoc_insert(assoc,v,4,v,0,0,R_ASSOC_REPLACE)){
|
||||
fprintf(stderr,"Couldn't insert %d\n",ct);
|
||||
exit(1);
|
||||
if(r = r_assoc_copy(&new_assoc, assoc)) {
|
||||
fprintf(stderr, "Couldn't copy\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
r_assoc_destroy(&assoc);
|
||||
|
||||
fetch_test(new_assoc);
|
||||
|
||||
r_assoc_destroy(&new_assoc);
|
||||
|
||||
printf("Tests pass\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int fetch_test(r_assoc *assoc) {
|
||||
int ct;
|
||||
char vec[4], *v;
|
||||
int r, _status, rnd;
|
||||
|
||||
for(ct = 0; ct < 65537; ct++) {
|
||||
rnd = rand();
|
||||
|
||||
rnd &= 0x3ff;
|
||||
|
||||
vec[0] = rnd & 255;
|
||||
vec[1] = (rnd >> 8) & 255;
|
||||
vec[2] = (rnd >> 16) & 255;
|
||||
vec[3] = (rnd >> 24) & 255;
|
||||
|
||||
if(r = r_assoc_fetch(assoc, vec, 4, (void **)&v)) {
|
||||
if(rnd < 256) {
|
||||
fprintf(stderr, "Couldn't fetch\n");
|
||||
exit(1);
|
||||
} else
|
||||
continue;
|
||||
} else {
|
||||
if(rnd > 255) {
|
||||
fprintf(stderr, "Spurious fetch\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
v+=4;
|
||||
}
|
||||
|
||||
fetch_test(assoc);
|
||||
|
||||
if(r=r_assoc_copy(&new_assoc,assoc)){
|
||||
fprintf(stderr,"Couldn't copy\n");
|
||||
if(memcmp(vec, v, 4)) {
|
||||
fprintf(stderr, "Fetch error\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
r_assoc_destroy(&assoc);
|
||||
|
||||
fetch_test(new_assoc);
|
||||
|
||||
r_assoc_destroy(&new_assoc);
|
||||
|
||||
printf("Tests pass\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int
|
||||
fetch_test (r_assoc *assoc)
|
||||
{
|
||||
int ct;
|
||||
char vec[4],*v;
|
||||
int r,_status,rnd;
|
||||
|
||||
for(ct=0;ct<65537;ct++){
|
||||
rnd=rand();
|
||||
|
||||
rnd &= 0x3ff;
|
||||
|
||||
vec[0]=rnd & 255;
|
||||
vec[1]=(rnd>>8) & 255;
|
||||
vec[2]=(rnd>>16) & 255;
|
||||
vec[3]=(rnd>>24) & 255;
|
||||
|
||||
if(r=r_assoc_fetch(assoc,vec,4,(void **)&v)){
|
||||
|
||||
if(rnd<256){
|
||||
fprintf(stderr,"Couldn't fetch\n");
|
||||
exit(1);
|
||||
}
|
||||
else
|
||||
continue;
|
||||
}
|
||||
else{
|
||||
if(rnd>255){
|
||||
fprintf(stderr,"Spurious fetch\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if(memcmp(vec,v,4)){
|
||||
fprintf(stderr,"Fetch error\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
|
|
@ -7,100 +7,90 @@
|
|||
ekr@rtfm.com Wed Oct 3 11:15:23 2001
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <r_common.h>
|
||||
#include "r_bitfield.h"
|
||||
|
||||
int
|
||||
r_bitfield_create (r_bitfield **setp, UINT4 size)
|
||||
{
|
||||
r_bitfield *set=0;
|
||||
int _status;
|
||||
int num_words=size/32+!!(size%32);
|
||||
|
||||
if(!(set=(r_bitfield *)RMALLOC(sizeof(r_bitfield))))
|
||||
ABORT(R_NO_MEMORY);
|
||||
int r_bitfield_create(r_bitfield **setp, UINT4 size) {
|
||||
r_bitfield *set = 0;
|
||||
int _status;
|
||||
int num_words = size / 32 + !!(size % 32);
|
||||
|
||||
if(!(set->data=(UINT4 *)RMALLOC(num_words*4)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
memset(set->data,0,4*num_words);
|
||||
|
||||
set->base=0;
|
||||
set->len=num_words;
|
||||
if(!(set = (r_bitfield *)RMALLOC(sizeof(r_bitfield))))
|
||||
ABORT(R_NO_MEMORY);
|
||||
|
||||
*setp=set;
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
if(_status){
|
||||
r_bitfield_destroy(&set);
|
||||
}
|
||||
return(_status);
|
||||
if(!(set->data = (UINT4 *)RMALLOC(num_words * 4)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
memset(set->data, 0, 4 * num_words);
|
||||
|
||||
set->base = 0;
|
||||
set->len = num_words;
|
||||
|
||||
*setp = set;
|
||||
|
||||
_status = 0;
|
||||
abort:
|
||||
if(_status) {
|
||||
r_bitfield_destroy(&set);
|
||||
}
|
||||
return (_status);
|
||||
}
|
||||
|
||||
int
|
||||
r_bitfield_destroy (r_bitfield **setp)
|
||||
{
|
||||
r_bitfield *set;
|
||||
|
||||
if(!setp || !*setp)
|
||||
return(0);
|
||||
int r_bitfield_destroy(r_bitfield **setp) {
|
||||
r_bitfield *set;
|
||||
|
||||
set=*setp;
|
||||
if(!setp || !*setp)
|
||||
return (0);
|
||||
|
||||
set = *setp;
|
||||
|
||||
RFREE(set->data);
|
||||
RFREE(set);
|
||||
|
||||
*setp = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int r_bitfield_set(r_bitfield *set, int bit) {
|
||||
int word = (bit - set->base) / 32;
|
||||
int bbit = (bit - set->base) % 32;
|
||||
int _status;
|
||||
|
||||
/* Resize? */
|
||||
if(word > set->len) {
|
||||
UINT4 newlen = set->len;
|
||||
UINT4 *tmp;
|
||||
|
||||
while(newlen < word)
|
||||
newlen *= 2;
|
||||
|
||||
if(!(tmp = (UINT4 *)RMALLOC(newlen)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
|
||||
memcpy(tmp, set->data, set->len * 4);
|
||||
memset(tmp + set->len * 4, 0, (newlen - set->len) * 4);
|
||||
|
||||
RFREE(set->data);
|
||||
RFREE(set);
|
||||
|
||||
*setp=0;
|
||||
return(0);
|
||||
set->data = tmp;
|
||||
}
|
||||
|
||||
int
|
||||
r_bitfield_set (r_bitfield *set, int bit)
|
||||
{
|
||||
int word=(bit-set->base)/32;
|
||||
int bbit=(bit-set->base)%32;
|
||||
int _status;
|
||||
set->data[word] |= 1 << bbit;
|
||||
|
||||
/* Resize? */
|
||||
if(word>set->len){
|
||||
UINT4 newlen=set->len;
|
||||
UINT4 *tmp;
|
||||
|
||||
while(newlen<word)
|
||||
newlen*=2;
|
||||
|
||||
if(!(tmp=(UINT4 *)RMALLOC(newlen)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
|
||||
memcpy(tmp,set->data,set->len*4);
|
||||
memset(tmp+set->len*4,0,(newlen-set->len)*4);
|
||||
_status = 0;
|
||||
abort:
|
||||
return (_status);
|
||||
}
|
||||
|
||||
RFREE(set->data);
|
||||
set->data=tmp;
|
||||
}
|
||||
int r_bitfield_isset(r_bitfield *set, int bit) {
|
||||
int word = (bit - set->base) / 32;
|
||||
int bbit = (bit - set->base) % 32;
|
||||
int _status;
|
||||
|
||||
set->data[word]|=1<<bbit;
|
||||
if(bit < set->base)
|
||||
return (0);
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
return(_status);
|
||||
}
|
||||
/* Resize? */
|
||||
if(word > set->len)
|
||||
return (0);
|
||||
|
||||
int
|
||||
r_bitfield_isset (r_bitfield *set, int bit)
|
||||
{
|
||||
int word=(bit-set->base)/32;
|
||||
int bbit=(bit-set->base)%32;
|
||||
int _status;
|
||||
|
||||
if(bit<set->base)
|
||||
return(0);
|
||||
|
||||
/* Resize? */
|
||||
if(word>set->len)
|
||||
return(0);
|
||||
|
||||
return(set->data[word]&(1<<bbit));
|
||||
}
|
||||
return (set->data[word] & (1 << bbit));
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,112 +44,95 @@
|
|||
ekr@rtfm.com Tue Aug 17 15:39:50 1999
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <r_common.h>
|
||||
#include <r_data.h>
|
||||
|
||||
int
|
||||
r_data_create (Data **dp, UCHAR *d, int l)
|
||||
{
|
||||
Data *d_=0;
|
||||
int _status;
|
||||
|
||||
if(!(d_=(Data *)calloc(sizeof(Data),1)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
if(!(d_->data=(UCHAR *)malloc(l)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
int r_data_create(Data **dp, UCHAR *d, int l) {
|
||||
Data *d_ = 0;
|
||||
int _status;
|
||||
|
||||
memcpy(d_->data,d,l);
|
||||
d_->len=l;
|
||||
if(!(d_ = (Data *)calloc(sizeof(Data), 1)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
if(!(d_->data = (UCHAR *)malloc(l)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
|
||||
*dp=d_;
|
||||
memcpy(d_->data, d, l);
|
||||
d_->len = l;
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
if(_status)
|
||||
r_data_destroy(&d_);
|
||||
*dp = d_;
|
||||
|
||||
return(_status);
|
||||
}
|
||||
_status = 0;
|
||||
abort:
|
||||
if(_status)
|
||||
r_data_destroy(&d_);
|
||||
|
||||
int
|
||||
r_data_alloc (Data **dp, int l)
|
||||
{
|
||||
Data *d_=0;
|
||||
int _status;
|
||||
|
||||
if(!(d_=(Data *)calloc(sizeof(Data),1)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
if(!(d_->data=(UCHAR *)calloc(l,1)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
return (_status);
|
||||
}
|
||||
|
||||
d_->len=l;
|
||||
|
||||
*dp=d_;
|
||||
_status=0;
|
||||
abort:
|
||||
if(_status)
|
||||
r_data_destroy(&d_);
|
||||
int r_data_alloc(Data **dp, int l) {
|
||||
Data *d_ = 0;
|
||||
int _status;
|
||||
|
||||
return(_status);
|
||||
}
|
||||
if(!(d_ = (Data *)calloc(sizeof(Data), 1)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
if(!(d_->data = (UCHAR *)calloc(l, 1)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
|
||||
int
|
||||
r_data_make (Data *dp, UCHAR *d, int l)
|
||||
{
|
||||
if(!(dp->data=(UCHAR *)malloc(l)))
|
||||
ERETURN(R_NO_MEMORY);
|
||||
d_->len = l;
|
||||
|
||||
memcpy(dp->data,d,l);
|
||||
dp->len=l;
|
||||
*dp = d_;
|
||||
_status = 0;
|
||||
abort:
|
||||
if(_status)
|
||||
r_data_destroy(&d_);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
r_data_destroy (Data **dp)
|
||||
{
|
||||
if(!dp || !*dp)
|
||||
return(0);
|
||||
return (_status);
|
||||
}
|
||||
|
||||
if((*dp)->data)
|
||||
free((*dp)->data);
|
||||
int r_data_make(Data *dp, UCHAR *d, int l) {
|
||||
if(!(dp->data = (UCHAR *)malloc(l)))
|
||||
ERETURN(R_NO_MEMORY);
|
||||
|
||||
free(*dp);
|
||||
*dp=0;
|
||||
memcpy(dp->data, d, l);
|
||||
dp->len = l;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
r_data_copy (Data *dst, Data *src)
|
||||
{
|
||||
if(!(dst->data=(UCHAR *)malloc(src->len)))
|
||||
ERETURN(R_NO_MEMORY);
|
||||
memcpy(dst->data,src->data,dst->len=src->len);
|
||||
return(0);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
r_data_zfree (Data *d)
|
||||
{
|
||||
if(!d)
|
||||
return(0);
|
||||
if(!d->data)
|
||||
return(0);
|
||||
memset(d->data,0,d->len);
|
||||
free(d->data);
|
||||
return(0);
|
||||
}
|
||||
int r_data_destroy(Data **dp) {
|
||||
if(!dp || !*dp)
|
||||
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));
|
||||
}
|
||||
|
||||
if((*dp)->data)
|
||||
free((*dp)->data);
|
||||
|
||||
free(*dp);
|
||||
*dp = 0;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int r_data_copy(Data *dst, Data *src) {
|
||||
if(!(dst->data = (UCHAR *)malloc(src->len)))
|
||||
ERETURN(R_NO_MEMORY);
|
||||
memcpy(dst->data, src->data, dst->len = src->len);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int r_data_zfree(Data *d) {
|
||||
if(!d)
|
||||
return (0);
|
||||
if(!d->data)
|
||||
return (0);
|
||||
memset(d->data, 0, d->len);
|
||||
free(d->data);
|
||||
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));
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,10 +44,7 @@
|
|||
ekr@rtfm.com Fri Feb 4 08:58:48 2000
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _r_data_h
|
||||
#define _r_data_h
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,18 +44,15 @@
|
|||
ekr@rtfm.com Tue Feb 16 16:37:05 1999
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include "r_common.h"
|
||||
#include "r_errors.h"
|
||||
|
||||
int verr_exit(char *fmt,...)
|
||||
{
|
||||
va_list ap;
|
||||
int verr_exit(char *fmt, ...) {
|
||||
va_list ap;
|
||||
|
||||
va_start(ap,fmt);
|
||||
vfprintf(stderr,fmt,ap);
|
||||
exit(1);
|
||||
}
|
||||
va_start(ap, fmt);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
exit(1);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,188 +44,171 @@
|
|||
ekr@rtfm.com Tue Jan 19 08:36:39 1999
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <r_common.h>
|
||||
#include "r_list.h"
|
||||
|
||||
typedef struct r_list_el_ {
|
||||
void *data;
|
||||
struct r_list_el_ *next;
|
||||
struct r_list_el_ *prev;
|
||||
int (*copy) PROTO_LIST((void **new,void *old));
|
||||
int (*destroy) PROTO_LIST((void **ptr));
|
||||
void *data;
|
||||
struct r_list_el_ *next;
|
||||
struct r_list_el_ *prev;
|
||||
int(*copy) PROTO_LIST((void **new, void *old));
|
||||
int(*destroy) PROTO_LIST((void **ptr));
|
||||
} r_list_el;
|
||||
|
||||
struct r_list_ {
|
||||
struct r_list_el_ *first;
|
||||
struct r_list_el_ *last;
|
||||
struct r_list_el_ *first;
|
||||
struct r_list_el_ *last;
|
||||
};
|
||||
|
||||
int
|
||||
r_list_create (r_list **listp)
|
||||
{
|
||||
r_list *list=0;
|
||||
int _status;
|
||||
int r_list_create(r_list **listp) {
|
||||
r_list *list = 0;
|
||||
int _status;
|
||||
|
||||
if(!(list=(r_list *)calloc(sizeof(r_list),1)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
if(!(list = (r_list *)calloc(sizeof(r_list), 1)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
|
||||
list->first=0;
|
||||
list->last=0;
|
||||
*listp=list;
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
return(_status);
|
||||
}
|
||||
list->first = 0;
|
||||
list->last = 0;
|
||||
*listp = list;
|
||||
|
||||
int
|
||||
r_list_destroy (r_list **listp)
|
||||
{
|
||||
r_list *list;
|
||||
r_list_el *el;
|
||||
|
||||
if(!listp || !*listp)
|
||||
return(0);
|
||||
list=*listp;
|
||||
_status = 0;
|
||||
abort:
|
||||
return (_status);
|
||||
}
|
||||
|
||||
el=list->first;
|
||||
|
||||
while(el){
|
||||
r_list_el *el_t;
|
||||
|
||||
if(el->destroy && el->data)
|
||||
el->destroy(&el->data);
|
||||
el_t=el;
|
||||
el=el->next;
|
||||
free(el_t);
|
||||
}
|
||||
|
||||
free(list);
|
||||
*listp=0;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
r_list_copy (r_list **outp, r_list *in)
|
||||
{
|
||||
r_list *out=0;
|
||||
r_list_el *el,*el2,*last=0;
|
||||
int r, _status;
|
||||
|
||||
if(r=r_list_create(&out))
|
||||
ABORT(r);
|
||||
|
||||
for(el=in->first;in;el=el->next){
|
||||
if(!(el2=(r_list_el *)calloc(sizeof(r_list_el),1)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
|
||||
if(el->copy && el->data){
|
||||
if(r=el->copy(&el2->data,el->data))
|
||||
ABORT(r);
|
||||
}
|
||||
|
||||
el2->copy=el->copy;
|
||||
el2->destroy=el->destroy;
|
||||
|
||||
if(!(out->first))
|
||||
out->first=el2;
|
||||
|
||||
el2->prev=last;
|
||||
last->next=el2;
|
||||
last=el2;
|
||||
}
|
||||
|
||||
out->last=last;
|
||||
|
||||
*outp=out;
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
if(_status)
|
||||
r_list_destroy(&out);
|
||||
return(_status);
|
||||
}
|
||||
|
||||
int r_list_insert(list,value,copy,destroy)
|
||||
int r_list_destroy(r_list **listp) {
|
||||
r_list *list;
|
||||
void *value;
|
||||
int (*copy) PROTO_LIST((void **out, void *in));
|
||||
int (*destroy) PROTO_LIST((void **val));
|
||||
{
|
||||
r_list_el *el=0;
|
||||
int _status;
|
||||
|
||||
if(!(el=(r_list_el *)calloc(sizeof(r_list_el),1)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
el->data=value;
|
||||
el->copy=copy;
|
||||
el->destroy=destroy;
|
||||
r_list_el *el;
|
||||
|
||||
el->prev=0;
|
||||
el->next=list->first;
|
||||
if(list->first){
|
||||
list->first->prev=el;
|
||||
if(!listp || !*listp)
|
||||
return (0);
|
||||
list = *listp;
|
||||
|
||||
el = list->first;
|
||||
|
||||
while(el) {
|
||||
r_list_el *el_t;
|
||||
|
||||
if(el->destroy && el->data)
|
||||
el->destroy(&el->data);
|
||||
el_t = el;
|
||||
el = el->next;
|
||||
free(el_t);
|
||||
}
|
||||
|
||||
free(list);
|
||||
*listp = 0;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int r_list_copy(r_list **outp, r_list *in) {
|
||||
r_list *out = 0;
|
||||
r_list_el *el, *el2, *last = 0;
|
||||
int r, _status;
|
||||
|
||||
if(r = r_list_create(&out))
|
||||
ABORT(r);
|
||||
|
||||
for(el = in->first; in; el = el->next) {
|
||||
if(!(el2 = (r_list_el *)calloc(sizeof(r_list_el), 1)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
|
||||
if(el->copy && el->data) {
|
||||
if(r = el->copy(&el2->data, el->data))
|
||||
ABORT(r);
|
||||
}
|
||||
list->first=el;
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
return(_status);
|
||||
el2->copy = el->copy;
|
||||
el2->destroy = el->destroy;
|
||||
|
||||
if(!(out->first))
|
||||
out->first = el2;
|
||||
|
||||
el2->prev = last;
|
||||
last->next = el2;
|
||||
last = el2;
|
||||
}
|
||||
|
||||
int r_list_append(list,value,copy,destroy)
|
||||
r_list *list;
|
||||
void *value;
|
||||
int (*copy) PROTO_LIST((void **out, void *in));
|
||||
int (*destroy) PROTO_LIST((void **val));
|
||||
{
|
||||
r_list_el *el=0;
|
||||
int _status;
|
||||
|
||||
if(!(el=(r_list_el *)calloc(sizeof(r_list_el),1)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
el->data=value;
|
||||
el->copy=copy;
|
||||
el->destroy=destroy;
|
||||
out->last = last;
|
||||
|
||||
el->prev=list->last;
|
||||
el->next=0;
|
||||
|
||||
if(list->last) list->last->next=el;
|
||||
else list->first=el;
|
||||
|
||||
list->last=el;
|
||||
*outp = out;
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
return(_status);
|
||||
_status = 0;
|
||||
abort:
|
||||
if(_status)
|
||||
r_list_destroy(&out);
|
||||
return (_status);
|
||||
}
|
||||
|
||||
int r_list_insert(list, value, copy, destroy) r_list *list;
|
||||
void *value;
|
||||
int(*copy) PROTO_LIST((void **out, void *in));
|
||||
int(*destroy) PROTO_LIST((void **val));
|
||||
{
|
||||
r_list_el *el = 0;
|
||||
int _status;
|
||||
|
||||
if(!(el = (r_list_el *)calloc(sizeof(r_list_el), 1)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
el->data = value;
|
||||
el->copy = copy;
|
||||
el->destroy = destroy;
|
||||
|
||||
el->prev = 0;
|
||||
el->next = list->first;
|
||||
if(list->first) {
|
||||
list->first->prev = el;
|
||||
}
|
||||
list->first = el;
|
||||
|
||||
int
|
||||
r_list_init_iter (r_list *list, r_list_iterator *iter)
|
||||
{
|
||||
iter->list=list;
|
||||
iter->ptr=list->first;
|
||||
_status = 0;
|
||||
abort:
|
||||
return (_status);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
int r_list_append(list, value, copy, destroy) r_list *list;
|
||||
void *value;
|
||||
int(*copy) PROTO_LIST((void **out, void *in));
|
||||
int(*destroy) PROTO_LIST((void **val));
|
||||
{
|
||||
r_list_el *el = 0;
|
||||
int _status;
|
||||
|
||||
int
|
||||
r_list_iter (r_list_iterator *iter, void **val)
|
||||
{
|
||||
if(!iter->ptr)
|
||||
return(R_EOD);
|
||||
if(!(el = (r_list_el *)calloc(sizeof(r_list_el), 1)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
el->data = value;
|
||||
el->copy = copy;
|
||||
el->destroy = destroy;
|
||||
|
||||
*val=iter->ptr->data;
|
||||
iter->ptr=iter->ptr->next;
|
||||
|
||||
return(0);
|
||||
}
|
||||
el->prev = list->last;
|
||||
el->next = 0;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if(list->last)
|
||||
list->last->next = el;
|
||||
else
|
||||
list->first = el;
|
||||
|
||||
list->last = el;
|
||||
|
||||
_status = 0;
|
||||
abort:
|
||||
return (_status);
|
||||
}
|
||||
|
||||
int r_list_init_iter(r_list *list, r_list_iterator *iter) {
|
||||
iter->list = list;
|
||||
iter->ptr = list->first;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int r_list_iter(r_list_iterator *iter, void **val) {
|
||||
if(!iter->ptr)
|
||||
return (R_EOD);
|
||||
|
||||
*val = iter->ptr->data;
|
||||
iter->ptr = iter->ptr->next;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,24 +44,19 @@
|
|||
ekr@rtfm.com Sun Oct 1 11:18:49 2000
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "r_common.h"
|
||||
#include "r_common.h"
|
||||
|
||||
#ifndef HAVE_STRDUP
|
||||
|
||||
char *
|
||||
strdup (char *str)
|
||||
{
|
||||
int len=strlen(str);
|
||||
char *n;
|
||||
|
||||
if(!(n=(char *)malloc(len+1)))
|
||||
return(0);
|
||||
char *strdup(char *str) {
|
||||
int len = strlen(str);
|
||||
char *n;
|
||||
|
||||
memcpy(n,str,len+1);
|
||||
if(!(n = (char *)malloc(len + 1)))
|
||||
return (0);
|
||||
|
||||
return(n);
|
||||
}
|
||||
#endif
|
||||
|
||||
memcpy(n, str, len + 1);
|
||||
|
||||
return (n);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,8 +44,6 @@
|
|||
ekr@rtfm.com Thu Mar 4 08:43:46 1999
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <r_common.h>
|
||||
#include <r_time.h>
|
||||
|
||||
|
@ -52,103 +51,97 @@
|
|||
|
||||
#include <windows.h>
|
||||
|
||||
int gettimeofday(struct timeval *tv, struct timezone *tzp)
|
||||
{
|
||||
/* JAN1_1970_OFFSET is the number of 100-nanoseconds ticks
|
||||
between midnight jan 1, 1970 and jan 1, 1601.
|
||||
*/
|
||||
int gettimeofday(struct timeval *tv, struct timezone *tzp) {
|
||||
/* JAN1_1970_OFFSET is the number of 100-nanoseconds ticks
|
||||
between midnight jan 1, 1970 and jan 1, 1601.
|
||||
*/
|
||||
|
||||
const ULARGE_INTEGER JAN1_1970_OFFSET = {0xd53e8000, 0x019db1de};
|
||||
ULARGE_INTEGER currentTimeSinceJan_1_1970;
|
||||
FILETIME currentTime;
|
||||
const ULARGE_INTEGER JAN1_1970_OFFSET = {0xd53e8000, 0x019db1de};
|
||||
ULARGE_INTEGER currentTimeSinceJan_1_1970;
|
||||
FILETIME currentTime;
|
||||
|
||||
GetSystemTimeAsFileTime( ¤tTime );
|
||||
currentTimeSinceJan_1_1970.LowPart = currentTime.dwLowDateTime;
|
||||
currentTimeSinceJan_1_1970.HighPart = currentTime.dwHighDateTime;
|
||||
currentTimeSinceJan_1_1970.QuadPart -= JAN1_1970_OFFSET.QuadPart;
|
||||
GetSystemTimeAsFileTime(¤tTime);
|
||||
currentTimeSinceJan_1_1970.LowPart = currentTime.dwLowDateTime;
|
||||
currentTimeSinceJan_1_1970.HighPart = currentTime.dwHighDateTime;
|
||||
currentTimeSinceJan_1_1970.QuadPart -= JAN1_1970_OFFSET.QuadPart;
|
||||
|
||||
/* At this point, currentTimeSinceJan_1_1970 contains the
|
||||
number of 100-nanosecond 'ticks' since midnight, Jan. 1,
|
||||
1970. This is equivalent to 10 * the number of microseconds
|
||||
elapsed since this time. The BSD man pages for gettimeofday()
|
||||
suggest that we should return the whole number of seconds in
|
||||
the tv_sec field, and the fractional number of seconds in units
|
||||
of microseconds in the tv_usec field.
|
||||
/* At this point, currentTimeSinceJan_1_1970 contains the
|
||||
number of 100-nanosecond 'ticks' since midnight, Jan. 1,
|
||||
1970. This is equivalent to 10 * the number of microseconds
|
||||
elapsed since this time. The BSD man pages for gettimeofday()
|
||||
suggest that we should return the whole number of seconds in
|
||||
the tv_sec field, and the fractional number of seconds in units
|
||||
of microseconds in the tv_usec field.
|
||||
|
||||
sec = time / 10000000, usec = (time % 10000000) / 10;
|
||||
*/
|
||||
sec = time / 10000000, usec = (time % 10000000) / 10;
|
||||
*/
|
||||
|
||||
tv->tv_sec = currentTimeSinceJan_1_1970.QuadPart / 10000000;
|
||||
tv->tv_usec = (currentTimeSinceJan_1_1970.QuadPart % 10000000) / 10;
|
||||
return 0;
|
||||
tv->tv_sec = currentTimeSinceJan_1_1970.QuadPart / 10000000;
|
||||
tv->tv_usec = (currentTimeSinceJan_1_1970.QuadPart % 10000000) / 10;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
/*Note that t1 must be > t0 */
|
||||
int
|
||||
r_timeval_diff (struct timeval *t1, struct timeval *t0, struct timeval *diff)
|
||||
{
|
||||
long d;
|
||||
int r_timeval_diff(struct timeval *t1,
|
||||
struct timeval *t0,
|
||||
struct timeval *diff) {
|
||||
long d;
|
||||
|
||||
if(t0->tv_sec > t1->tv_sec)
|
||||
ERETURN(R_BAD_ARGS);
|
||||
if(t0->tv_sec > t1->tv_sec)
|
||||
ERETURN(R_BAD_ARGS);
|
||||
|
||||
/*Easy case*/
|
||||
if(t0->tv_usec <= t1->tv_usec){
|
||||
diff->tv_sec=t1->tv_sec - t0->tv_sec;
|
||||
diff->tv_usec=t1->tv_usec - t0->tv_usec;
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*Hard case*/
|
||||
d=t0->tv_usec - t1->tv_usec;
|
||||
if(t1->tv_sec < (t0->tv_sec + 1))
|
||||
ERETURN(R_BAD_ARGS);
|
||||
diff->tv_sec=t1->tv_sec - (t0->tv_sec + 1);
|
||||
diff->tv_usec=1000000 - d;
|
||||
|
||||
return(0);
|
||||
/*Easy case*/
|
||||
if(t0->tv_usec <= t1->tv_usec) {
|
||||
diff->tv_sec = t1->tv_sec - t0->tv_sec;
|
||||
diff->tv_usec = t1->tv_usec - t0->tv_usec;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
r_timeval_add (struct timeval *t1, struct timeval *t2, struct timeval *sum)
|
||||
{
|
||||
long tv_sec,tv_usec,d;
|
||||
/*Hard case*/
|
||||
d = t0->tv_usec - t1->tv_usec;
|
||||
if(t1->tv_sec < (t0->tv_sec + 1))
|
||||
ERETURN(R_BAD_ARGS);
|
||||
diff->tv_sec = t1->tv_sec - (t0->tv_sec + 1);
|
||||
diff->tv_usec = 1000000 - d;
|
||||
|
||||
tv_sec=t1->tv_sec + t2->tv_sec;
|
||||
return (0);
|
||||
}
|
||||
|
||||
d=t1->tv_usec + t2->tv_usec;
|
||||
if(d>1000000){
|
||||
tv_sec++;
|
||||
tv_usec=d-1000000;
|
||||
}
|
||||
else{
|
||||
tv_usec=d;
|
||||
}
|
||||
int r_timeval_add(struct timeval *t1, struct timeval *t2, struct timeval *sum) {
|
||||
long tv_sec, tv_usec, d;
|
||||
|
||||
sum->tv_sec=tv_sec;
|
||||
sum->tv_usec=tv_usec;
|
||||
|
||||
return(0);
|
||||
tv_sec = t1->tv_sec + t2->tv_sec;
|
||||
|
||||
d = t1->tv_usec + t2->tv_usec;
|
||||
if(d > 1000000) {
|
||||
tv_sec++;
|
||||
tv_usec = d - 1000000;
|
||||
} else {
|
||||
tv_usec = d;
|
||||
}
|
||||
|
||||
UINT8
|
||||
r_timeval2int (struct timeval *tv)
|
||||
{
|
||||
UINT8 r=0;
|
||||
|
||||
r=(tv->tv_sec);
|
||||
r*=1000000;
|
||||
r+=tv->tv_usec;
|
||||
|
||||
return r;
|
||||
}
|
||||
sum->tv_sec = tv_sec;
|
||||
sum->tv_usec = tv_usec;
|
||||
|
||||
UINT8
|
||||
r_gettimeint (void)
|
||||
{
|
||||
struct timeval tv;
|
||||
return (0);
|
||||
}
|
||||
|
||||
gettimeofday(&tv,0);
|
||||
UINT8
|
||||
r_timeval2int(struct timeval *tv) {
|
||||
UINT8 r = 0;
|
||||
|
||||
return r_timeval2int(&tv);
|
||||
}
|
||||
r = (tv->tv_sec);
|
||||
r *= 1000000;
|
||||
r += tv->tv_usec;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
UINT8
|
||||
r_gettimeint(void) {
|
||||
struct timeval tv;
|
||||
|
||||
gettimeofday(&tv, 0);
|
||||
|
||||
return r_timeval2int(&tv);
|
||||
}
|
||||
|
|
|
@ -7,146 +7,125 @@
|
|||
ekr@rtfm.com Tue Feb 23 15:08:03 1999
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <r_common.h>
|
||||
#include <r_thread.h>
|
||||
#include <pthread.h>
|
||||
|
||||
static int thread_count=0;
|
||||
static int thread_count = 0;
|
||||
|
||||
typedef struct {
|
||||
void (*func) PROTO_LIST((void *));
|
||||
void *arg;
|
||||
void(*func) PROTO_LIST((void *));
|
||||
void *arg;
|
||||
} helper;
|
||||
|
||||
|
||||
static void *r_thread_real_create PROTO_LIST((void *arg));
|
||||
|
||||
static void *
|
||||
r_thread_real_create (void *arg)
|
||||
{
|
||||
helper *h;
|
||||
static void *r_thread_real_create(void *arg) {
|
||||
helper *h;
|
||||
|
||||
h=(helper *)arg;
|
||||
h = (helper *)arg;
|
||||
|
||||
thread_count++;
|
||||
thread_count++;
|
||||
|
||||
h->func(h->arg);
|
||||
h->func(h->arg);
|
||||
|
||||
thread_count--;
|
||||
free(h);
|
||||
return(0);
|
||||
}
|
||||
|
||||
int r_thread_fork(func,arg,id)
|
||||
void (*func) PROTO_LIST((void *));
|
||||
void *arg;
|
||||
r_thread *id;
|
||||
{
|
||||
pthread_t thread;
|
||||
helper *h;
|
||||
int r,_status;
|
||||
thread_count--;
|
||||
free(h);
|
||||
return (0);
|
||||
}
|
||||
|
||||
h=(helper *)malloc(sizeof(helper));
|
||||
|
||||
h->func=func;
|
||||
h->arg=arg;
|
||||
|
||||
if(r=pthread_create(&thread,0,r_thread_real_create,(void *)h))
|
||||
ABORT(R_INTERNAL);
|
||||
int r_thread_fork(func, arg, id) void(*func) PROTO_LIST((void *));
|
||||
void *arg;
|
||||
r_thread *id;
|
||||
{
|
||||
pthread_t thread;
|
||||
helper *h;
|
||||
int r, _status;
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
return(_status);
|
||||
}
|
||||
h = (helper *)malloc(sizeof(helper));
|
||||
|
||||
int
|
||||
r_thread_yield (void)
|
||||
{
|
||||
h->func = func;
|
||||
h->arg = arg;
|
||||
|
||||
if(r = pthread_create(&thread, 0, r_thread_real_create, (void *)h))
|
||||
ABORT(R_INTERNAL);
|
||||
|
||||
_status = 0;
|
||||
abort:
|
||||
return (_status);
|
||||
}
|
||||
|
||||
int r_thread_yield(void) {
|
||||
pthread_yield();
|
||||
}
|
||||
|
||||
int r_thread_exit(void) {
|
||||
thread_count--;
|
||||
pthread_exit(0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int r_thread_wait_last(void) {
|
||||
do {
|
||||
pthread_yield();
|
||||
usleep(10000);
|
||||
DBG((0, "%d threads left", thread_count));
|
||||
} while(thread_count);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int r_rwlock_create(r_rwlock **lockp) {
|
||||
pthread_rwlock_t *lock;
|
||||
int r;
|
||||
|
||||
if(!(lock = (pthread_rwlock_t *)malloc(sizeof(pthread_rwlock_t))))
|
||||
ERETURN(R_NO_MEMORY);
|
||||
|
||||
if(r = pthread_rwlock_init(lock, 0))
|
||||
ERETURN(R_INTERNAL);
|
||||
|
||||
*lockp = (void *)lock;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int r_rwlock_destroy(r_rwlock **lock) {
|
||||
pthread_rwlock_t *plock;
|
||||
|
||||
if(!lock || !*lock)
|
||||
return (0);
|
||||
|
||||
plock = (pthread_rwlock_t *)(*lock);
|
||||
|
||||
pthread_rwlock_destroy(plock);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int r_rwlock_lock(r_rwlock *lock, int action) {
|
||||
pthread_rwlock_t *plock;
|
||||
int r, _status;
|
||||
|
||||
plock = (pthread_rwlock_t *)lock;
|
||||
|
||||
switch(action) {
|
||||
case R_RWLOCK_UNLOCK:
|
||||
if(r = pthread_rwlock_unlock(plock))
|
||||
ABORT(R_INTERNAL);
|
||||
break;
|
||||
case R_RWLOCK_RLOCK:
|
||||
if(r = pthread_rwlock_rdlock(plock))
|
||||
ABORT(R_INTERNAL);
|
||||
break;
|
||||
case R_RWLOCK_WLOCK:
|
||||
if(r = pthread_rwlock_wrlock(plock))
|
||||
ABORT(R_INTERNAL);
|
||||
break;
|
||||
default:
|
||||
ABORT(R_BAD_ARGS);
|
||||
}
|
||||
|
||||
int
|
||||
r_thread_exit (void)
|
||||
{
|
||||
thread_count--;
|
||||
pthread_exit(0);
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
r_thread_wait_last (void)
|
||||
{
|
||||
do {
|
||||
pthread_yield();
|
||||
usleep(10000);
|
||||
DBG((0,"%d threads left",thread_count));
|
||||
} while (thread_count);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
r_rwlock_create (r_rwlock **lockp)
|
||||
{
|
||||
pthread_rwlock_t *lock;
|
||||
int r;
|
||||
|
||||
if(!(lock=(pthread_rwlock_t *)malloc(sizeof(pthread_rwlock_t))))
|
||||
ERETURN(R_NO_MEMORY);
|
||||
|
||||
if(r=pthread_rwlock_init(lock,0))
|
||||
ERETURN(R_INTERNAL);
|
||||
|
||||
*lockp=(void *)lock;
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
r_rwlock_destroy (r_rwlock **lock)
|
||||
{
|
||||
pthread_rwlock_t *plock;
|
||||
|
||||
if(!lock || !*lock)
|
||||
return(0);
|
||||
|
||||
plock=(pthread_rwlock_t *)(*lock);
|
||||
|
||||
pthread_rwlock_destroy(plock);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
r_rwlock_lock (r_rwlock *lock, int action)
|
||||
{
|
||||
pthread_rwlock_t *plock;
|
||||
int r,_status;
|
||||
|
||||
plock=(pthread_rwlock_t *)lock;
|
||||
|
||||
switch(action){
|
||||
case R_RWLOCK_UNLOCK:
|
||||
if(r=pthread_rwlock_unlock(plock))
|
||||
ABORT(R_INTERNAL);
|
||||
break;
|
||||
case R_RWLOCK_RLOCK:
|
||||
if(r=pthread_rwlock_rdlock(plock))
|
||||
ABORT(R_INTERNAL);
|
||||
break;
|
||||
case R_RWLOCK_WLOCK:
|
||||
if(r=pthread_rwlock_wrlock(plock))
|
||||
ABORT(R_INTERNAL);
|
||||
break;
|
||||
default:
|
||||
ABORT(R_BAD_ARGS);
|
||||
}
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
return(_status);
|
||||
}
|
||||
|
||||
|
||||
|
||||
_status = 0;
|
||||
abort:
|
||||
return (_status);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,110 +44,105 @@
|
|||
ekr@rtfm.com Thu Jan 7 22:58:27 1999
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <ctype.h>
|
||||
#include "network.h"
|
||||
#include "proto_mod.h"
|
||||
#include "debug.h"
|
||||
|
||||
typedef struct null_analyzer_ {
|
||||
int num;
|
||||
int num;
|
||||
} null_analyzer;
|
||||
|
||||
static int create_null_analyzer PROTO_LIST((void *handle,
|
||||
proto_ctx *ctx,tcp_conn *conn,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));
|
||||
proto_ctx *ctx,
|
||||
tcp_conn *conn,
|
||||
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,
|
||||
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)
|
||||
{
|
||||
null_analyzer *obj=0;
|
||||
static int ctr;
|
||||
|
||||
if(!(obj=(null_analyzer *)calloc(1,sizeof(null_analyzer))))
|
||||
ERETURN(R_NO_MEMORY);
|
||||
static int create_null_analyzer(void *handle,
|
||||
proto_ctx *ctx,
|
||||
tcp_conn *conn,
|
||||
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) {
|
||||
null_analyzer *obj = 0;
|
||||
static int ctr;
|
||||
|
||||
obj->num=ctr++;
|
||||
|
||||
DBG((0,"Creating analyzer for connection %d\n",obj->num));
|
||||
|
||||
*objp=(proto_obj *)obj;
|
||||
return(0);
|
||||
}
|
||||
if(!(obj = (null_analyzer *)calloc(1, sizeof(null_analyzer))))
|
||||
ERETURN(R_NO_MEMORY);
|
||||
|
||||
int
|
||||
destroy_null_analyzer (proto_obj **objp)
|
||||
{
|
||||
null_analyzer *obj;
|
||||
|
||||
if(!objp || !*objp)
|
||||
return(0);
|
||||
obj->num = ctr++;
|
||||
|
||||
obj=(null_analyzer *)*objp;
|
||||
DBG((0,"Destroying analyzer for connection %d\n",obj->num));
|
||||
|
||||
free(*objp);
|
||||
*objp=0;
|
||||
DBG((0, "Creating analyzer for connection %d\n", obj->num));
|
||||
|
||||
return(0);
|
||||
}
|
||||
*objp = (proto_obj *)obj;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
data_null_analyzer (proto_obj *_obj, segment *seg, int direction)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
null_analyzer *obj=(null_analyzer *)_obj;
|
||||
#endif
|
||||
DBG((0,"Processing data for connection %d dir %d\n",obj->num,
|
||||
direction));
|
||||
int destroy_null_analyzer(proto_obj **objp) {
|
||||
null_analyzer *obj;
|
||||
|
||||
for(;seg;seg=seg->next){
|
||||
int i;
|
||||
|
||||
for(i=0;i<MIN(seg->len,20);i++){
|
||||
if(!isascii(seg->data[i]))
|
||||
break;
|
||||
}
|
||||
if(i<20)
|
||||
xdump("NSEGMENT",seg->data,seg->len);
|
||||
else{
|
||||
printf("NSEGMENT: ");
|
||||
fwrite(seg->data,1,seg->len,stdout);
|
||||
}
|
||||
printf("====\n");
|
||||
if(!objp || !*objp)
|
||||
return (0);
|
||||
|
||||
obj = (null_analyzer *)*objp;
|
||||
DBG((0, "Destroying analyzer for connection %d\n", obj->num));
|
||||
|
||||
free(*objp);
|
||||
*objp = 0;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int data_null_analyzer(proto_obj *_obj, segment *seg, int direction) {
|
||||
#ifdef DEBUG
|
||||
null_analyzer *obj = (null_analyzer *)_obj;
|
||||
#endif
|
||||
DBG((0, "Processing data for connection %d dir %d\n", obj->num, direction));
|
||||
|
||||
for(; seg; seg = seg->next) {
|
||||
int i;
|
||||
|
||||
for(i = 0; i < MIN(seg->len, 20); i++) {
|
||||
if(!isascii(seg->data[i]))
|
||||
break;
|
||||
}
|
||||
|
||||
return(0);
|
||||
if(i < 20)
|
||||
xdump("NSEGMENT", seg->data, seg->len);
|
||||
else {
|
||||
printf("NSEGMENT: ");
|
||||
fwrite(seg->data, 1, seg->len, stdout);
|
||||
}
|
||||
printf("====\n");
|
||||
}
|
||||
|
||||
int
|
||||
fin_null_analyzer (proto_obj *_obj, packet *p, int direction)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
null_analyzer *obj=(null_analyzer *)_obj;
|
||||
#endif
|
||||
DBG((0,"Received FIN on connection %d\n",obj->num));
|
||||
return(0);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int fin_null_analyzer(proto_obj *_obj, packet *p, int direction) {
|
||||
#ifdef DEBUG
|
||||
null_analyzer *obj = (null_analyzer *)_obj;
|
||||
#endif
|
||||
DBG((0, "Received FIN on connection %d\n", obj->num));
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static struct proto_mod_vtbl_ null_vtbl ={
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
create_null_analyzer,
|
||||
0,
|
||||
destroy_null_analyzer,
|
||||
data_null_analyzer,
|
||||
fin_null_analyzer,
|
||||
static struct proto_mod_vtbl_ null_vtbl = {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
create_null_analyzer,
|
||||
0,
|
||||
destroy_null_analyzer,
|
||||
data_null_analyzer,
|
||||
fin_null_analyzer,
|
||||
};
|
||||
|
||||
struct proto_mod_ null_mod = {
|
||||
0,
|
||||
&null_vtbl
|
||||
};
|
||||
struct proto_mod_ null_mod = {0, &null_vtbl};
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,11 +44,9 @@
|
|||
ekr@rtfm.com Fri Jan 8 11:23:10 1999
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _null_analyze_h
|
||||
#define _null_analyze_h
|
||||
|
||||
extern proto_mod null_mod;
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -43,17 +43,17 @@
|
|||
*/
|
||||
|
||||
#if !defined(__GNUC__) && !defined(__clang__)
|
||||
#define __attribute__(x)
|
||||
#define __attribute__(x)
|
||||
#endif
|
||||
|
||||
#define UNUSED __attribute__((unused))
|
||||
#define NORET __attribute__((noreturn))
|
||||
#define PRINTF(f,a) __attribute__((format(printf,(f),(a))))
|
||||
#define SCANF(f,a) __attribute__((format(scanf,(f),(a))))
|
||||
#define WUNRES __attribute__((warn_unused_result))
|
||||
#define MALLOC __attribute__((malloc)) WUNRES
|
||||
#define NONNULL(...) __attribute__((nonnull(__VA_ARGS__)))
|
||||
#define PURE __attribute__((pure))
|
||||
#define UNUSED __attribute__((unused))
|
||||
#define NORET __attribute__((noreturn))
|
||||
#define PRINTF(f, a) __attribute__((format(printf, (f), (a))))
|
||||
#define SCANF(f, a) __attribute__((format(scanf, (f), (a))))
|
||||
#define WUNRES __attribute__((warn_unused_result))
|
||||
#define MALLOC __attribute__((malloc)) WUNRES
|
||||
#define NONNULL(...) __attribute__((nonnull(__VA_ARGS__)))
|
||||
#define PURE __attribute__((pure))
|
||||
|
||||
/*
|
||||
* Branch prediction macros.
|
||||
|
@ -61,11 +61,11 @@
|
|||
*/
|
||||
|
||||
#if !defined(__GNUC__) && !defined(__clang__)
|
||||
#define likely(expr) (expr)
|
||||
#define unlikely(expr) (expr)
|
||||
#define likely(expr) (expr)
|
||||
#define unlikely(expr) (expr)
|
||||
#else
|
||||
#define likely(expr) __builtin_expect((expr), 1)
|
||||
#define unlikely(expr) __builtin_expect((expr), 0)
|
||||
#define likely(expr) __builtin_expect((expr), 1)
|
||||
#define unlikely(expr) __builtin_expect((expr), 0)
|
||||
#endif
|
||||
|
||||
#endif /* !ATTRIB_H */
|
||||
|
|
1122
pcap/logpkt.c
1122
pcap/logpkt.c
File diff suppressed because it is too large
Load diff
|
@ -35,7 +35,6 @@
|
|||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
|
||||
|
||||
#ifndef WITHOUT_MIRROR
|
||||
#include <libnet.h>
|
||||
#else /* WITHOUT_MIRROR */
|
||||
|
@ -44,28 +43,39 @@
|
|||
#endif /* WITHOUT_MIRROR */
|
||||
|
||||
typedef struct {
|
||||
libnet_t *libnet;
|
||||
uint8_t src_ether[ETHER_ADDR_LEN];
|
||||
uint8_t dst_ether[ETHER_ADDR_LEN];
|
||||
struct sockaddr_storage src_addr;
|
||||
struct sockaddr_storage dst_addr;
|
||||
uint32_t src_seq;
|
||||
uint32_t dst_seq;
|
||||
size_t mss;
|
||||
libnet_t *libnet;
|
||||
uint8_t src_ether[ETHER_ADDR_LEN];
|
||||
uint8_t dst_ether[ETHER_ADDR_LEN];
|
||||
struct sockaddr_storage src_addr;
|
||||
struct sockaddr_storage dst_addr;
|
||||
uint32_t src_seq;
|
||||
uint32_t dst_seq;
|
||||
size_t mss;
|
||||
} logpkt_ctx_t;
|
||||
|
||||
#define LOGPKT_REQUEST 0
|
||||
#define LOGPKT_REQUEST 0
|
||||
#define LOGPKT_RESPONSE 1
|
||||
|
||||
int logpkt_pcap_open_fd(int fd) WUNRES;
|
||||
void logpkt_ctx_init(logpkt_ctx_t *, libnet_t *, size_t,
|
||||
const uint8_t *, const uint8_t *,
|
||||
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;
|
||||
void logpkt_ctx_init(logpkt_ctx_t *,
|
||||
libnet_t *,
|
||||
size_t,
|
||||
const uint8_t *,
|
||||
const uint8_t *,
|
||||
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_ether_lookup(libnet_t *, uint8_t *, uint8_t *,
|
||||
const char *, const char *) WUNRES;
|
||||
int logpkt_ether_lookup(libnet_t *,
|
||||
uint8_t *,
|
||||
uint8_t *,
|
||||
const char *,
|
||||
const char *) WUNRES;
|
||||
|
||||
#endif /* !LOGPKT_H */
|
||||
|
|
|
@ -17,132 +17,137 @@
|
|||
|
||||
#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 create_pcap_logger PROTO_LIST((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 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));
|
||||
static int create_pcap_logger PROTO_LIST((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 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;
|
||||
static uint8_t content_pcap_src_ether[ETHER_ADDR_LEN] = {0x02, 0x00, 0x00, 0x11, 0x11, 0x11};
|
||||
static uint8_t content_pcap_dst_ether[ETHER_ADDR_LEN] = {0x02, 0x00, 0x00, 0x22, 0x22, 0x22};
|
||||
|
||||
static int
|
||||
init_pcap_logger (void *data)
|
||||
{
|
||||
char *pcap_outfile = (char *) data;
|
||||
pcap_fd = open(pcap_outfile, O_RDWR|O_CREAT, DFLT_FILEMODE);
|
||||
if (pcap_fd == -1) {
|
||||
//printf("Failed to open pcap '%s' for writing\n", pcap_outfile);
|
||||
return -1;
|
||||
}
|
||||
if (logpkt_pcap_open_fd(pcap_fd) == -1) {
|
||||
//printf("Failed to prepare '%s' for PCAP writing\n", pcap_outfile);
|
||||
close(pcap_fd);
|
||||
pcap_fd = -1;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static uint8_t content_pcap_src_ether[ETHER_ADDR_LEN] = {0x02, 0x00, 0x00,
|
||||
0x11, 0x11, 0x11};
|
||||
static uint8_t content_pcap_dst_ether[ETHER_ADDR_LEN] = {0x02, 0x00, 0x00,
|
||||
0x22, 0x22, 0x22};
|
||||
|
||||
static int
|
||||
deinit_pcap_logger (void)
|
||||
{
|
||||
fdatasync(pcap_fd);
|
||||
static int init_pcap_logger(void *data) {
|
||||
char *pcap_outfile = (char *)data;
|
||||
pcap_fd = open(pcap_outfile, O_RDWR | O_CREAT, DFLT_FILEMODE);
|
||||
if(pcap_fd == -1) {
|
||||
// printf("Failed to open pcap '%s' for writing\n", pcap_outfile);
|
||||
return -1;
|
||||
}
|
||||
if(logpkt_pcap_open_fd(pcap_fd) == -1) {
|
||||
// printf("Failed to prepare '%s' for PCAP writing\n", pcap_outfile);
|
||||
close(pcap_fd);
|
||||
return 0;
|
||||
pcap_fd = -1;
|
||||
return -1;
|
||||
}
|
||||
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)
|
||||
{
|
||||
int r,_status;
|
||||
logpkt_ctx_t *pcap_obj=0;
|
||||
struct sockaddr_in src_addr, dst_addr;
|
||||
static int deinit_pcap_logger(void) {
|
||||
fdatasync(pcap_fd);
|
||||
close(pcap_fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!(pcap_obj=(logpkt_ctx_t *)calloc(1,sizeof(logpkt_ctx_t))))
|
||||
ABORT(R_NO_MEMORY);
|
||||
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) {
|
||||
int r, _status;
|
||||
logpkt_ctx_t *pcap_obj = 0;
|
||||
struct sockaddr_in src_addr, dst_addr;
|
||||
|
||||
//src_addr.sin_family = AF_INET;
|
||||
//src_addr.sin_addr = *i_addr;
|
||||
memcpy(&src_addr, i_addr, sizeof(struct sockaddr_in));
|
||||
src_addr.sin_port = htons(i_port);
|
||||
if(!(pcap_obj = (logpkt_ctx_t *)calloc(1, sizeof(logpkt_ctx_t))))
|
||||
ABORT(R_NO_MEMORY);
|
||||
|
||||
//dst_addr.sin_family = AF_INET;
|
||||
//dst_addr.sin_addr = *r_addr;
|
||||
memcpy(&dst_addr, r_addr, sizeof(struct sockaddr_in));
|
||||
dst_addr.sin_port = htons(r_port);
|
||||
// src_addr.sin_family = AF_INET;
|
||||
// src_addr.sin_addr = *i_addr;
|
||||
memcpy(&src_addr, i_addr, sizeof(struct sockaddr_in));
|
||||
src_addr.sin_port = htons(i_port);
|
||||
|
||||
logpkt_ctx_init(pcap_obj,NULL,0,content_pcap_src_ether, content_pcap_dst_ether,
|
||||
(const struct sockaddr*)&src_addr, sizeof(src_addr),
|
||||
(const struct sockaddr*)&dst_addr, sizeof(dst_addr));
|
||||
*objp=(proto_obj *)pcap_obj;
|
||||
_status=0;
|
||||
abort:
|
||||
if(_status){
|
||||
destroy_pcap_logger((proto_obj **)&pcap_obj);
|
||||
}
|
||||
return(_status);
|
||||
// dst_addr.sin_family = AF_INET;
|
||||
// dst_addr.sin_addr = *r_addr;
|
||||
memcpy(&dst_addr, r_addr, sizeof(struct sockaddr_in));
|
||||
dst_addr.sin_port = htons(r_port);
|
||||
|
||||
logpkt_ctx_init(pcap_obj, NULL, 0, content_pcap_src_ether,
|
||||
content_pcap_dst_ether, (const struct sockaddr *)&src_addr,
|
||||
sizeof(src_addr), (const struct sockaddr *)&dst_addr,
|
||||
sizeof(dst_addr));
|
||||
*objp = (proto_obj *)pcap_obj;
|
||||
_status = 0;
|
||||
abort:
|
||||
if(_status) {
|
||||
destroy_pcap_logger((proto_obj **)&pcap_obj);
|
||||
}
|
||||
return (_status);
|
||||
}
|
||||
|
||||
static int
|
||||
destroy_pcap_logger (proto_obj **objp)
|
||||
{
|
||||
logpkt_ctx_t *pcap_obj;
|
||||
static int destroy_pcap_logger(proto_obj **objp) {
|
||||
logpkt_ctx_t *pcap_obj;
|
||||
|
||||
if(!objp || !*objp)
|
||||
return(0);
|
||||
if(!objp || !*objp)
|
||||
return (0);
|
||||
|
||||
pcap_obj=(logpkt_ctx_t *)*objp;
|
||||
pcap_obj = (logpkt_ctx_t *)*objp;
|
||||
|
||||
free(pcap_obj);
|
||||
*objp=0;
|
||||
free(pcap_obj);
|
||||
*objp = 0;
|
||||
|
||||
return(0);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
data_pcap_logger (proto_obj *_obj, unsigned char *data, unsigned int len, int dir)
|
||||
{
|
||||
logpkt_ctx_t *pcap_obj = (logpkt_ctx_t *)_obj;
|
||||
int direction;
|
||||
int status;
|
||||
|
||||
if (dir == DIR_I2R ) direction = LOGPKT_REQUEST;
|
||||
else direction = LOGPKT_RESPONSE;
|
||||
static int data_pcap_logger(proto_obj *_obj,
|
||||
unsigned char *data,
|
||||
unsigned int len,
|
||||
int dir) {
|
||||
logpkt_ctx_t *pcap_obj = (logpkt_ctx_t *)_obj;
|
||||
int direction;
|
||||
int status;
|
||||
|
||||
status = logpkt_write_payload(pcap_obj,pcap_fd,direction,data,len);
|
||||
if(dir == DIR_I2R)
|
||||
direction = LOGPKT_REQUEST;
|
||||
else
|
||||
direction = LOGPKT_RESPONSE;
|
||||
|
||||
return status;
|
||||
}
|
||||
status = logpkt_write_payload(pcap_obj, pcap_fd, direction, data, len);
|
||||
|
||||
int
|
||||
close_pcap_logger (proto_obj *_obj, unsigned char *data, unsigned int len, int dir)
|
||||
{
|
||||
logpkt_ctx_t *pcap_obj = (logpkt_ctx_t *)_obj;
|
||||
int direction;
|
||||
int status;
|
||||
|
||||
if (dir == DIR_I2R ) direction = LOGPKT_REQUEST;
|
||||
else direction = LOGPKT_RESPONSE;
|
||||
return status;
|
||||
}
|
||||
|
||||
status = logpkt_write_close(pcap_obj, pcap_fd, direction);
|
||||
|
||||
return status;
|
||||
}
|
||||
int close_pcap_logger(proto_obj *_obj,
|
||||
unsigned char *data,
|
||||
unsigned int len,
|
||||
int dir) {
|
||||
logpkt_ctx_t *pcap_obj = (logpkt_ctx_t *)_obj;
|
||||
int direction;
|
||||
int status;
|
||||
|
||||
static struct logger_mod_vtbl_ pcap_vtbl ={
|
||||
init_pcap_logger,
|
||||
deinit_pcap_logger,
|
||||
create_pcap_logger,
|
||||
destroy_pcap_logger,
|
||||
data_pcap_logger,
|
||||
close_pcap_logger,
|
||||
if(dir == DIR_I2R)
|
||||
direction = LOGPKT_REQUEST;
|
||||
else
|
||||
direction = LOGPKT_RESPONSE;
|
||||
|
||||
status = logpkt_write_close(pcap_obj, pcap_fd, direction);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static struct logger_mod_vtbl_ pcap_vtbl = {
|
||||
init_pcap_logger, deinit_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;
|
||||
|
||||
#endif
|
||||
|
||||
|
|
58
pcap/sys.c
58
pcap/sys.c
|
@ -53,47 +53,41 @@
|
|||
/*
|
||||
* Determine address family of addr
|
||||
*/
|
||||
int
|
||||
sys_get_af(const char *addr)
|
||||
{
|
||||
if (strstr(addr, ":"))
|
||||
return AF_INET6;
|
||||
else if (!strpbrk(addr, "abcdefghijklmnopqrstu"
|
||||
"vwxyzABCDEFGHIJKLMNOP"
|
||||
"QRSTUVWXYZ-"))
|
||||
return AF_INET;
|
||||
else
|
||||
return AF_UNSPEC;
|
||||
int sys_get_af(const char *addr) {
|
||||
if(strstr(addr, ":"))
|
||||
return AF_INET6;
|
||||
else if(!strpbrk(addr,
|
||||
"abcdefghijklmnopqrstu"
|
||||
"vwxyzABCDEFGHIJKLMNOP"
|
||||
"QRSTUVWXYZ-"))
|
||||
return AF_INET;
|
||||
else
|
||||
return AF_UNSPEC;
|
||||
}
|
||||
|
||||
|
||||
static int sys_rand_seeded = 0;
|
||||
|
||||
static void
|
||||
sys_rand_seed(void) {
|
||||
struct timeval seed;
|
||||
static void sys_rand_seed(void) {
|
||||
struct timeval seed;
|
||||
|
||||
if (gettimeofday(&seed, NULL) == -1) {
|
||||
srandom((unsigned)time(NULL));
|
||||
} else {
|
||||
srandom((unsigned)(seed.tv_sec ^ seed.tv_usec));
|
||||
}
|
||||
sys_rand_seeded = 1;
|
||||
if(gettimeofday(&seed, NULL) == -1) {
|
||||
srandom((unsigned)time(NULL));
|
||||
} else {
|
||||
srandom((unsigned)(seed.tv_sec ^ seed.tv_usec));
|
||||
}
|
||||
sys_rand_seeded = 1;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
sys_rand16(void) {
|
||||
if (unlikely(!sys_rand_seeded))
|
||||
sys_rand_seed();
|
||||
return random();
|
||||
uint16_t sys_rand16(void) {
|
||||
if(unlikely(!sys_rand_seeded))
|
||||
sys_rand_seed();
|
||||
return random();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
sys_rand32(void) {
|
||||
if (unlikely(!sys_rand_seeded))
|
||||
sys_rand_seed();
|
||||
return random();
|
||||
uint32_t sys_rand32(void) {
|
||||
if(unlikely(!sys_rand_seeded))
|
||||
sys_rand_seed();
|
||||
return random();
|
||||
}
|
||||
|
||||
/* vim: set noet ft=c: */
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,209 +44,203 @@
|
|||
ekr@rtfm.com Tue Mar 30 17:19:56 1999
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <r_common.h>
|
||||
|
||||
#include "sslciphers.h"
|
||||
|
||||
static SSL_CipherSuite CipherSuites[]={
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{27,KEX_DH,SIG_NONE,ENC_3DES,8,192,192,DIG_MD5,16,0},
|
||||
// Missing: 44-46
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
// Missing: 138-149
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
// Missing: 168-185
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{4867,KEX_DH,SIG_NONE,ENC_CHACHA20_POLY1305,64,256,256,DIG_SHA256,32,0},
|
||||
{4868,KEX_DH,SIG_NONE,ENC_AES128_CCM,16,128,128,DIG_SHA256,32,0},
|
||||
{4869,KEX_DH,SIG_NONE,ENC_AES128_CCM_8,16,128,128,DIG_SHA256,32,0},
|
||||
{49153,KEX_DH,SIG_DSS,ENC_NULL,0,0,0,DIG_SHA,20,0},
|
||||
{49154,KEX_DH,SIG_DSS,ENC_RC4,1,128,128,DIG_SHA,20,0},
|
||||
{49155,KEX_DH,SIG_DSS,ENC_3DES,8,192,192,DIG_SHA,20,0},
|
||||
{49156,KEX_DH,SIG_DSS,ENC_AES128,16,128,128,DIG_SHA,20,0},
|
||||
{49157,KEX_DH,SIG_DSS,ENC_AES256,16,256,256,DIG_SHA,20,0},
|
||||
{49158,KEX_DH,SIG_DSS,ENC_NULL,0,0,0,DIG_SHA,20,0},
|
||||
{49159,KEX_DH,SIG_DSS,ENC_RC4,1,128,128,DIG_SHA,20,0},
|
||||
{49160,KEX_DH,SIG_DSS,ENC_3DES,8,192,192,DIG_SHA,20,0},
|
||||
{49161,KEX_DH,SIG_DSS,ENC_AES128,16,128,128,DIG_SHA,20,0},
|
||||
{49162,KEX_DH,SIG_DSS,ENC_AES256,16,256,256,DIG_SHA,20,0},
|
||||
{49163,KEX_DH,SIG_RSA,ENC_NULL,0,0,0,DIG_SHA,20,0},
|
||||
{49164,KEX_DH,SIG_RSA,ENC_RC4,1,128,128,DIG_SHA,20,0},
|
||||
{49165,KEX_DH,SIG_RSA,ENC_3DES,8,192,192,DIG_SHA,20,0},
|
||||
{49166,KEX_DH,SIG_RSA,ENC_AES128,16,128,128,DIG_SHA,20,0},
|
||||
{49167,KEX_DH,SIG_RSA,ENC_AES256,16,256,256,DIG_SHA,20,0},
|
||||
{49168,KEX_DH,SIG_RSA,ENC_NULL,0,0,0,DIG_SHA,20,0},
|
||||
{49169,KEX_DH,SIG_RSA,ENC_RC4,1,128,128,DIG_SHA,20,0},
|
||||
{49170,KEX_DH,SIG_RSA,ENC_3DES,8,192,192,DIG_SHA,20,0},
|
||||
{49171,KEX_DH,SIG_RSA,ENC_AES128,16,128,128,DIG_SHA,20,0},
|
||||
{49172,KEX_DH,SIG_RSA,ENC_AES256,16,256,256,DIG_SHA,20,0},
|
||||
{49173,KEX_DH,SIG_NONE,ENC_NULL,0,0,0,DIG_SHA,20,0},
|
||||
{49174,KEX_DH,SIG_NONE,ENC_RC4,1,128,128,DIG_SHA,20,0},
|
||||
{49175,KEX_DH,SIG_NONE,ENC_3DES,8,192,192,DIG_SHA,20,0},
|
||||
{49176,KEX_DH,SIG_NONE,ENC_AES128,16,128,128,DIG_SHA,20,0},
|
||||
{49177,KEX_DH,SIG_NONE,ENC_AES256,16,256,256,DIG_SHA,20,0},
|
||||
{49187,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},
|
||||
{49189,KEX_DH,SIG_DSS,ENC_AES128,16,128,128,DIG_SHA256,32,0},
|
||||
{49190,KEX_DH,SIG_DSS,ENC_AES256,16,256,256,DIG_SHA384,48,0},
|
||||
{49191,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},
|
||||
{49193,KEX_DH,SIG_RSA,ENC_AES128,16,128,128,DIG_SHA256,32,0},
|
||||
{49194,KEX_DH,SIG_RSA,ENC_AES256,16,256,256,DIG_SHA384,48,0},
|
||||
{49195,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},
|
||||
{49197,KEX_DH,SIG_DSS,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},
|
||||
{49199,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},
|
||||
{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
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
// Missing: 49294-49307
|
||||
{-1}
|
||||
};
|
||||
static SSL_CipherSuite CipherSuites[] = {
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{27, KEX_DH, SIG_NONE, ENC_3DES, 8, 192, 192, DIG_MD5, 16, 0},
|
||||
// Missing: 44-46
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
// Missing: 138-149
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
// Missing: 168-185
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{4867, KEX_DH, SIG_NONE, ENC_CHACHA20_POLY1305, 64, 256, 256, DIG_SHA256,
|
||||
32, 0},
|
||||
{4868, KEX_DH, SIG_NONE, ENC_AES128_CCM, 16, 128, 128, DIG_SHA256, 32, 0},
|
||||
{4869, KEX_DH, SIG_NONE, ENC_AES128_CCM_8, 16, 128, 128, DIG_SHA256, 32, 0},
|
||||
{49153, KEX_DH, SIG_DSS, ENC_NULL, 0, 0, 0, DIG_SHA, 20, 0},
|
||||
{49154, KEX_DH, SIG_DSS, ENC_RC4, 1, 128, 128, DIG_SHA, 20, 0},
|
||||
{49155, KEX_DH, SIG_DSS, ENC_3DES, 8, 192, 192, DIG_SHA, 20, 0},
|
||||
{49156, KEX_DH, SIG_DSS, ENC_AES128, 16, 128, 128, DIG_SHA, 20, 0},
|
||||
{49157, KEX_DH, SIG_DSS, ENC_AES256, 16, 256, 256, DIG_SHA, 20, 0},
|
||||
{49158, KEX_DH, SIG_DSS, ENC_NULL, 0, 0, 0, DIG_SHA, 20, 0},
|
||||
{49159, KEX_DH, SIG_DSS, ENC_RC4, 1, 128, 128, DIG_SHA, 20, 0},
|
||||
{49160, KEX_DH, SIG_DSS, ENC_3DES, 8, 192, 192, DIG_SHA, 20, 0},
|
||||
{49161, KEX_DH, SIG_DSS, ENC_AES128, 16, 128, 128, DIG_SHA, 20, 0},
|
||||
{49162, KEX_DH, SIG_DSS, ENC_AES256, 16, 256, 256, DIG_SHA, 20, 0},
|
||||
{49163, KEX_DH, SIG_RSA, ENC_NULL, 0, 0, 0, DIG_SHA, 20, 0},
|
||||
{49164, KEX_DH, SIG_RSA, ENC_RC4, 1, 128, 128, DIG_SHA, 20, 0},
|
||||
{49165, KEX_DH, SIG_RSA, ENC_3DES, 8, 192, 192, DIG_SHA, 20, 0},
|
||||
{49166, KEX_DH, SIG_RSA, ENC_AES128, 16, 128, 128, DIG_SHA, 20, 0},
|
||||
{49167, KEX_DH, SIG_RSA, ENC_AES256, 16, 256, 256, DIG_SHA, 20, 0},
|
||||
{49168, KEX_DH, SIG_RSA, ENC_NULL, 0, 0, 0, DIG_SHA, 20, 0},
|
||||
{49169, KEX_DH, SIG_RSA, ENC_RC4, 1, 128, 128, DIG_SHA, 20, 0},
|
||||
{49170, KEX_DH, SIG_RSA, ENC_3DES, 8, 192, 192, DIG_SHA, 20, 0},
|
||||
{49171, KEX_DH, SIG_RSA, ENC_AES128, 16, 128, 128, DIG_SHA, 20, 0},
|
||||
{49172, KEX_DH, SIG_RSA, ENC_AES256, 16, 256, 256, DIG_SHA, 20, 0},
|
||||
{49173, KEX_DH, SIG_NONE, ENC_NULL, 0, 0, 0, DIG_SHA, 20, 0},
|
||||
{49174, KEX_DH, SIG_NONE, ENC_RC4, 1, 128, 128, DIG_SHA, 20, 0},
|
||||
{49175, KEX_DH, SIG_NONE, ENC_3DES, 8, 192, 192, DIG_SHA, 20, 0},
|
||||
{49176, KEX_DH, SIG_NONE, ENC_AES128, 16, 128, 128, DIG_SHA, 20, 0},
|
||||
{49177, KEX_DH, SIG_NONE, ENC_AES256, 16, 256, 256, DIG_SHA, 20, 0},
|
||||
{49187, 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},
|
||||
{49189, KEX_DH, SIG_DSS, ENC_AES128, 16, 128, 128, DIG_SHA256, 32, 0},
|
||||
{49190, KEX_DH, SIG_DSS, ENC_AES256, 16, 256, 256, DIG_SHA384, 48, 0},
|
||||
{49191, 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},
|
||||
{49193, KEX_DH, SIG_RSA, ENC_AES128, 16, 128, 128, DIG_SHA256, 32, 0},
|
||||
{49194, KEX_DH, SIG_RSA, ENC_AES256, 16, 256, 256, DIG_SHA384, 48, 0},
|
||||
{49195, 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},
|
||||
{49197, KEX_DH, SIG_DSS, 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},
|
||||
{49199, 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},
|
||||
{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
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
{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},
|
||||
// Missing: 49294-49307
|
||||
{-1}};
|
||||
|
||||
int
|
||||
ssl_find_cipher (int num, SSL_CipherSuite **cs)
|
||||
{
|
||||
SSL_CipherSuite *c;
|
||||
int ssl_find_cipher(int num, SSL_CipherSuite **cs) {
|
||||
SSL_CipherSuite *c;
|
||||
|
||||
for(c=CipherSuites;c->number!=-1;c++){
|
||||
if(c->number==num){
|
||||
*cs=c;
|
||||
return(0);
|
||||
}
|
||||
for(c = CipherSuites; c->number != -1; c++) {
|
||||
if(c->number == num) {
|
||||
*cs = c;
|
||||
return (0);
|
||||
}
|
||||
|
||||
ERETURN(R_NOT_FOUND);
|
||||
}
|
||||
|
||||
|
||||
|
||||
ERETURN(R_NOT_FOUND);
|
||||
}
|
||||
|
|
4825
ssl/ssl.enums.c
4825
ssl/ssl.enums.c
File diff suppressed because it is too large
Load diff
1002
ssl/ssl_analyze.c
1002
ssl/ssl_analyze.c
File diff suppressed because it is too large
Load diff
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,43 +44,42 @@
|
|||
ekr@rtfm.com Tue Jan 12 08:45:44 1999
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _ssl_analyze_h
|
||||
#define _ssl_analyze_h
|
||||
|
||||
extern proto_mod ssl_mod;
|
||||
|
||||
/*The type of data this is*/
|
||||
#define P_RH (1<<3)
|
||||
#define P_HT (1<<4)
|
||||
#define P_HL (1<<5)
|
||||
#define P_ND (1<<6)
|
||||
#define P_DC (1<<7)
|
||||
#define P_NR (1<<8)
|
||||
#define P_ASN (1<<9)
|
||||
#define P_CR (1<<10)
|
||||
#define P_AD (1<<11)
|
||||
#define P_TSA (1<<12)
|
||||
#define P_QT (1<<13)
|
||||
#define P_HO (1<<14)
|
||||
#define P_JS (1<<15)
|
||||
#define P_RH (1 << 3)
|
||||
#define P_HT (1 << 4)
|
||||
#define P_HL (1 << 5)
|
||||
#define P_ND (1 << 6)
|
||||
#define P_DC (1 << 7)
|
||||
#define P_NR (1 << 8)
|
||||
#define P_ASN (1 << 9)
|
||||
#define P_CR (1 << 10)
|
||||
#define P_AD (1 << 11)
|
||||
#define P_TSA (1 << 12)
|
||||
#define P_QT (1 << 13)
|
||||
#define P_HO (1 << 14)
|
||||
#define P_JS (1 << 15)
|
||||
|
||||
#define SSL_PRINT_TIMESTAMP (1) /*Timestamp records*/
|
||||
#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_HANDSHAKE_TYPE P_HT /*Print the handshake type*/
|
||||
#define SSL_PRINT_HIGHLIGHTS (P_HT | P_HL)
|
||||
#define SSL_PRINT_ALL_FIELDS (P_RH | P_HT | P_HL | P_ND)
|
||||
#define SSL_PRINT_DECODE (P_DC) /*Print fields as decoded*/
|
||||
#define SSL_PRINT_NROFF (P_NR)
|
||||
#define SSL_PRINT_DECODE_ASN1 (P_ASN)
|
||||
#define SSL_PRINT_CRYPTO (P_CR)
|
||||
#define SSL_PRINT_APP_DATA (P_AD)
|
||||
#define SSL_PRINT_TIMESTAMP_ABSOLUTE (P_TSA)
|
||||
#define SSL_PRINT_QUIET (P_QT)
|
||||
#define SSL_PRINT_HEX_ONLY (P_HO)
|
||||
#define SSL_PRINT_JSON (P_JS)
|
||||
#define SSL_PRINT_ALL 0xfffffff
|
||||
#define SSL_PRINT_TIMESTAMP (1) /*Timestamp records*/
|
||||
#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_HANDSHAKE_TYPE P_HT /*Print the handshake type*/
|
||||
#define SSL_PRINT_HIGHLIGHTS (P_HT | P_HL)
|
||||
#define SSL_PRINT_ALL_FIELDS (P_RH | P_HT | P_HL | P_ND)
|
||||
#define SSL_PRINT_DECODE (P_DC) /*Print fields as decoded*/
|
||||
#define SSL_PRINT_NROFF (P_NR)
|
||||
#define SSL_PRINT_DECODE_ASN1 (P_ASN)
|
||||
#define SSL_PRINT_CRYPTO (P_CR)
|
||||
#define SSL_PRINT_APP_DATA (P_AD)
|
||||
#define SSL_PRINT_TIMESTAMP_ABSOLUTE (P_TSA)
|
||||
#define SSL_PRINT_QUIET (P_QT)
|
||||
#define SSL_PRINT_HEX_ONLY (P_HO)
|
||||
#define SSL_PRINT_JSON (P_JS)
|
||||
#define SSL_PRINT_ALL 0xfffffff
|
||||
|
||||
extern UINT4 SSL_print_flags;
|
||||
extern char *SSL_keyfile;
|
||||
|
@ -87,4 +87,3 @@ extern char *SSL_password;
|
|||
extern char *SSL_keylogfile;
|
||||
|
||||
#endif
|
||||
|
||||
|
|
133
ssl/ssl_h.h
133
ssl/ssl_h.h
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,7 +44,6 @@
|
|||
ekr@rtfm.com Fri Jan 8 14:09:37 1999
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _ssl_h
|
||||
#define _ssl_h
|
||||
|
||||
|
@ -52,19 +52,18 @@
|
|||
typedef struct ssl_decode_ctx_ ssl_decode_ctx;
|
||||
typedef struct ssl_decoder_ ssl_decoder;
|
||||
|
||||
|
||||
typedef struct d_queue_ {
|
||||
short state; /*What state we're in*/
|
||||
#define SSL_READ_NONE 1
|
||||
#define SSL_READ_HEADER 2
|
||||
int read_left; /*How many more bytes to read in this state*/
|
||||
int len; /*The length of the total record, including header*/
|
||||
UCHAR *data; /*The data for this record*/
|
||||
UCHAR *ptr; /*The data ptr*/
|
||||
int _allocated; /*The number of data bytes allocated for this record*/
|
||||
segment *q; /*The segments that match this record*/
|
||||
segment *q_last; /*The last segment*/
|
||||
int offset; /*How far into the first segment this record starts*/
|
||||
short state; /*What state we're in*/
|
||||
#define SSL_READ_NONE 1
|
||||
#define SSL_READ_HEADER 2
|
||||
int read_left; /*How many more bytes to read in this state*/
|
||||
int len; /*The length of the total record, including header*/
|
||||
UCHAR *data; /*The data for this record*/
|
||||
UCHAR *ptr; /*The data ptr*/
|
||||
int _allocated; /*The number of data bytes allocated for this record*/
|
||||
segment *q; /*The segments that match this record*/
|
||||
segment *q_last; /*The last segment*/
|
||||
int offset; /*How far into the first segment this record starts*/
|
||||
} r_queue;
|
||||
|
||||
typedef struct ssl_extensions_ {
|
||||
|
@ -75,77 +74,75 @@ typedef struct ssl_extensions_ {
|
|||
} ssl_extensions;
|
||||
|
||||
typedef struct ssl_obj_ {
|
||||
tcp_conn *conn;
|
||||
proto_obj *logger_obj;
|
||||
int r_state;
|
||||
int i_state;
|
||||
int version;
|
||||
UINT4 cipher_suite;
|
||||
tcp_conn *conn;
|
||||
proto_obj *logger_obj;
|
||||
int r_state;
|
||||
int i_state;
|
||||
int version;
|
||||
UINT4 cipher_suite;
|
||||
|
||||
char *client_name;
|
||||
char *client_ip;
|
||||
int client_port;
|
||||
char *server_name;
|
||||
char *server_ip;
|
||||
int server_port;
|
||||
char *client_name;
|
||||
char *client_ip;
|
||||
int client_port;
|
||||
char *server_name;
|
||||
char *server_ip;
|
||||
int server_port;
|
||||
|
||||
struct SSL_CipherSuite_ *cs;
|
||||
r_queue *i2r_queue;
|
||||
r_queue *r2i_queue;
|
||||
struct timeval time_start;
|
||||
struct timeval time_last;
|
||||
ssl_decode_ctx *ssl_ctx;
|
||||
ssl_decoder *decoder;
|
||||
ssl_extensions *extensions;
|
||||
struct SSL_CipherSuite_ *cs;
|
||||
r_queue *i2r_queue;
|
||||
r_queue *r2i_queue;
|
||||
struct timeval time_start;
|
||||
struct timeval time_last;
|
||||
ssl_decode_ctx *ssl_ctx;
|
||||
ssl_decoder *decoder;
|
||||
ssl_extensions *extensions;
|
||||
|
||||
int process_ciphertext;
|
||||
int process_ciphertext;
|
||||
|
||||
/*Printing bookkeeping*/
|
||||
#define REC_PLAINTEXT 1
|
||||
#define REC_DECRYPTED_CIPHERTEXT 2
|
||||
#define REC_CIPHERTEXT 3
|
||||
int record_encryption;
|
||||
/*Printing bookkeeping*/
|
||||
#define REC_PLAINTEXT 1
|
||||
#define REC_DECRYPTED_CIPHERTEXT 2
|
||||
#define REC_CIPHERTEXT 3
|
||||
int record_encryption;
|
||||
|
||||
int direction; /* The direction we're currently working in*/
|
||||
int record_count;
|
||||
int indent_depth;
|
||||
int indent_name_len;
|
||||
struct json_object *cur_json_st;
|
||||
char *cur_ja3_ec_str;
|
||||
char *cur_ja3_ecp_str;
|
||||
int direction; /* The direction we're currently working in*/
|
||||
int record_count;
|
||||
int indent_depth;
|
||||
int indent_name_len;
|
||||
struct json_object *cur_json_st;
|
||||
char *cur_ja3_ec_str;
|
||||
char *cur_ja3_ecp_str;
|
||||
} ssl_obj;
|
||||
|
||||
typedef struct decoder_ {
|
||||
int type;
|
||||
char *name;
|
||||
int (*print) PROTO_LIST((ssl_obj *,int direction,segment *seg,Data *data));
|
||||
int type;
|
||||
char *name;
|
||||
int(*print) PROTO_LIST((ssl_obj *, int direction, segment *seg, Data *data));
|
||||
} decoder;
|
||||
|
||||
#define SSL_NO_DATA 1
|
||||
#define SSL_NO_DATA 1
|
||||
#define SSL_BAD_CONTENT_TYPE 2
|
||||
#define SSL_BAD_PMS 3
|
||||
#define SSL_CANT_DO_CIPHER 4
|
||||
#define SSL_NO_DECRYPT 5
|
||||
#define SSL_BAD_MAC 6
|
||||
#define SSL_BAD_DATA 7
|
||||
#define SSL_BAD_PMS 3
|
||||
#define SSL_CANT_DO_CIPHER 4
|
||||
#define SSL_NO_DECRYPT 5
|
||||
#define SSL_BAD_MAC 6
|
||||
#define SSL_BAD_DATA 7
|
||||
|
||||
/*SSL defines*/
|
||||
#define COMBINE(a,b) ((a<<8) | b)
|
||||
#define COMBINE(a, b) ((a << 8) | b)
|
||||
#define SSL_HEADER_SIZE 5
|
||||
|
||||
#define SSLV3_VERSION 0x300
|
||||
#define TLSV1_VERSION 0x301
|
||||
#define TLSV11_VERSION 0x302
|
||||
#define TLSV12_VERSION 0x303
|
||||
#define TLSV13_VERSION 0x304
|
||||
#define SSLV3_VERSION 0x300
|
||||
#define TLSV1_VERSION 0x301
|
||||
#define TLSV11_VERSION 0x302
|
||||
#define TLSV12_VERSION 0x303
|
||||
#define TLSV13_VERSION 0x304
|
||||
|
||||
/*State defines*/
|
||||
#define SSL_ST_SENT_NOTHING 0
|
||||
#define SSL_ST_HANDSHAKE 1
|
||||
#define SSL_ST_SENT_CHANGE_CIPHER_SPEC 2
|
||||
#define SSL_ST_SENT_NOTHING 0
|
||||
#define SSL_ST_HANDSHAKE 1
|
||||
#define SSL_ST_SENT_CHANGE_CIPHER_SPEC 2
|
||||
|
||||
#include "ssldecode.h"
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
788
ssl/ssl_rec.c
788
ssl/ssl_rec.c
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,8 +44,6 @@
|
|||
ekr@rtfm.com Wed Aug 18 15:46:57 1999
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "network.h"
|
||||
#include "ssl_h.h"
|
||||
#include "sslprint.h"
|
||||
|
@ -58,460 +57,453 @@
|
|||
#include "ssldecode.h"
|
||||
#include "ssl_rec.h"
|
||||
|
||||
|
||||
struct ssl_rec_decoder_ {
|
||||
SSL_CipherSuite *cs;
|
||||
Data *mac_key;
|
||||
Data *implicit_iv; /* for AEAD ciphers */
|
||||
Data *write_key; /* for AEAD ciphers */
|
||||
#ifdef OPENSSL
|
||||
EVP_CIPHER_CTX *evp;
|
||||
#endif
|
||||
UINT8 seq;
|
||||
};
|
||||
|
||||
char *digests[]={
|
||||
"MD5",
|
||||
"SHA1",
|
||||
"SHA224",
|
||||
"SHA256",
|
||||
"SHA384",
|
||||
"SHA512",
|
||||
NULL
|
||||
};
|
||||
|
||||
char *ciphers[]={
|
||||
"DES",
|
||||
"3DES",
|
||||
"RC4",
|
||||
"RC2",
|
||||
"IDEA",
|
||||
"AES128",
|
||||
"AES256",
|
||||
"CAMELLIA128",
|
||||
"CAMELLIA256",
|
||||
"SEED",
|
||||
NULL,
|
||||
"aes-128-gcm",
|
||||
"aes-256-gcm",
|
||||
"ChaCha20-Poly1305",
|
||||
"aes-128-ccm",
|
||||
"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));
|
||||
|
||||
int
|
||||
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;
|
||||
SSL_CipherSuite *cs;
|
||||
Data *mac_key;
|
||||
Data *implicit_iv; /* for AEAD ciphers */
|
||||
Data *write_key; /* for AEAD ciphers */
|
||||
#ifdef OPENSSL
|
||||
const EVP_CIPHER *ciph=0;
|
||||
int iv_len = ssl->version == TLSV13_VERSION?12:ssl->cs->block;
|
||||
|
||||
/* Find the SSLeay cipher */
|
||||
if(ssl->cs->enc!=ENC_NULL){
|
||||
ciph=(EVP_CIPHER *)EVP_get_cipherbyname(ciphers[ssl->cs->enc-0x30]);
|
||||
if(!ciph)
|
||||
ABORT(R_INTERNAL);
|
||||
}
|
||||
else {
|
||||
ciph=EVP_enc_null();
|
||||
}
|
||||
|
||||
if(!(dec=(ssl_rec_decoder *)calloc(1,sizeof(ssl_rec_decoder))))
|
||||
ABORT(R_NO_MEMORY);
|
||||
|
||||
dec->cs=ssl->cs;
|
||||
|
||||
if((r=r_data_alloc(&dec->mac_key,ssl->cs->dig_len)))
|
||||
ABORT(r);
|
||||
|
||||
if((r=r_data_alloc(&dec->implicit_iv,iv_len)))
|
||||
ABORT(r);
|
||||
memcpy(dec->implicit_iv->data,iv, iv_len);
|
||||
|
||||
if((r=r_data_create(&dec->write_key,sk,ssl->cs->eff_bits/8)))
|
||||
ABORT(r);
|
||||
|
||||
/*
|
||||
This is necessary for AEAD ciphers, because we must wait to fully initialize the cipher
|
||||
in order to include the implicit IV
|
||||
*/
|
||||
if(IS_AEAD_CIPHER(ssl->cs)){
|
||||
sk=NULL;
|
||||
iv=NULL;
|
||||
}
|
||||
else
|
||||
memcpy(dec->mac_key->data,mk,ssl->cs->dig_len);
|
||||
|
||||
if(!(dec->evp=EVP_CIPHER_CTX_new()))
|
||||
ABORT(R_NO_MEMORY);
|
||||
EVP_CIPHER_CTX_init(dec->evp);
|
||||
EVP_CipherInit(dec->evp,ciph,sk,iv,0);
|
||||
EVP_CIPHER_CTX *evp;
|
||||
#endif
|
||||
|
||||
*dp=dec;
|
||||
_status=0;
|
||||
abort:
|
||||
if(_status){
|
||||
ssl_destroy_rec_decoder(&dec);
|
||||
}
|
||||
return(_status);
|
||||
UINT8 seq;
|
||||
};
|
||||
|
||||
char *digests[] = {"MD5", "SHA1", "SHA224", "SHA256", "SHA384", "SHA512", NULL};
|
||||
|
||||
char *ciphers[] = {
|
||||
"DES", "3DES",
|
||||
"RC4", "RC2",
|
||||
"IDEA", "AES128",
|
||||
"AES256", "CAMELLIA128",
|
||||
"CAMELLIA256", "SEED",
|
||||
NULL, "aes-128-gcm",
|
||||
"aes-256-gcm", "ChaCha20-Poly1305",
|
||||
"aes-128-ccm",
|
||||
"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));
|
||||
|
||||
int 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;
|
||||
#ifdef OPENSSL
|
||||
const EVP_CIPHER *ciph = 0;
|
||||
int iv_len = ssl->version == TLSV13_VERSION ? 12 : ssl->cs->block;
|
||||
|
||||
/* Find the SSLeay cipher */
|
||||
if(ssl->cs->enc != ENC_NULL) {
|
||||
ciph = (EVP_CIPHER *)EVP_get_cipherbyname(ciphers[ssl->cs->enc - 0x30]);
|
||||
if(!ciph)
|
||||
ABORT(R_INTERNAL);
|
||||
} else {
|
||||
ciph = EVP_enc_null();
|
||||
}
|
||||
|
||||
int
|
||||
ssl_destroy_rec_decoder (ssl_rec_decoder **dp)
|
||||
{
|
||||
ssl_rec_decoder *d;
|
||||
|
||||
if(!dp || !*dp)
|
||||
return(0);
|
||||
d=*dp;
|
||||
if(!(dec = (ssl_rec_decoder *)calloc(1, sizeof(ssl_rec_decoder))))
|
||||
ABORT(R_NO_MEMORY);
|
||||
|
||||
r_data_destroy(&d->mac_key);
|
||||
r_data_destroy(&d->implicit_iv);
|
||||
r_data_destroy(&d->write_key);
|
||||
#ifdef OPENSSL
|
||||
if(d->evp){
|
||||
EVP_CIPHER_CTX_free(d->evp);
|
||||
}
|
||||
free(*dp);
|
||||
#endif
|
||||
dec->cs = ssl->cs;
|
||||
|
||||
*dp=0;
|
||||
return(0);
|
||||
if((r = r_data_alloc(&dec->mac_key, ssl->cs->dig_len)))
|
||||
ABORT(r);
|
||||
|
||||
if((r = r_data_alloc(&dec->implicit_iv, iv_len)))
|
||||
ABORT(r);
|
||||
memcpy(dec->implicit_iv->data, iv, iv_len);
|
||||
|
||||
if((r = r_data_create(&dec->write_key, sk, ssl->cs->eff_bits / 8)))
|
||||
ABORT(r);
|
||||
|
||||
/*
|
||||
This is necessary for AEAD ciphers, because we must wait to fully
|
||||
initialize the cipher in order to include the implicit IV
|
||||
*/
|
||||
if(IS_AEAD_CIPHER(ssl->cs)) {
|
||||
sk = NULL;
|
||||
iv = NULL;
|
||||
} else
|
||||
memcpy(dec->mac_key->data, mk, ssl->cs->dig_len);
|
||||
|
||||
if(!(dec->evp = EVP_CIPHER_CTX_new()))
|
||||
ABORT(R_NO_MEMORY);
|
||||
EVP_CIPHER_CTX_init(dec->evp);
|
||||
EVP_CipherInit(dec->evp, ciph, sk, iv, 0);
|
||||
#endif
|
||||
|
||||
*dp = dec;
|
||||
_status = 0;
|
||||
abort:
|
||||
if(_status) {
|
||||
ssl_destroy_rec_decoder(&dec);
|
||||
}
|
||||
|
||||
|
||||
#define MSB(a) ((a>>8)&0xff)
|
||||
#define LSB(a) (a&0xff)
|
||||
|
||||
int
|
||||
tls13_update_rec_key (ssl_rec_decoder *d, UCHAR *newkey, UCHAR *newiv)
|
||||
{
|
||||
d->write_key->data = newkey;
|
||||
d->implicit_iv->data = newiv;
|
||||
d->seq = 0;
|
||||
return (_status);
|
||||
}
|
||||
|
||||
int
|
||||
tls13_decode_rec_data (ssl_obj *ssl, ssl_rec_decoder *d, int ct, int version, UCHAR *in, int inl, UCHAR *out, int *outl)
|
||||
{
|
||||
int pad,i;
|
||||
int r,encpadl,x,_status=0;
|
||||
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");
|
||||
ABORT(-1);
|
||||
}
|
||||
memcpy(aead_nonce, d->implicit_iv->data, 12);
|
||||
for (i = 0; i < 8; i++) { // AEAD NONCE according to RFC TLS1.3
|
||||
aead_nonce[12 - 1 - i] ^= ((d->seq >> (i * 8)) & 0xFF);
|
||||
}
|
||||
d->seq++;
|
||||
CRDUMP("NONCE",aead_nonce,12);
|
||||
tag = in+(inl-taglen);
|
||||
CRDUMP("Tag", tag, taglen);
|
||||
int ssl_destroy_rec_decoder(ssl_rec_decoder **dp) {
|
||||
ssl_rec_decoder *d;
|
||||
|
||||
aad[0] = ct;
|
||||
aad[1] = 0x03;
|
||||
aad[2] = 0x03;
|
||||
aad[3] = MSB(inl);
|
||||
aad[4] = LSB(inl);
|
||||
CRDUMP("AAD",aad,5);
|
||||
inl-=taglen;
|
||||
if(!dp || !*dp)
|
||||
return (0);
|
||||
d = *dp;
|
||||
|
||||
if (!EVP_CIPHER_CTX_ctrl(d->evp, EVP_CTRL_AEAD_SET_IVLEN, 12, NULL)) {
|
||||
fprintf(stderr, "Unable to set ivlen\n");
|
||||
ABORT(-1);
|
||||
}
|
||||
r_data_destroy(&d->mac_key);
|
||||
r_data_destroy(&d->implicit_iv);
|
||||
r_data_destroy(&d->write_key);
|
||||
#ifdef OPENSSL
|
||||
if(d->evp) {
|
||||
EVP_CIPHER_CTX_free(d->evp);
|
||||
}
|
||||
free(*dp);
|
||||
#endif
|
||||
|
||||
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");
|
||||
ABORT(-1);
|
||||
}
|
||||
*dp = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
if(!EVP_DecryptInit_ex(d->evp,NULL,NULL,d->write_key->data,aead_nonce)){
|
||||
fprintf(stderr,"Unable to init evp1\n");
|
||||
ABORT(-1);
|
||||
}
|
||||
#define MSB(a) ((a >> 8) & 0xff)
|
||||
#define LSB(a) (a & 0xff)
|
||||
|
||||
if (IS_CCM_CIPHER(d->cs) && !EVP_DecryptUpdate(d->evp,NULL,outl,NULL,inl)){
|
||||
fprintf(stderr,"Unable to update data length\n");
|
||||
ABORT(-1);
|
||||
}
|
||||
int tls13_update_rec_key(ssl_rec_decoder *d, UCHAR *newkey, UCHAR *newiv) {
|
||||
d->write_key->data = newkey;
|
||||
d->implicit_iv->data = newiv;
|
||||
d->seq = 0;
|
||||
}
|
||||
|
||||
if (!EVP_DecryptUpdate(d->evp,NULL,outl,aad,5)){
|
||||
fprintf(stderr,"Unable to update aad\n");
|
||||
ABORT(-1);
|
||||
}
|
||||
int tls13_decode_rec_data(ssl_obj *ssl,
|
||||
ssl_rec_decoder *d,
|
||||
int ct,
|
||||
int version,
|
||||
UCHAR *in,
|
||||
int inl,
|
||||
UCHAR *out,
|
||||
int *outl) {
|
||||
int pad, i;
|
||||
int r, encpadl, x, _status = 0;
|
||||
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");
|
||||
ABORT(-1);
|
||||
}
|
||||
memcpy(aead_nonce, d->implicit_iv->data, 12);
|
||||
for(i = 0; i < 8; i++) { // AEAD NONCE according to RFC TLS1.3
|
||||
aead_nonce[12 - 1 - i] ^= ((d->seq >> (i * 8)) & 0xFF);
|
||||
}
|
||||
d->seq++;
|
||||
CRDUMP("NONCE", aead_nonce, 12);
|
||||
tag = in + (inl - taglen);
|
||||
CRDUMP("Tag", tag, taglen);
|
||||
|
||||
CRDUMP("Real CipherText", in, inl);
|
||||
if (!EVP_DecryptUpdate(d->evp,out,outl,in,inl)){
|
||||
fprintf(stderr,"Unable to update with CipherText\n");
|
||||
ABORT(-1);
|
||||
}
|
||||
aad[0] = ct;
|
||||
aad[1] = 0x03;
|
||||
aad[2] = 0x03;
|
||||
aad[3] = MSB(inl);
|
||||
aad[4] = LSB(inl);
|
||||
CRDUMP("AAD", aad, 5);
|
||||
inl -= taglen;
|
||||
|
||||
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))) {
|
||||
fprintf(stderr,"BAD MAC\n");
|
||||
ABORT(SSL_BAD_MAC);
|
||||
}
|
||||
if(!EVP_CIPHER_CTX_ctrl(d->evp, EVP_CTRL_AEAD_SET_IVLEN, 12, NULL)) {
|
||||
fprintf(stderr, "Unable to set ivlen\n");
|
||||
ABORT(-1);
|
||||
}
|
||||
|
||||
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");
|
||||
ABORT(-1);
|
||||
}
|
||||
|
||||
if(!EVP_DecryptInit_ex(d->evp, NULL, NULL, d->write_key->data, aead_nonce)) {
|
||||
fprintf(stderr, "Unable to init evp1\n");
|
||||
ABORT(-1);
|
||||
}
|
||||
|
||||
if(IS_CCM_CIPHER(d->cs) &&
|
||||
!EVP_DecryptUpdate(d->evp, NULL, outl, NULL, inl)) {
|
||||
fprintf(stderr, "Unable to update data length\n");
|
||||
ABORT(-1);
|
||||
}
|
||||
|
||||
if(!EVP_DecryptUpdate(d->evp, NULL, outl, aad, 5)) {
|
||||
fprintf(stderr, "Unable to update aad\n");
|
||||
ABORT(-1);
|
||||
}
|
||||
|
||||
CRDUMP("Real CipherText", in, inl);
|
||||
if(!EVP_DecryptUpdate(d->evp, out, outl, in, inl)) {
|
||||
fprintf(stderr, "Unable to update with CipherText\n");
|
||||
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))) {
|
||||
fprintf(stderr, "BAD MAC\n");
|
||||
ABORT(SSL_BAD_MAC);
|
||||
}
|
||||
|
||||
abort:
|
||||
ERR_print_errors_fp(stderr);
|
||||
return _status;
|
||||
ERR_print_errors_fp(stderr);
|
||||
return _status;
|
||||
}
|
||||
|
||||
int
|
||||
ssl_decode_rec_data (ssl_obj *ssl, ssl_rec_decoder *d, int ct, int version, UCHAR *in, int inl, UCHAR *out, int *outl)
|
||||
{
|
||||
int ssl_decode_rec_data(ssl_obj *ssl,
|
||||
ssl_rec_decoder *d,
|
||||
int ct,
|
||||
int version,
|
||||
UCHAR *in,
|
||||
int inl,
|
||||
UCHAR *out,
|
||||
int *outl) {
|
||||
#ifdef OPENSSL
|
||||
int pad;
|
||||
int r,encpadl,x;
|
||||
UCHAR *mac,aead_tag[13],aead_nonce[12];
|
||||
|
||||
CRDUMP("Ciphertext",in,inl);
|
||||
if(IS_AEAD_CIPHER(d->cs)){
|
||||
memcpy(aead_nonce,d->implicit_iv->data,d->implicit_iv->len);
|
||||
memcpy(aead_nonce+d->implicit_iv->len,in,12-d->implicit_iv->len);
|
||||
in+=12-d->implicit_iv->len;
|
||||
inl-=12-d->implicit_iv->len;
|
||||
int pad;
|
||||
int r, encpadl, x;
|
||||
UCHAR *mac, aead_tag[13], aead_nonce[12];
|
||||
|
||||
EVP_DecryptInit(d->evp,
|
||||
NULL,
|
||||
d->write_key->data,
|
||||
aead_nonce);
|
||||
CRDUMP("Ciphertext", in, inl);
|
||||
if(IS_AEAD_CIPHER(d->cs)) {
|
||||
memcpy(aead_nonce, d->implicit_iv->data, d->implicit_iv->len);
|
||||
memcpy(aead_nonce + d->implicit_iv->len, in, 12 - d->implicit_iv->len);
|
||||
in += 12 - d->implicit_iv->len;
|
||||
inl -= 12 - d->implicit_iv->len;
|
||||
|
||||
/*
|
||||
Then tag is always 16 bytes, as per:
|
||||
https://tools.ietf.org/html/rfc5116#section-5.2
|
||||
*/
|
||||
EVP_CIPHER_CTX_ctrl(d->evp,EVP_CTRL_GCM_SET_TAG,16,in+(inl-16));
|
||||
inl-=16;
|
||||
|
||||
fmt_seq(d->seq,aead_tag);
|
||||
d->seq++;
|
||||
aead_tag[8]=ct;
|
||||
aead_tag[9]=MSB(version);
|
||||
aead_tag[10]=LSB(version);
|
||||
aead_tag[11]=MSB(inl);
|
||||
aead_tag[12]=LSB(inl);
|
||||
|
||||
EVP_DecryptUpdate(d->evp,NULL,outl,aead_tag,13);
|
||||
EVP_DecryptUpdate(d->evp,out,outl,in,inl);
|
||||
|
||||
if (!(x=EVP_DecryptFinal(d->evp,NULL,&x)))
|
||||
ERETURN(SSL_BAD_MAC);
|
||||
}
|
||||
EVP_DecryptInit(d->evp, NULL, d->write_key->data, aead_nonce);
|
||||
|
||||
/*
|
||||
Encrypt-then-MAC is not used with AEAD ciphers, as per:
|
||||
https://tools.ietf.org/html/rfc7366#section-3
|
||||
Then tag is always 16 bytes, as per:
|
||||
https://tools.ietf.org/html/rfc5116#section-5.2
|
||||
*/
|
||||
else if(ssl->extensions->encrypt_then_mac==2){
|
||||
*outl=inl;
|
||||
EVP_CIPHER_CTX_ctrl(d->evp, EVP_CTRL_GCM_SET_TAG, 16, in + (inl - 16));
|
||||
inl -= 16;
|
||||
|
||||
/* First strip off the MAC */
|
||||
*outl-=d->cs->dig_len;
|
||||
mac=in+(*outl);
|
||||
fmt_seq(d->seq, aead_tag);
|
||||
d->seq++;
|
||||
aead_tag[8] = ct;
|
||||
aead_tag[9] = MSB(version);
|
||||
aead_tag[10] = LSB(version);
|
||||
aead_tag[11] = MSB(inl);
|
||||
aead_tag[12] = LSB(inl);
|
||||
|
||||
encpadl=*outl;
|
||||
/* Now decrypt */
|
||||
EVP_Cipher(d->evp,out,in,*outl);
|
||||
CRDUMP("Plaintext",out,*outl);
|
||||
EVP_DecryptUpdate(d->evp, NULL, outl, aead_tag, 13);
|
||||
EVP_DecryptUpdate(d->evp, out, outl, in, inl);
|
||||
|
||||
/* And then strip off the padding*/
|
||||
if(d->cs->block>1){
|
||||
pad=out[*outl-1];
|
||||
*outl-=(pad+1);
|
||||
if(!(x = EVP_DecryptFinal(d->evp, NULL, &x)))
|
||||
ERETURN(SSL_BAD_MAC);
|
||||
}
|
||||
|
||||
/*
|
||||
Encrypt-then-MAC is not used with AEAD ciphers, as per:
|
||||
https://tools.ietf.org/html/rfc7366#section-3
|
||||
*/
|
||||
else if(ssl->extensions->encrypt_then_mac == 2) {
|
||||
*outl = inl;
|
||||
|
||||
/* First strip off the MAC */
|
||||
*outl -= d->cs->dig_len;
|
||||
mac = in + (*outl);
|
||||
|
||||
encpadl = *outl;
|
||||
/* Now decrypt */
|
||||
EVP_Cipher(d->evp, out, in, *outl);
|
||||
CRDUMP("Plaintext", out, *outl);
|
||||
|
||||
/* And then strip off the padding*/
|
||||
if(d->cs->block > 1) {
|
||||
pad = out[*outl - 1];
|
||||
*outl -= (pad + 1);
|
||||
}
|
||||
/* TLS 1.1 and beyond: remove explicit IV, only used with
|
||||
* non-stream ciphers. */
|
||||
if(ssl->version >= 0x0302 && ssl->cs->block > 1) {
|
||||
UINT4 blk = ssl->cs->block;
|
||||
if(blk <= *outl) {
|
||||
*outl -= blk;
|
||||
memmove(out, out + blk, *outl);
|
||||
} else {
|
||||
DBG((0, "Block size greater than Plaintext!"));
|
||||
ERETURN(SSL_BAD_MAC);
|
||||
}
|
||||
|
||||
if((r = tls_check_mac(d, ct, version, in + blk, encpadl, in, blk, mac)))
|
||||
ERETURN(r);
|
||||
|
||||
} else if((r = tls_check_mac(d, ct, version, in, encpadl, NULL, 0, mac)))
|
||||
ERETURN(r);
|
||||
|
||||
} else {
|
||||
/* First decrypt*/
|
||||
EVP_Cipher(d->evp, out, in, inl);
|
||||
|
||||
CRDUMP("Plaintext", out, inl);
|
||||
*outl = inl;
|
||||
|
||||
/* Now strip off the padding*/
|
||||
if(d->cs->block > 1) {
|
||||
pad = out[inl - 1];
|
||||
*outl -= (pad + 1);
|
||||
}
|
||||
|
||||
/* And the MAC */
|
||||
*outl -= d->cs->dig_len;
|
||||
mac = out + (*outl);
|
||||
CRDUMP("Record data", out, *outl);
|
||||
|
||||
/* Now check the MAC */
|
||||
if(ssl->version == 0x300) {
|
||||
if((r = ssl3_check_mac(d, ct, version, out, *outl, mac)))
|
||||
ERETURN(r);
|
||||
} else {
|
||||
/* TLS 1.1 and beyond: remove explicit IV, only used with
|
||||
* non-stream ciphers. */
|
||||
if (ssl->version>=0x0302 && ssl->cs->block > 1) {
|
||||
UINT4 blk = ssl->cs->block;
|
||||
if (blk <= *outl) {
|
||||
*outl-=blk;
|
||||
memmove(out, out+blk, *outl);
|
||||
}
|
||||
else {
|
||||
DBG((0,"Block size greater than Plaintext!"));
|
||||
ERETURN(SSL_BAD_MAC);
|
||||
}
|
||||
|
||||
if((r=tls_check_mac(d,ct,version,in+blk,encpadl,in,blk,mac)))
|
||||
ERETURN(r);
|
||||
|
||||
if(ssl->version >= 0x0302 && ssl->cs->block > 1) {
|
||||
UINT4 blk = ssl->cs->block;
|
||||
if(blk <= *outl) {
|
||||
*outl -= blk;
|
||||
memmove(out, out + blk, *outl);
|
||||
} else {
|
||||
DBG((0, "Block size greater than Plaintext!"));
|
||||
ERETURN(SSL_BAD_MAC);
|
||||
}
|
||||
}
|
||||
else
|
||||
if((r=tls_check_mac(d,ct,version,in,encpadl,NULL,0,mac)))
|
||||
ERETURN(r);
|
||||
|
||||
if((r = tls_check_mac(d, ct, version, out, *outl, NULL, 0, mac)))
|
||||
ERETURN(r);
|
||||
}
|
||||
else {
|
||||
/* First decrypt*/
|
||||
EVP_Cipher(d->evp,out,in,inl);
|
||||
|
||||
CRDUMP("Plaintext",out,inl);
|
||||
*outl=inl;
|
||||
|
||||
/* Now strip off the padding*/
|
||||
if(d->cs->block>1){
|
||||
pad=out[inl-1];
|
||||
*outl-=(pad+1);
|
||||
}
|
||||
|
||||
/* And the MAC */
|
||||
*outl-=d->cs->dig_len;
|
||||
mac=out+(*outl);
|
||||
CRDUMP("Record data",out,*outl);
|
||||
|
||||
/* Now check the MAC */
|
||||
if(ssl->version==0x300){
|
||||
if((r=ssl3_check_mac(d,ct,version,out,*outl,mac)))
|
||||
ERETURN(r);
|
||||
}
|
||||
else{
|
||||
/* TLS 1.1 and beyond: remove explicit IV, only used with
|
||||
* non-stream ciphers. */
|
||||
if (ssl->version>=0x0302 && ssl->cs->block > 1) {
|
||||
UINT4 blk = ssl->cs->block;
|
||||
if (blk <= *outl) {
|
||||
*outl-=blk;
|
||||
memmove(out, out+blk, *outl);
|
||||
}
|
||||
else {
|
||||
DBG((0,"Block size greater than Plaintext!"));
|
||||
ERETURN(SSL_BAD_MAC);
|
||||
}
|
||||
}
|
||||
if((r=tls_check_mac(d,ct,version,out,*outl,NULL,0,mac)))
|
||||
ERETURN(r);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return(0);
|
||||
}
|
||||
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef OPENSSL
|
||||
|
||||
/* This should go to 2^128, but we're never really going to see
|
||||
more than 2^64, so we cheat*/
|
||||
static int
|
||||
fmt_seq (UINT4 num, UCHAR *buf)
|
||||
{
|
||||
UINT4 netnum;
|
||||
|
||||
memset(buf,0,8);
|
||||
netnum=htonl(num);
|
||||
memcpy(buf+4,&netnum,4);
|
||||
static int fmt_seq(UINT4 num, UCHAR *buf) {
|
||||
UINT4 netnum;
|
||||
|
||||
return(0);
|
||||
}
|
||||
memset(buf, 0, 8);
|
||||
netnum = htonl(num);
|
||||
memcpy(buf + 4, &netnum, 4);
|
||||
|
||||
static int
|
||||
tls_check_mac (ssl_rec_decoder *d, int ct, int ver, UCHAR *data, UINT4 datalen, UCHAR *iv, UINT4 ivlen, UCHAR *mac)
|
||||
{
|
||||
HMAC_CTX *hm = HMAC_CTX_new();
|
||||
if(!hm)
|
||||
ERETURN(R_NO_MEMORY);
|
||||
const EVP_MD *md;
|
||||
UINT4 l;
|
||||
UCHAR buf[128];
|
||||
|
||||
md=EVP_get_digestbyname(digests[d->cs->dig-0x40]);
|
||||
HMAC_Init_ex(hm,d->mac_key->data,d->mac_key->len,md,NULL);
|
||||
return (0);
|
||||
}
|
||||
|
||||
fmt_seq(d->seq,buf);
|
||||
d->seq++;
|
||||
HMAC_Update(hm,buf,8);
|
||||
buf[0]=ct;
|
||||
HMAC_Update(hm,buf,1);
|
||||
static int tls_check_mac(ssl_rec_decoder *d,
|
||||
int ct,
|
||||
int ver,
|
||||
UCHAR *data,
|
||||
UINT4 datalen,
|
||||
UCHAR *iv,
|
||||
UINT4 ivlen,
|
||||
UCHAR *mac) {
|
||||
HMAC_CTX *hm = HMAC_CTX_new();
|
||||
if(!hm)
|
||||
ERETURN(R_NO_MEMORY);
|
||||
const EVP_MD *md;
|
||||
UINT4 l;
|
||||
UCHAR buf[128];
|
||||
|
||||
buf[0]=MSB(ver);
|
||||
buf[1]=LSB(ver);
|
||||
HMAC_Update(hm,buf,2);
|
||||
md = EVP_get_digestbyname(digests[d->cs->dig - 0x40]);
|
||||
HMAC_Init_ex(hm, d->mac_key->data, d->mac_key->len, md, NULL);
|
||||
|
||||
buf[0]=MSB(datalen);
|
||||
buf[1]=LSB(datalen);
|
||||
HMAC_Update(hm,buf,2);
|
||||
fmt_seq(d->seq, buf);
|
||||
d->seq++;
|
||||
HMAC_Update(hm, buf, 8);
|
||||
buf[0] = ct;
|
||||
HMAC_Update(hm, buf, 1);
|
||||
|
||||
/* for encrypt-then-mac with an explicit IV */
|
||||
if(ivlen && iv){
|
||||
HMAC_Update(hm,iv,ivlen);
|
||||
HMAC_Update(hm,data,datalen-ivlen);
|
||||
}
|
||||
else
|
||||
HMAC_Update(hm,data,datalen);
|
||||
|
||||
HMAC_Final(hm,buf,&l);
|
||||
if(memcmp(mac,buf,l))
|
||||
ERETURN(SSL_BAD_MAC);
|
||||
buf[0] = MSB(ver);
|
||||
buf[1] = LSB(ver);
|
||||
HMAC_Update(hm, buf, 2);
|
||||
|
||||
HMAC_CTX_free(hm);
|
||||
return(0);
|
||||
}
|
||||
buf[0] = MSB(datalen);
|
||||
buf[1] = LSB(datalen);
|
||||
HMAC_Update(hm, buf, 2);
|
||||
|
||||
int
|
||||
ssl3_check_mac (ssl_rec_decoder *d, int ct, int ver, UCHAR *data, UINT4 datalen, UCHAR *mac)
|
||||
{
|
||||
EVP_MD_CTX *mc = EVP_MD_CTX_new();
|
||||
const EVP_MD *md;
|
||||
UINT4 l;
|
||||
UCHAR buf[64],dgst[20];
|
||||
int pad_ct;
|
||||
/* for encrypt-then-mac with an explicit IV */
|
||||
if(ivlen && iv) {
|
||||
HMAC_Update(hm, iv, ivlen);
|
||||
HMAC_Update(hm, data, datalen - ivlen);
|
||||
} else
|
||||
HMAC_Update(hm, data, datalen);
|
||||
|
||||
pad_ct=(d->cs->dig==DIG_SHA)?40:48;
|
||||
|
||||
md=EVP_get_digestbyname(digests[d->cs->dig-0x40]);
|
||||
EVP_DigestInit(mc,md);
|
||||
HMAC_Final(hm, buf, &l);
|
||||
if(memcmp(mac, buf, l))
|
||||
ERETURN(SSL_BAD_MAC);
|
||||
|
||||
EVP_DigestUpdate(mc,d->mac_key->data,d->mac_key->len);
|
||||
HMAC_CTX_free(hm);
|
||||
return (0);
|
||||
}
|
||||
|
||||
memset(buf,0x36,pad_ct);
|
||||
EVP_DigestUpdate(mc,buf,pad_ct);
|
||||
int ssl3_check_mac(ssl_rec_decoder *d,
|
||||
int ct,
|
||||
int ver,
|
||||
UCHAR *data,
|
||||
UINT4 datalen,
|
||||
UCHAR *mac) {
|
||||
EVP_MD_CTX *mc = EVP_MD_CTX_new();
|
||||
const EVP_MD *md;
|
||||
UINT4 l;
|
||||
UCHAR buf[64], dgst[20];
|
||||
int pad_ct;
|
||||
|
||||
fmt_seq(d->seq,buf);
|
||||
d->seq++;
|
||||
EVP_DigestUpdate(mc,buf,8);
|
||||
pad_ct = (d->cs->dig == DIG_SHA) ? 40 : 48;
|
||||
|
||||
buf[0]=ct;
|
||||
EVP_DigestUpdate(mc,buf,1);
|
||||
|
||||
buf[0]=MSB(datalen);
|
||||
buf[1]=LSB(datalen);
|
||||
EVP_DigestUpdate(mc,buf,2);
|
||||
md = EVP_get_digestbyname(digests[d->cs->dig - 0x40]);
|
||||
EVP_DigestInit(mc, md);
|
||||
|
||||
EVP_DigestUpdate(mc,data,datalen);
|
||||
EVP_DigestUpdate(mc, d->mac_key->data, d->mac_key->len);
|
||||
|
||||
EVP_DigestFinal(mc,dgst,&l);
|
||||
|
||||
EVP_DigestInit(mc,md);
|
||||
memset(buf, 0x36, pad_ct);
|
||||
EVP_DigestUpdate(mc, buf, pad_ct);
|
||||
|
||||
EVP_DigestUpdate(mc,d->mac_key->data,d->mac_key->len);
|
||||
|
||||
memset(buf,0x5c,pad_ct);
|
||||
EVP_DigestUpdate(mc,buf,pad_ct);
|
||||
fmt_seq(d->seq, buf);
|
||||
d->seq++;
|
||||
EVP_DigestUpdate(mc, buf, 8);
|
||||
|
||||
EVP_DigestUpdate(mc,dgst,l);
|
||||
buf[0] = ct;
|
||||
EVP_DigestUpdate(mc, buf, 1);
|
||||
|
||||
EVP_DigestFinal(mc,dgst,&l);
|
||||
buf[0] = MSB(datalen);
|
||||
buf[1] = LSB(datalen);
|
||||
EVP_DigestUpdate(mc, buf, 2);
|
||||
|
||||
if(memcmp(mac,dgst,l))
|
||||
ERETURN(SSL_BAD_MAC);
|
||||
EVP_DigestUpdate(mc, data, datalen);
|
||||
|
||||
EVP_MD_CTX_free(mc);
|
||||
EVP_DigestFinal(mc, dgst, &l);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
#endif
|
||||
EVP_DigestInit(mc, md);
|
||||
|
||||
EVP_DigestUpdate(mc, d->mac_key->data, d->mac_key->len);
|
||||
|
||||
memset(buf, 0x5c, pad_ct);
|
||||
EVP_DigestUpdate(mc, buf, pad_ct);
|
||||
|
||||
EVP_DigestUpdate(mc, dgst, l);
|
||||
|
||||
EVP_DigestFinal(mc, dgst, &l);
|
||||
|
||||
if(memcmp(mac, dgst, l))
|
||||
ERETURN(SSL_BAD_MAC);
|
||||
|
||||
EVP_MD_CTX_free(mc);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,24 +44,43 @@
|
|||
ekr@rtfm.com Wed Aug 18 16:16:23 1999
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _ssl_rec_h
|
||||
#define _ssl_rec_h
|
||||
|
||||
typedef struct ssl_rec_decoder_ ssl_rec_decoder;
|
||||
|
||||
int ssl_destroy_rec_decoder PROTO_LIST((ssl_rec_decoder **dp));
|
||||
int ssl_create_rec_decoder PROTO_LIST((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 ct,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 ssl_destroy_rec_decoder PROTO_LIST((ssl_rec_decoder * *dp));
|
||||
int ssl_create_rec_decoder PROTO_LIST(
|
||||
(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 ct,
|
||||
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,
|
||||
UINT4 datalen, UCHAR *mac);
|
||||
int ssl3_check_mac(ssl_rec_decoder *d,
|
||||
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_CCM_CIPHER(cs) (cs->enc==0x3e||cs->enc==0x3f)
|
||||
#define IS_AEAD_CIPHER(cs) \
|
||||
(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
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,55 +44,52 @@
|
|||
ekr@rtfm.com Tue Mar 30 18:11:55 1999
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _sslciphers_h
|
||||
#define _sslciphers_h
|
||||
typedef struct SSL_CipherSuite_ {
|
||||
int number;
|
||||
int kex;
|
||||
int sig;
|
||||
int enc;
|
||||
int block;
|
||||
int bits;
|
||||
int eff_bits;
|
||||
int dig;
|
||||
int dig_len;
|
||||
int export;
|
||||
int number;
|
||||
int kex;
|
||||
int sig;
|
||||
int enc;
|
||||
int block;
|
||||
int bits;
|
||||
int eff_bits;
|
||||
int dig;
|
||||
int dig_len;
|
||||
int export;
|
||||
} SSL_CipherSuite;
|
||||
|
||||
#define KEX_RSA 0x10
|
||||
#define KEX_DH 0x11
|
||||
#define KEX_RSA 0x10
|
||||
#define KEX_DH 0x11
|
||||
|
||||
#define SIG_RSA 0x20
|
||||
#define SIG_DSS 0x21
|
||||
#define SIG_NONE 0x22
|
||||
#define SIG_RSA 0x20
|
||||
#define SIG_DSS 0x21
|
||||
#define SIG_NONE 0x22
|
||||
|
||||
#define ENC_DES 0x30
|
||||
#define ENC_3DES 0x31
|
||||
#define ENC_RC4 0x32
|
||||
#define ENC_RC2 0x33
|
||||
#define ENC_IDEA 0x34
|
||||
#define ENC_AES128 0x35
|
||||
#define ENC_AES256 0x36
|
||||
#define ENC_CAMELLIA128 0x37
|
||||
#define ENC_CAMELLIA256 0x38
|
||||
#define ENC_SEED 0x39
|
||||
#define ENC_NULL 0x3a
|
||||
#define ENC_AES128_GCM 0x3b
|
||||
#define ENC_AES256_GCM 0x3c
|
||||
#define ENC_CHACHA20_POLY1305 0x3d
|
||||
#define ENC_AES128_CCM 0x3e
|
||||
#define ENC_AES128_CCM_8 0x3f
|
||||
#define ENC_DES 0x30
|
||||
#define ENC_3DES 0x31
|
||||
#define ENC_RC4 0x32
|
||||
#define ENC_RC2 0x33
|
||||
#define ENC_IDEA 0x34
|
||||
#define ENC_AES128 0x35
|
||||
#define ENC_AES256 0x36
|
||||
#define ENC_CAMELLIA128 0x37
|
||||
#define ENC_CAMELLIA256 0x38
|
||||
#define ENC_SEED 0x39
|
||||
#define ENC_NULL 0x3a
|
||||
#define ENC_AES128_GCM 0x3b
|
||||
#define ENC_AES256_GCM 0x3c
|
||||
#define ENC_CHACHA20_POLY1305 0x3d
|
||||
#define ENC_AES128_CCM 0x3e
|
||||
#define ENC_AES128_CCM_8 0x3f
|
||||
|
||||
#define DIG_MD5 0x40
|
||||
#define DIG_SHA 0x41
|
||||
#define DIG_SHA224 0x42 /* Not sure why EKR didn't follow RFC for */
|
||||
#define DIG_SHA256 0x43 /* these values, but whatever, just adding on */
|
||||
#define DIG_SHA384 0x44
|
||||
#define DIG_SHA512 0x45
|
||||
|
||||
int ssl_find_cipher PROTO_LIST((int num,SSL_CipherSuite **cs));
|
||||
#define DIG_MD5 0x40
|
||||
#define DIG_SHA 0x41
|
||||
#define DIG_SHA224 0x42 /* Not sure why EKR didn't follow RFC for */
|
||||
#define DIG_SHA256 0x43 /* these values, but whatever, just adding on */
|
||||
#define DIG_SHA384 0x44
|
||||
#define DIG_SHA512 0x45
|
||||
|
||||
int ssl_find_cipher PROTO_LIST((int num, SSL_CipherSuite **cs));
|
||||
|
||||
#endif
|
||||
|
||||
|
|
2337
ssl/ssldecode.c
2337
ssl/ssldecode.c
File diff suppressed because it is too large
Load diff
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,40 +44,56 @@
|
|||
ekr@rtfm.com Thu Apr 1 15:02:02 1999
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _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 CRDUMPD(a,b) P_(P_CR) {exdump(ssl,a,b);LF;}
|
||||
#define CRDUMP(a, b, c) \
|
||||
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,
|
||||
char *keyfile,char *password,char *keylogfile));
|
||||
int ssl_decode_ctx_create PROTO_LIST(
|
||||
(ssl_decode_ctx * *ctx, char *keyfile, char *password, char *keylogfile));
|
||||
int ssl_decode_ctx_destroy(ssl_decode_ctx **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_set_client_random PROTO_LIST((ssl_decoder *dp,
|
||||
UCHAR *msg,int len));
|
||||
int ssl_set_server_random PROTO_LIST((ssl_decoder *dp,
|
||||
UCHAR *msg,int len));
|
||||
int ssl_set_client_session_id PROTO_LIST((ssl_decoder *dp,
|
||||
UCHAR *msg,int len));
|
||||
int ssl_process_server_session_id PROTO_LIST((ssl_obj *obj,ssl_decoder *dp,
|
||||
UCHAR *msg,int len));
|
||||
int ssl_process_client_session_id PROTO_LIST((ssl_obj *obj,ssl_decoder *dp,
|
||||
UCHAR *msg,int len));
|
||||
int ssl_process_client_key_exchange PROTO_LIST((struct ssl_obj_ *,
|
||||
ssl_decoder *d,UCHAR *msg,int len));
|
||||
int ssl_process_change_cipher_spec PROTO_LIST((ssl_obj *ssl,
|
||||
ssl_decoder *d,int direction));
|
||||
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));
|
||||
int ssl_tls13_update_keying_material PROTO_LIST((ssl_obj *ssl,ssl_decoder *dec,int dir));
|
||||
|
||||
int ssl_decoder_destroy PROTO_LIST((ssl_decoder * *dp));
|
||||
int ssl_decoder_create PROTO_LIST((ssl_decoder * *dp, ssl_decode_ctx *ctx));
|
||||
int ssl_set_client_random PROTO_LIST((ssl_decoder * dp, UCHAR *msg, int len));
|
||||
int ssl_set_server_random PROTO_LIST((ssl_decoder * dp, UCHAR *msg, int len));
|
||||
int ssl_set_client_session_id PROTO_LIST((ssl_decoder * dp,
|
||||
UCHAR *msg,
|
||||
int len));
|
||||
int ssl_process_server_session_id
|
||||
PROTO_LIST((ssl_obj * obj, ssl_decoder *dp, UCHAR *msg, int len));
|
||||
int ssl_process_client_session_id
|
||||
PROTO_LIST((ssl_obj * obj, ssl_decoder *dp, UCHAR *msg, int len));
|
||||
int ssl_process_client_key_exchange
|
||||
PROTO_LIST((struct ssl_obj_ *, ssl_decoder *d, UCHAR *msg, int len));
|
||||
int ssl_process_change_cipher_spec PROTO_LIST((ssl_obj * ssl,
|
||||
ssl_decoder *d,
|
||||
int direction));
|
||||
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));
|
||||
int ssl_tls13_update_keying_material PROTO_LIST((ssl_obj * ssl,
|
||||
ssl_decoder *dec,
|
||||
int dir));
|
||||
|
||||
#endif
|
||||
|
||||
|
|
1270
ssl/sslprint.c
1270
ssl/sslprint.c
File diff suppressed because it is too large
Load diff
145
ssl/sslprint.h
145
ssl/sslprint.h
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,66 +44,104 @@
|
|||
ekr@rtfm.com Wed Feb 10 15:34:14 1999
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _sslprint_h
|
||||
#define _sslprint_h
|
||||
|
||||
#include "ssl_analyze.h"
|
||||
#include "ssl_h.h"
|
||||
|
||||
int ssl_expand_record PROTO_LIST((ssl_obj *ssl,
|
||||
segment *q,int direction,UCHAR *data,int len));
|
||||
int ssl_decode_switch PROTO_LIST((ssl_obj *ssl,
|
||||
decoder *dtable,int value,int dir,segment *seg,Data *data));
|
||||
int ssl_decode_uintX PROTO_LIST((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));
|
||||
int ssl_lookup_enum PROTO_LIST((ssl_obj *ssl,decoder *dtable,
|
||||
UINT4 val,char **ptr));
|
||||
int ssl_print_enum PROTO_LIST((ssl_obj *obj,char *name,
|
||||
decoder *decode,UINT4 value));
|
||||
int ssl_get_enum_str PROTO_LIST((ssl_obj *obj,char *outstr,
|
||||
decoder *decode,UINT4 value));
|
||||
int print_data PROTO_LIST((ssl_obj *ssl,Data *d));
|
||||
int process_v2_hello PROTO_LIST((ssl_obj *ssl,segment *seg));
|
||||
int process_beginning_plaintext PROTO_LIST((ssl_obj *ssl,
|
||||
segment *seg,int direction));
|
||||
int ssl_print_direction_indicator PROTO_LIST((ssl_obj *ssl,int dir));
|
||||
int ssl_print_timestamp PROTO_LIST((ssl_obj *ssl,struct timeval *ts));
|
||||
int ssl_print_record_num PROTO_LIST((ssl_obj *ssl));
|
||||
int ssl_print_cipher_suite PROTO_LIST((ssl_obj *ssl,int version,int p,
|
||||
UINT4 val));
|
||||
int ssl_expand_record PROTO_LIST(
|
||||
(ssl_obj * ssl, segment *q, int direction, UCHAR *data, int len));
|
||||
int ssl_decode_switch PROTO_LIST((ssl_obj * ssl,
|
||||
decoder *dtable,
|
||||
int value,
|
||||
int dir,
|
||||
segment *seg,
|
||||
Data *data));
|
||||
int ssl_decode_uintX PROTO_LIST(
|
||||
(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));
|
||||
int ssl_lookup_enum
|
||||
PROTO_LIST((ssl_obj * ssl, decoder *dtable, UINT4 val, char **ptr));
|
||||
int ssl_print_enum
|
||||
PROTO_LIST((ssl_obj * obj, char *name, decoder *decode, UINT4 value));
|
||||
int ssl_get_enum_str
|
||||
PROTO_LIST((ssl_obj * obj, char *outstr, decoder *decode, UINT4 value));
|
||||
int print_data PROTO_LIST((ssl_obj * ssl, Data *d));
|
||||
int process_v2_hello PROTO_LIST((ssl_obj * ssl, segment *seg));
|
||||
int process_beginning_plaintext PROTO_LIST((ssl_obj * ssl,
|
||||
segment *seg,
|
||||
int direction));
|
||||
int ssl_print_direction_indicator PROTO_LIST((ssl_obj * ssl, int dir));
|
||||
int ssl_print_timestamp PROTO_LIST((ssl_obj * ssl, struct timeval *ts));
|
||||
int ssl_print_record_num PROTO_LIST((ssl_obj * ssl));
|
||||
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 exdump PROTO_LIST((ssl_obj *ssl,char *name,Data *data));
|
||||
int exstr PROTO_LIST((ssl_obj *ssl,char *name,Data *data));
|
||||
int explain PROTO_LIST((ssl_obj * ssl, char *format, ...));
|
||||
int exdump 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 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 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 \
|
||||
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_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 LF if(!(NET_print_flags & NET_PRINT_JSON)) printf("\n")
|
||||
|
||||
#endif
|
||||
#define LF \
|
||||
if(!(NET_print_flags & NET_PRINT_JSON)) \
|
||||
printf("\n")
|
||||
|
||||
#endif
|
||||
|
|
350
ssl/sslxprint.c
350
ssl/sslxprint.c
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,7 +44,6 @@
|
|||
ekr@rtfm.com Thu Mar 25 21:17:16 1999
|
||||
*/
|
||||
|
||||
|
||||
#include <json.h>
|
||||
#include "network.h"
|
||||
#include "ssl_h.h"
|
||||
|
@ -57,201 +57,195 @@
|
|||
|
||||
#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
|
||||
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
|
||||
|
||||
int
|
||||
sslx_print_certificate (ssl_obj *ssl, Data *data, int pf)
|
||||
{
|
||||
#ifdef OPENSSL
|
||||
X509 *x=0;
|
||||
ASN1_INTEGER *a;
|
||||
#endif
|
||||
UCHAR *d;
|
||||
int _status;
|
||||
struct json_object *cert_obj;
|
||||
|
||||
#ifdef OPENSSL
|
||||
P_(P_ASN){
|
||||
char buf[BUFSIZE];
|
||||
int ext;
|
||||
char *b64_cert;
|
||||
|
||||
char *serial_str = NULL;
|
||||
Data data_tmp;
|
||||
|
||||
struct json_object *jobj;
|
||||
jobj = ssl->cur_json_st;
|
||||
|
||||
cert_obj = json_object_new_object();
|
||||
|
||||
d=data->data;
|
||||
|
||||
if(!(b64_cert=(char *)calloc(1,sizeof(char) * ((((data->len) + 3 - 1)/3) * 4 + 1))))
|
||||
ABORT(R_NO_MEMORY);
|
||||
|
||||
EVP_EncodeBlock((unsigned char *)b64_cert, d, data->len);
|
||||
json_object_object_add(cert_obj, "cert_der", json_object_new_string(b64_cert));
|
||||
free(b64_cert);
|
||||
|
||||
if(!(x=d2i_X509(0,(const unsigned char **) &d,data->len))){
|
||||
explain(ssl,"Bad certificate");
|
||||
ABORT(R_BAD_DATA);
|
||||
}
|
||||
X509_NAME_oneline(X509_get_subject_name(x),buf,
|
||||
BUFSIZE);
|
||||
explain(ssl,"Subject\n");
|
||||
INDENT_INCR;
|
||||
json_object_object_add(cert_obj, "cert_subject", json_object_new_string(buf));
|
||||
sslx__print_dn(ssl,buf);
|
||||
INDENT_POP;
|
||||
X509_NAME_oneline(X509_get_issuer_name(x),buf,
|
||||
BUFSIZE);
|
||||
explain(ssl,"Issuer\n");
|
||||
INDENT_INCR;
|
||||
json_object_object_add(cert_obj, "cert_issuer", json_object_new_string(buf));
|
||||
sslx__print_dn(ssl,buf);
|
||||
INDENT_POP;
|
||||
a=X509_get_serialNumber(x);
|
||||
explain(ssl,"Serial ");
|
||||
if(!(serial_str=(char *)calloc(1,sizeof(char) * (a->length * 3))))
|
||||
ABORT(R_NO_MEMORY);
|
||||
INIT_DATA(data_tmp,a->data,a->length);
|
||||
exstr(ssl, serial_str, &data_tmp);
|
||||
json_object_object_add(cert_obj, "cert_serial", json_object_new_string(serial_str));
|
||||
free(serial_str);
|
||||
sslx__print_serial(ssl,a);
|
||||
|
||||
ext=X509_get_ext_count(x);
|
||||
if(ext>0){
|
||||
int i,j;
|
||||
UCHAR buf[1024];
|
||||
|
||||
explain(ssl,"Extensions\n");
|
||||
INDENT_INCR;
|
||||
for(i=0;i<ext;i++){
|
||||
X509_EXTENSION *ex;
|
||||
ASN1_OBJECT *obj;
|
||||
|
||||
ex=X509_get_ext(x,i);
|
||||
obj=X509_EXTENSION_get_object(ex);
|
||||
i2t_ASN1_OBJECT((char *)buf,sizeof(buf),obj);
|
||||
|
||||
explain(ssl,"Extension: %s\n",buf);
|
||||
j=X509_EXTENSION_get_critical(ex);
|
||||
if(j){
|
||||
INDENT;
|
||||
explain(ssl,"Critical\n");
|
||||
}
|
||||
if(SSL_print_flags & SSL_PRINT_NROFF){
|
||||
if(ssl->process_ciphertext&ssl->direction)
|
||||
printf("\\f(CI");
|
||||
else
|
||||
printf("\\fC");
|
||||
|
||||
INDENT_INCR;
|
||||
INDENT;
|
||||
if(!X509V3_EXT_print_fp(stdout,ex,0,0)){
|
||||
printf("Hex value");
|
||||
}
|
||||
INDENT_POP;
|
||||
explain(ssl,"\n");
|
||||
}
|
||||
}
|
||||
INDENT_POP;
|
||||
|
||||
}
|
||||
else{
|
||||
int sslx_print_certificate(ssl_obj *ssl, Data *data, int pf) {
|
||||
#ifdef OPENSSL
|
||||
X509 *x = 0;
|
||||
ASN1_INTEGER *a;
|
||||
#endif
|
||||
P_(pf){
|
||||
exdump(ssl,"certificate",data);
|
||||
}
|
||||
#ifdef OPENSSL
|
||||
}
|
||||
UCHAR *d;
|
||||
int _status;
|
||||
struct json_object *cert_obj;
|
||||
|
||||
struct json_object *certs_array;
|
||||
json_object_object_get_ex(jobj, "cert_chain", &certs_array);
|
||||
json_object_array_add(certs_array,cert_obj);
|
||||
#ifdef OPENSSL
|
||||
P_(P_ASN) {
|
||||
char buf[BUFSIZE];
|
||||
int ext;
|
||||
char *b64_cert;
|
||||
|
||||
char *serial_str = NULL;
|
||||
Data data_tmp;
|
||||
|
||||
struct json_object *jobj;
|
||||
jobj = ssl->cur_json_st;
|
||||
|
||||
cert_obj = json_object_new_object();
|
||||
|
||||
d = data->data;
|
||||
|
||||
if(!(b64_cert = (char *)calloc(
|
||||
1, sizeof(char) * ((((data->len) + 3 - 1) / 3) * 4 + 1))))
|
||||
ABORT(R_NO_MEMORY);
|
||||
|
||||
EVP_EncodeBlock((unsigned char *)b64_cert, d, data->len);
|
||||
json_object_object_add(cert_obj, "cert_der",
|
||||
json_object_new_string(b64_cert));
|
||||
free(b64_cert);
|
||||
|
||||
if(!(x = d2i_X509(0, (const unsigned char **)&d, data->len))) {
|
||||
explain(ssl, "Bad certificate");
|
||||
ABORT(R_BAD_DATA);
|
||||
}
|
||||
#endif
|
||||
X509_NAME_oneline(X509_get_subject_name(x), buf, BUFSIZE);
|
||||
explain(ssl, "Subject\n");
|
||||
INDENT_INCR;
|
||||
json_object_object_add(cert_obj, "cert_subject",
|
||||
json_object_new_string(buf));
|
||||
sslx__print_dn(ssl, buf);
|
||||
INDENT_POP;
|
||||
X509_NAME_oneline(X509_get_issuer_name(x), buf, BUFSIZE);
|
||||
explain(ssl, "Issuer\n");
|
||||
INDENT_INCR;
|
||||
json_object_object_add(cert_obj, "cert_issuer",
|
||||
json_object_new_string(buf));
|
||||
sslx__print_dn(ssl, buf);
|
||||
INDENT_POP;
|
||||
a = X509_get_serialNumber(x);
|
||||
explain(ssl, "Serial ");
|
||||
if(!(serial_str = (char *)calloc(1, sizeof(char) * (a->length * 3))))
|
||||
ABORT(R_NO_MEMORY);
|
||||
INIT_DATA(data_tmp, a->data, a->length);
|
||||
exstr(ssl, serial_str, &data_tmp);
|
||||
json_object_object_add(cert_obj, "cert_serial",
|
||||
json_object_new_string(serial_str));
|
||||
free(serial_str);
|
||||
sslx__print_serial(ssl, a);
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
#ifdef OPENSSL
|
||||
if(x) X509_free(x);
|
||||
#endif
|
||||
if(_status && cert_obj) json_object_put(cert_obj);
|
||||
return(_status);
|
||||
}
|
||||
ext = X509_get_ext_count(x);
|
||||
if(ext > 0) {
|
||||
int i, j;
|
||||
UCHAR buf[1024];
|
||||
|
||||
int
|
||||
sslx_print_dn (ssl_obj *ssl, Data *data, int pf)
|
||||
{
|
||||
UCHAR buf[BUFSIZE];
|
||||
int _status;
|
||||
UCHAR *d=data->data;
|
||||
#ifdef OPENSSL
|
||||
X509_NAME *n=0;
|
||||
#endif
|
||||
|
||||
P_(pf){
|
||||
#ifdef OPENSSL
|
||||
P_(P_ASN){
|
||||
if(!(n=d2i_X509_NAME(0,(const unsigned char **) &d,data->len)))
|
||||
ABORT(R_BAD_DATA);
|
||||
X509_NAME_oneline(n,(char *)buf,BUFSIZE);
|
||||
sslx__print_dn(ssl,(char *)buf);
|
||||
}
|
||||
else{
|
||||
#endif
|
||||
exdump(ssl,0,data);
|
||||
#ifdef OPENSSL
|
||||
explain(ssl, "Extensions\n");
|
||||
INDENT_INCR;
|
||||
for(i = 0; i < ext; i++) {
|
||||
X509_EXTENSION *ex;
|
||||
ASN1_OBJECT *obj;
|
||||
|
||||
ex = X509_get_ext(x, i);
|
||||
obj = X509_EXTENSION_get_object(ex);
|
||||
i2t_ASN1_OBJECT((char *)buf, sizeof(buf), obj);
|
||||
|
||||
explain(ssl, "Extension: %s\n", buf);
|
||||
j = X509_EXTENSION_get_critical(ex);
|
||||
if(j) {
|
||||
INDENT;
|
||||
explain(ssl, "Critical\n");
|
||||
}
|
||||
if(SSL_print_flags & SSL_PRINT_NROFF) {
|
||||
if(ssl->process_ciphertext & ssl->direction)
|
||||
printf("\\f(CI");
|
||||
else
|
||||
printf("\\fC");
|
||||
|
||||
INDENT_INCR;
|
||||
INDENT;
|
||||
if(!X509V3_EXT_print_fp(stdout, ex, 0, 0)) {
|
||||
printf("Hex value");
|
||||
}
|
||||
INDENT_POP;
|
||||
explain(ssl, "\n");
|
||||
}
|
||||
}
|
||||
INDENT_POP;
|
||||
|
||||
} else {
|
||||
#endif
|
||||
P_(pf) { exdump(ssl, "certificate", data); }
|
||||
#ifdef OPENSSL
|
||||
}
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
#ifdef OPENSSL
|
||||
struct json_object *certs_array;
|
||||
json_object_object_get_ex(jobj, "cert_chain", &certs_array);
|
||||
json_object_array_add(certs_array, cert_obj);
|
||||
}
|
||||
#endif
|
||||
|
||||
_status = 0;
|
||||
abort:
|
||||
#ifdef OPENSSL
|
||||
if(x)
|
||||
X509_free(x);
|
||||
#endif
|
||||
if(_status && cert_obj)
|
||||
json_object_put(cert_obj);
|
||||
return (_status);
|
||||
}
|
||||
|
||||
int sslx_print_dn(ssl_obj *ssl, Data *data, int pf) {
|
||||
UCHAR buf[BUFSIZE];
|
||||
int _status;
|
||||
UCHAR *d = data->data;
|
||||
#ifdef OPENSSL
|
||||
X509_NAME *n = 0;
|
||||
#endif
|
||||
|
||||
P_(pf){
|
||||
#ifdef OPENSSL
|
||||
P_(P_ASN){if(!(n = d2i_X509_NAME(0, (const unsigned char **)&d,
|
||||
data->len))) ABORT(R_BAD_DATA);
|
||||
X509_NAME_oneline(n, (char *)buf, BUFSIZE);
|
||||
sslx__print_dn(ssl, (char *)buf);
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
exdump(ssl, 0, data);
|
||||
#ifdef OPENSSL
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
_status = 0;
|
||||
abort :
|
||||
#ifdef OPENSSL
|
||||
if(n) X509_NAME_free(n);
|
||||
#endif
|
||||
return(_status);
|
||||
}
|
||||
#endif
|
||||
return (_status);
|
||||
}
|
||||
|
||||
static int
|
||||
sslx__print_dn (ssl_obj *ssl, char *x)
|
||||
{
|
||||
char *slash;
|
||||
static int sslx__print_dn(ssl_obj *ssl, char *x) {
|
||||
char *slash;
|
||||
|
||||
if(*x=='/') x++;
|
||||
|
||||
while (x){
|
||||
if((slash=strchr(x,'/'))){
|
||||
*slash=0;
|
||||
}
|
||||
if(*x == '/')
|
||||
x++;
|
||||
|
||||
explain(ssl,"%s\n",x);
|
||||
while(x) {
|
||||
if((slash = strchr(x, '/'))) {
|
||||
*slash = 0;
|
||||
}
|
||||
|
||||
x=slash?slash+1:0;
|
||||
};
|
||||
explain(ssl, "%s\n", x);
|
||||
|
||||
return(0);
|
||||
}
|
||||
x = slash ? slash + 1 : 0;
|
||||
};
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef OPENSSL
|
||||
static int
|
||||
sslx__print_serial (ssl_obj *ssl, ASN1_INTEGER *a)
|
||||
{
|
||||
Data d;
|
||||
|
||||
if(a->length==0)
|
||||
printf("0");
|
||||
static int sslx__print_serial(ssl_obj *ssl, ASN1_INTEGER *a) {
|
||||
Data d;
|
||||
|
||||
INIT_DATA(d,a->data,a->length);
|
||||
exdump(ssl,0,&d);
|
||||
if(a->length == 0)
|
||||
printf("0");
|
||||
|
||||
return(0);
|
||||
}
|
||||
INIT_DATA(d, a->data, a->length);
|
||||
exdump(ssl, 0, &d);
|
||||
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
|
||||
|
||||
This product includes software developed by Eric Rescorla for
|
||||
RTFM, Inc.
|
||||
|
||||
|
@ -35,7 +35,8 @@
|
|||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
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 $
|
||||
|
||||
|
@ -43,12 +44,10 @@
|
|||
ekr@rtfm.com Thu Mar 25 21:23:34 1999
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _sslxprint_h
|
||||
#define _sslxprint_h
|
||||
|
||||
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_certificate PROTO_LIST((ssl_obj * ssl, Data *data, int pf));
|
||||
int sslx_print_dn PROTO_LIST((ssl_obj * ssl, Data *data, int pf));
|
||||
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in a new issue