uclmmbase-1.2.16.0/0000755000175000017500000000000010374736110012665 5ustar enderenderuclmmbase-1.2.16.0/doc/0000755000175000017500000000000010374736110013432 5ustar enderenderuclmmbase-1.2.16.0/doc/html/0000755000175000017500000000000010374735701014403 5ustar enderenderuclmmbase-1.2.16.0/doc/html/book1.html0000644000175000017500000000407607261724472016317 0ustar enderenderUCL Common Library Reference

UCL Common Library Reference

Table of Contents
Overview
HMAC — cryptographic message authentication.
MD5 — Message Digest-5 algorithm.
NETUDP — A UDP interface for IPv4 and IPv6.
RTP — Real-Time Transport Protocol (RTP) Implementation.
Debug — Functions for outputing diagnostics.
Memory — Memory allocation and debugging functions.
uclmmbase-1.2.16.0/doc/html/uclmmbase-hmac.html0000644000175000017500000001306707257725330020161 0ustar enderenderHMAC

HMAC

Name

HMAC -- cryptographic message authentication.

Synopsis


#include <hmac.h>


void        hmac_md5                        (unsigned char *data,
                                             int data_len,
                                             unsigned char *key,
                                             int key_len,
                                             unsigned char digest[16]);

Description

HMAC is a cryptographic mechanism for message authentication described in RFC2104. It allows a sender and receiver with a shared cryptographic key to verify the authenticity of a message.

Details

hmac_md5 ()

void        hmac_md5                        (unsigned char *data,
                                             int data_len,
                                             unsigned char *key,
                                             int key_len,
                                             unsigned char digest[16]);

Computes MD5 digest of data using key key.

data : pointer to data stream.
data_len : length of data stream in bytes.
key : pointer to authentication key.
key_len : length of authentication key in bytes.
digest : digest to be filled in.

See Also

RFC2104 - HMAC: Keyed-Hashing for Message Authentication

uclmmbase-1.2.16.0/doc/html/uclmmbase-md5.html0000644000175000017500000002044407257725330017733 0ustar enderenderMD5

MD5

Name

MD5 -- Message Digest-5 algorithm.

Synopsis


#include <md5.h>


typedef     MD5_CTX;
void        MD5Init                         (MD5_CTX *context);
void        MD5Update                       (MD5_CTX *context,
                                             unsigned char *input,
                                             unsigned int inputLen);
void        MD5Final                        (unsigned char digest[16],
                                             MD5_CTX *context);

Description

The MD5 algorithm calculates a 128-bit digest of an arbitrary length stream of data. The digest is a fingerprint that can be used to verify the integrity of a transmitted message. The sender and receiver of the message independently calculate the message digest and compare values to ascertain the integrity of the message. The probability of two messages having the same digest is miniscule.

The MD5 algorithm is the intellectual property of RSA Data Security, Inc.

Details

MD5_CTX

typedef struct {
  uint32_t state[4];            /* state (ABCD) */
  uint32_t count[2];        	/* number of bits, modulo 2^64 (lsb first) */
  unsigned char buffer[64];     /* input buffer */
} MD5_CTX;

The state for the MD5 calculation.


MD5Init ()

void        MD5Init                         (MD5_CTX *context);

Initializes MD5 context for the start of message digest computation.

context : MD5 context to be initialized.


MD5Update ()

void        MD5Update                       (MD5_CTX *context,
                                             unsigned char *input,
                                             unsigned int inputLen);

MD5 block update operation. Continues an MD5 message-digest operation, processing another message block, and updating the context.

context : MD5 context to be updated.
input : pointer to data to be fed into MD5 algorithm.
inputLen : size of input data in bytes.


MD5Final ()

void        MD5Final                        (unsigned char digest[16],
                                             MD5_CTX *context);

Ends an MD5 message-digest operation, writing the the message digest and zeroing the context. The context must be initialized with MD5Init() before being used for other MD5 checksum calculations.

digest : 16-byte buffer to write MD5 checksum.
context : MD5 context to be finalized.

See Also

RFC1321 - The MD5 Message Digest Algorithm

uclmmbase-1.2.16.0/doc/html/uclmmbase-net-udp.html0000644000175000017500000005102107257725330020615 0ustar enderenderNETUDP

NETUDP

Name

NETUDP -- A UDP interface for IPv4 and IPv6.

Synopsis


#include <net_udp.h>


struct      socket_udp;
int         udp_addr_valid                  (const char *addr);
socket_udp* udp_init                        (const char *addr,
                                             uint16_t rx_port,
                                             uint16_t tx_port,
                                             int ttl);
socket_udp* udp_init_if                     (const char *addr,
                                             const char *iface,
                                             uint16_t rx_port,
                                             uint16_t tx_port,
                                             int ttl);
void        udp_exit                        (socket_udp *s);
int         udp_send                        (socket_udp *s,
                                             char *buffer,
                                             int buflen);
int         udp_recv                        (socket_udp *s,
                                             char *buffer,
                                             int buflen);
int         udp_select                      (struct timeval *timeout);
void        udp_fd_zero                     (void);
void        udp_fd_set                      (socket_udp *s);
int         udp_fd_isset                    (socket_udp *s);
const char* udp_host_addr                   (socket_udp *s);
int         udp_fd                          (socket_udp *s);

Description

These functions provide a unified interface for sending are receiving UDP datagrams over IPv4 and IPv6 networks.

For IPv6 addresses to work the common library must be built with IPv6 enabled. On UNIX, the configure script has an option --enable-ip-v6 for this purpose. On Win32, there is a project configuration to use the Microsoft IPv6 stack when installed.

Details

struct socket_udp

struct socket_udp;

An opaque data structure containing information for a UDP session.


udp_addr_valid ()

int         udp_addr_valid                  (const char *addr);

addr : string representation of IPv4 or IPv6 network address.
Returns :TRUE if addr is valid, FALSE otherwise.


udp_init ()

socket_udp* udp_init                        (const char *addr,
                                             uint16_t rx_port,
                                             uint16_t tx_port,
                                             int ttl);

Creates a session for sending and receiving UDP datagrams over IP networks.

addr : character string containing an IPv4 or IPv6 network address.
rx_port : receive port.
tx_port : transmit port.
ttl : time-to-live value for transmitted packets.
Returns : a pointer to a valid socket_udp structure on success, NULL otherwise.


udp_init_if ()

socket_udp* udp_init_if                     (const char *addr,
                                             const char *iface,
                                             uint16_t rx_port,
                                             uint16_t tx_port,
                                             int ttl);

Creates a session for sending and receiving UDP datagrams over IP networks. The session uses iface as the interface to send and receive datagrams on.

addr : character string containing an IPv4 or IPv6 network address.
iface : character string containing an interface name.
rx_port : receive port.
tx_port : transmit port.
ttl : time-to-live value for transmitted packets.
Returns : a pointer to a socket_udp structure on success, NULL otherwise.


udp_exit ()

void        udp_exit                        (socket_udp *s);

Closes UDP session.

s : UDP session to be terminated.


udp_send ()

int         udp_send                        (socket_udp *s,
                                             char *buffer,
                                             int buflen);

Transmits a UDP datagram containing data from buffer.

s : UDP session.
buffer : pointer to buffer to be transmitted.
buflen : length of buffer.
Returns : 0 on success, -1 on failure.


udp_recv ()

int         udp_recv                        (socket_udp *s,
                                             char *buffer,
                                             int buflen);

Reads from datagram queue associated with UDP session.

s : UDP session.
buffer : buffer to read data into.
buflen : length of buffer.
Returns : number of bytes read, returns 0 if no data is available.


udp_select ()

int         udp_select                      (struct timeval *timeout);

Waits for data to arrive for UDP sessions.

timeout : maximum period to wait for data to arrive.
Returns : number of UDP sessions ready for reading.


udp_fd_zero ()

void        udp_fd_zero                     (void);

Clears file descriptor from set associated with UDP sessions (see select(2)).


udp_fd_set ()

void        udp_fd_set                      (socket_udp *s);

Adds file descriptor associated of s to set associated with UDP sessions.

s : UDP session.


udp_fd_isset ()

int         udp_fd_isset                    (socket_udp *s);

Checks if file descriptor associated with UDP session is ready for reading. This function should be called after udp_select().

s : UDP session.
Returns : non-zero if set, zero otherwise.


udp_host_addr ()

const char* udp_host_addr                   (socket_udp *s);

s : UDP session.
Returns : character string containing network address associated with session s.


udp_fd ()

int         udp_fd                          (socket_udp *s);

This function allows applications to apply their own socketopt()'s and ioctl()'s to the UDP session.

s : UDP session.
Returns : file descriptor of socket used by session s.

uclmmbase-1.2.16.0/doc/html/uclmmbase-rtp.html0000644000175000017500000022456107262621536020060 0ustar enderenderRTP

RTP

Name

RTP -- Real-Time Transport Protocol (RTP) Implementation.

Synopsis


#include <rtp.h>


#define     RTP_VERSION
#define     RTP_MAX_PACKET_LEN
typedef     rtp_packet;
#define     RTP_PACKET_HEADER_SIZE
typedef     rtcp_sr;
typedef     rtcp_rr;
enum        rtcp_sdes_type;
typedef     rtcp_sdes_item;
typedef     rtcp_app;
rtcp_app*   (*rtcp_app_callback)            (struct rtp *session,
                                             uint32_t rtp_ts,
                                             int max_size);
enum        rtp_event_type;
typedef     rtp_event;
void        (*rtp_callback)                 (struct rtp *session,
                                             rtp_event *e);
enum        rtp_option;
rtp_t       rtp_init                        (const char *addr,
                                             uint16_t rx_port,
                                             uint16_t tx_port,
                                             int ttl,
                                             double rtcp_bw,
                                             rtp_callback callback,
                                             uint8_t *userdata);
rtp_t       rtp_init_if                     (const char *addr,
                                             char *iface,
                                             uint16_t rx_port,
                                             uint16_t tx_port,
                                             int ttl,
                                             double rtcp_bw,
                                             rtp_callback callback,
                                             uint8_t *userdata);
void        rtp_send_bye                    (struct rtp *session);
void        rtp_done                        (struct rtp *session);
int         rtp_set_option                  (struct rtp *session,
                                             rtp_option optname,
                                             int optval);
int         rtp_get_option                  (struct rtp *session,
                                             rtp_option optname,
                                             int *optval);
int         rtp_recv                        (struct rtp *session,
                                             struct timeval *timeout,
                                             uint32_t curr_rtp_ts);
int         rtp_send_data                   (struct rtp *session,
                                             uint32_t rtp_ts,
                                             char pt,
                                             int m,
                                             int cc,
                                             uint32_t csrc[],
                                             char *data,
                                             int data_len,
                                             char *extn,
                                             uint16_t extn_len,
                                             uint16_t extn_type);
void        rtp_send_ctrl                   (struct rtp *session,
                                             uint32_t rtp_ts,
                                             rtcp_app_callback appcallback);
void        rtp_update                      (struct rtp *session);
uint32_t    rtp_my_ssrc                     (struct rtp *session);
int         rtp_add_csrc                    (struct rtp *session,
                                             uint32_t csrc);
int         rtp_del_csrc                    (struct rtp *session,
                                             uint32_t csrc);
int         rtp_set_sdes                    (struct rtp *session,
                                             uint32_t ssrc,
                                             rtcp_sdes_type type,
                                             const char *value,
                                             int length);
const char* rtp_get_sdes                    (struct rtp *session,
                                             uint32_t ssrc,
                                             rtcp_sdes_type type);
const rtcp_sr* rtp_get_sr                   (struct rtp *session,
                                             uint32_t ssrc);
const rtcp_rr* rtp_get_rr                   (struct rtp *session,
                                             uint32_t reporter,
                                             uint32_t reportee);
int         rtp_set_encryption_key          (struct rtp *session,
                                             const char *passphrase);
int         rtp_set_my_ssrc                 (struct rtp *session,
                                             uint32_t ssrc);
char*       rtp_get_addr                    (struct rtp *session);
uint16_t    rtp_get_rx_port                 (struct rtp *session);
uint16_t    rtp_get_tx_port                 (struct rtp *session);
int         rtp_get_ttl                     (struct rtp *session);
uint8_t*    rtp_get_userdata                (struct rtp *session);

Description

The Real-Time Transport Protocol (RTP) is a protocol for the transport of audio, video, and other real-time data across IP capable networks.

Details

RTP_VERSION

#define RTP_VERSION 2


RTP_MAX_PACKET_LEN

#define RTP_MAX_PACKET_LEN 1500


rtp_packet

typedef struct {
	/* The following are pointers to the data in the packet as    */
	/* it came off the wire. The packet it read in such that the  */
	/* header maps onto the latter part of this struct, and the   */
	/* fields in this first part of the struct point into it. The */
	/* entire packet can be freed by freeing this struct, without */
	/* having to free the csrc, data and extn blocks separately.  */
	/* WARNING: Don't change the size of the first portion of the */
	/* struct without changing RTP_PACKET_HEADER_SIZE to match.   */
	uint32_t	*csrc;
	char		*data;
	int		 data_len;
	unsigned char	*extn;
	uint16_t	 extn_len;	/* Size of the extension in 32 bit words minus one */
	uint16_t	 extn_type;	/* Extension type field in the RTP packet header   */
	/* The following map directly onto the RTP packet header...   */
#ifdef WORDS_BIGENDIAN
	unsigned short   v:2;		/* packet type                */
	unsigned short   p:1;		/* padding flag               */
	unsigned short   x:1;		/* header extension flag      */
	unsigned short   cc:4;		/* CSRC count                 */
	unsigned short   m:1;		/* marker bit                 */
	unsigned short   pt:7;		/* payload type               */
#else
	unsigned short   cc:4;		/* CSRC count                 */
	unsigned short   x:1;		/* header extension flag      */
	unsigned short   p:1;		/* padding flag               */
	unsigned short   v:2;		/* packet type                */
	unsigned short   pt:7;		/* payload type               */
	unsigned short   m:1;		/* marker bit                 */
#endif
	uint16_t          seq;		/* sequence number            */
	uint32_t          ts;		/* timestamp                  */
	uint32_t          ssrc;		/* synchronization source     */
	/* The csrc list, header extension and data follow, but can't */
	/* be represented in the struct.                              */
} rtp_packet;

The struct begins with pointers to the data in the packet as it came off the wire. The packet is read in such that the header maps onto the latter part of this struct, and the fields in this first part of the struct point into it. The entire packet can be freed by freeing this struct, without having to free the csrc, data and extn blocks separately. WARNING: Don't change the size of the first portion of the struct without changing RTP_PACKET_HEADER_SIZE to match.


RTP_PACKET_HEADER_SIZE

#define RTP_PACKET_HEADER_SIZE	((sizeof(char *) * 2) + sizeof(uint32_t *) + (2 * sizeof(int)))

This macro MUST resolve to the offset of the first packet field in the rtp_packet struct, including all padding. If you change rtp_packet, make sure to change this too.


rtcp_sr

typedef struct {
	uint32_t         ssrc;
	uint32_t         ntp_sec;
	uint32_t         ntp_frac;
	uint32_t         rtp_ts;
	uint32_t         sender_pcount;
	uint32_t         sender_bcount;
} rtcp_sr;


rtcp_rr

typedef struct {
	uint32_t	ssrc;		/* The ssrc to which this RR pertains */
#ifdef WORDS_BIGENDIAN
	uint32_t	fract_lost:8;
	uint32_t	total_lost:24;
#else
	uint32_t	total_lost:24;
	uint32_t	fract_lost:8;
#endif	
	uint32_t	last_seq;
	uint32_t	jitter;
	uint32_t	lsr;
	uint32_t	dlsr;
} rtcp_rr;


enum rtcp_sdes_type

typedef enum {
        RTCP_SDES_END   = 0,
        RTCP_SDES_CNAME = 1,
        RTCP_SDES_NAME  = 2,
        RTCP_SDES_EMAIL = 3,
        RTCP_SDES_PHONE = 4,
        RTCP_SDES_LOC   = 5,
        RTCP_SDES_TOOL  = 6,
        RTCP_SDES_NOTE  = 7,
        RTCP_SDES_PRIV  = 8
} rtcp_sdes_type;

Possible values of Session Description (SDES) identifiers. SDES items are announced via rtp_callback (with RX_SDES events) when they are received. SDES items may be configured and queried with rtp_set_sdes and rtp_get_sdes. The RTP guidelines recommend keeping SDES items constant during an RTP session to avoid confusing end users.

RTCP_SDES_ENDIndicates the end of SDES item processing when SDES data is received. Has no meaning with rtp_set_sdes and rtp_get_sdes.
RTCP_SDES_CNAMEThe canonical name associated with participant. It is algorithmically derived and should never be changed.
RTCP_SDES_NAMEThe local participant's name, typically displayed in RTP session participant list. The name can take any form, and should remain constant during a session to avoid confusion.
RTCP_SDES_EMAILThe local participant's email address (optional).
RTCP_SDES_PHONEThe local participant's telephone number (optional).
RTCP_SDES_LOCThe local participant's geographic location (optional).
RTCP_SDES_TOOLThe local participant's tool (optional).
RTCP_SDES_NOTEAny additional information the local participant wishes to communicate about themselves (optional).
RTCP_SDES_PRIVPrivate extension SDES item see RFC1889 for details.


rtcp_sdes_item

typedef struct {
	rtcp_sdes_type	type;		/* type of SDES item              */
	uint8_t		length;		/* length of SDES item (in bytes) */
	char		data[1];	/* text, not zero-terminated      */
} rtcp_sdes_item;


rtcp_app

typedef struct {
#ifdef WORDS_BIGENDIAN
	unsigned short  version:2;	/* RTP version            */
	unsigned short  p:1;		/* padding flag           */
	unsigned short  subtype:5;	/* application dependent  */
#else
	unsigned short  subtype:5;	/* application dependent  */
	unsigned short  p:1;		/* padding flag           */
	unsigned short  version:2;	/* RTP version            */
#endif
	unsigned short  pt:8;		/* packet type            */
	uint16_t        length;		/* packet length          */
	uint32_t        ssrc;
	char            name[4];        /* four ASCII characters  */
	char            data[1];        /* variable length field  */
} rtcp_app;


rtcp_app_callback ()

rtcp_app*   (*rtcp_app_callback)            (struct rtp *session,
                                             uint32_t rtp_ts,
                                             int max_size);

This callback function crafts an RTCP APP packet to be sent with an RTCP RR.

session :the session pointer (returned by rtp_init())
rtp_ts :the current time expressed in units of the media timestamp.
max_size :the max allowed size of an APP packet.
Returns :A fully-formed RTCP APP packet as an rtcp_app, or NULL (???) if no APP packet needs to be sent at this time.


enum rtp_event_type

typedef enum {
        RX_RTP,
        RX_SR,
        RX_RR,
        RX_SDES,
        RX_BYE,         /* Source is leaving the session, database entry is still valid */
        SOURCE_CREATED,
        SOURCE_DELETED, /* Source has been removed from the database                    */
        RX_RR_EMPTY,    /* We've received an empty reception report block                                               */
        RX_RTCP_START,  /* Processing a compound RTCP packet about to start. The SSRC is not valid in this event. */
        RX_RTCP_FINISH,	/* Processing a compound RTCP packet finished. The SSRC is not valid in this event.  */
        RR_TIMEOUT,
        RX_APP
} rtp_event_type;

The possible values for the type field in rtp_event. Each value represents an event in RTP or RTCP processing.

RX_RTPAn RTP data packet was received. The ssrc field contains the RTP data packet's SSRC. The data field points to a rtp_packet containing the RTP data packet. The callback must free the rtp_packet when it's done with it using the xfree() function.
RX_SRAn RTCP SR packet was received. The ssrc field contains the SR packet's SSRC. The data field points to an rtcp_sr.
RX_RRAn RTCP RR packet was received. The ssrc field contains the RR packet's SSRC. The data field points to an rtcp_rr.
RX_SDESAn RTCP SDES packet was received. The ssrc field contains the SDES packet's SSRC. The data field points to an rtcp_sdes_item.
RX_BYEAn RTCP BYE packet was received. The ssrc field contains the BYE packet's SSRC.
SOURCE_CREATEDA new session participant was heard from. The ssrc field contains the new participant's SSRC.
SOURCE_DELETEDA source was deleted from the database. The ssrc field contains the ex-participant's SSRC.
RX_RR_EMPTYAn RTCP RR packet with no sources listed was received. The ssrc field contains the RR packet's SSRC.
RX_RTCP_STARTCalled at the start of parsing an RTCP packet. Neither the ssrc nor data fields are valid.
RX_RTCP_FINISHCalled at the end of parsing an RTCP packet. Neither the ssrc nor data fields are valid.
RR_TIMEOUTAn RR from the given receiver has not been refreshed recently enough. The ssrc field contains the RR packet's SSRC. The data field points to the expiring rtcp_rr.
RX_APPAn APP packet was received. The ssrc field contains the APP packet's SSRC. The data field points to an rtcp_app. The callback must free the app packet when it's done with it.


rtp_event

typedef struct {
	uint32_t	 ssrc;
	rtp_event_type	 type;
	void		*data;
	struct timeval	*ts;
} rtp_event;

The event structure as passed to rtp_callback(). The callback type is carried in the type field; see rtp_event_type for a description of each callback. Unless otherwise noted, the ssrc field contains the SSRC of the participant triggering this callback. The data field points to any data contained in this callback; it must be cast to the appropriate type. The ts field contains the timestamp of the packet reception that caused this event.


rtp_callback ()

void        (*rtp_callback)                 (struct rtp *session,
                                             rtp_event *e);

Handles RTP events in an application-specific way. See rtp_event for a description of the possible events and how rtp_callback() should handle each.

session :The RTP Session.
e :The RTP Event information. See rtp_event.


enum rtp_option

typedef enum {
        RTP_OPT_PROMISC =	    1,
        RTP_OPT_WEAK_VALIDATION	=   2,
        RTP_OPT_FILTER_MY_PACKETS = 3
} rtp_option;

The possible options for a session that affect which RTP packets are passed to the application and when internal state for sources is created.

RTP_OPT_PROMISCPass RTP packets to application irrespective of whether a sender report has been received. Normally, participant state is created when a sender report is received and RTP packets that arrive prior to the sender report are discarded.
RTP_OPT_WEAK_VALIDATIONCreate source state when RTP packets arrive if none exists. This option is set by default. Disabling the option means source state is only created when sender reports are received.
RTP_OPT_FILTER_MY_PACKETSFilter out packets from local participant if they are received. With multicast sessions, packets may be looped back, causing senders packets to be received locally. This may be filtered out with this option.


rtp_init ()

rtp_t       rtp_init                        (const char *addr,
                                             uint16_t rx_port,
                                             uint16_t tx_port,
                                             int ttl,
                                             double rtcp_bw,
                                             rtp_callback callback,
                                             uint8_t *userdata);

addr : IP destination of this session (unicast or multicast), as an ASCII string. May be a host name, which will be looked up, or may be an IPv4 dotted quad or IPv6 literal adddress.
rx_port : The port to which to bind the UDP socket
tx_port : The port to which to send UDP packets
ttl : The TTL with which to send multicasts
rtcp_bw : The total bandwidth (in units of bytes per second) that is allocated to RTCP.
callback : See section on rtp_callback.
userdata : Opaque data associated with the session. See rtp_get_userdata().
Returns : An opaque session identifier to be used in future calls to the RTP library functions, or NULL on failure.


rtp_init_if ()

rtp_t       rtp_init_if                     (const char *addr,
                                             char *iface,
                                             uint16_t rx_port,
                                             uint16_t tx_port,
                                             int ttl,
                                             double rtcp_bw,
                                             rtp_callback callback,
                                             uint8_t *userdata);

Creates and initializes an RTP session.

addr : IP destination of this session (unicast or multicast), as an ASCII string. May be a host name, which will be looked up, or may be an IPv4 dotted quad or IPv6 literal adddress.
iface : If the destination of the session is multicast, the optional interface to bind to. May be NULL, in which case the default multicast interface as determined by the system will be used.
rx_port : The port to which to bind the UDP socket
tx_port : The port to which to send UDP packets
ttl : The TTL with which to send multicasts
rtcp_bw : The total bandwidth (in units of ___) that is allocated to RTCP.
callback : See section on rtp_callback.
userdata : Opaque data associated with the session. See rtp_get_userdata().
Returns : An opaque session identifier to be used in future calls to the RTP library functions, or NULL on failure.


rtp_send_bye ()

void        rtp_send_bye                    (struct rtp *session);

Sends a BYE message on the RTP session, indicating that this system is leaving the session. Should implement reverse reconsideration; right now it sends a BYE if there are less than 50 members and sends nothing otherwise.

session : The RTP session


rtp_done ()

void        rtp_done                        (struct rtp *session);

Free the state associated with the given RTP session. This function does not send any packets (e.g. an RTCP BYE) - an application which wishes to exit in a clean manner should call rtp_send_bye() first.

session : the RTP session to finish


rtp_set_option ()

int         rtp_set_option                  (struct rtp *session,
                                             rtp_option optname,
                                             int optval);

Sets the value of a session option. See rtp_option for documentation on the options and their legal values.

session : The RTP session.
optname : The option name, see rtp_option.
optval : The value to set.
Returns : TRUE on success, else FALSE.


rtp_get_option ()

int         rtp_get_option                  (struct rtp *session,
                                             rtp_option optname,
                                             int *optval);

Retrieves the value of a session option. See rtp_option for documentation on the options and their legal values.

session : The RTP session.
optname : The option name, see rtp_option.
optval : The return value.
Returns : TRUE and the value of the option in optval on success, else FALSE.


rtp_recv ()

int         rtp_recv                        (struct rtp *session,
                                             struct timeval *timeout,
                                             uint32_t curr_rtp_ts);

Receive RTP packets and dispatch them.

session : the session pointer (returned by rtp_init())
timeout : the amount of time that rtcp_recv() is allowed to block
curr_rtp_ts : the current time expressed in units of the media timestamp.
Returns : TRUE if data received, FALSE if the timeout occurred.


rtp_send_data ()

int         rtp_send_data                   (struct rtp *session,
                                             uint32_t rtp_ts,
                                             char pt,
                                             int m,
                                             int cc,
                                             uint32_t csrc[],
                                             char *data,
                                             int data_len,
                                             char *extn,
                                             uint16_t extn_len,
                                             uint16_t extn_type);

Send an RTP packet. Most media applications will only set the session, rtp_ts, pt, m, data, data_len arguments.

Mixers and translators typically set additional contributing sources arguments (cc, csrc).

Extensions fields (extn, extn_len, extn_type) are for including application specific information. When the widest amount of inter-operability is required these fields should be avoided as some applications discard packets with extensions they do not recognize.

session : the session pointer (returned by rtp_init())
rtp_ts : The timestamp reflects the sampling instant of the first octet of the RTP data to be sent. The timestamp is expressed in media units.
pt : The payload type identifying the format of the data.
m : Marker bit, interpretation defined by media profile of payload.
cc : Number of contributing sources (excluding local participant)
csrc : Array of SSRC identifiers for contributing sources.
data : The RTP data to be sent.
data_len : The size data in bytes.
extn : Extension data (if present).
extn_len : size of extn in bytes.
extn_type : extension type indicator.
Returns : Number of bytes transmitted.


rtp_send_ctrl ()

void        rtp_send_ctrl                   (struct rtp *session,
                                             uint32_t rtp_ts,
                                             rtcp_app_callback appcallback);

Checks RTCP timer and sends RTCP data when nececessary. The interval between RTCP packets is randomized over an interval that depends on the session bandwidth, the number of participants, and whether the local participant is a sender. This function should be called at least once per second, and can be safely called more frequently.

session : the session pointer (returned by rtp_init())
rtp_ts : the current time expressed in units of the media timestamp.
appcallback : a callback to create an APP RTCP packet, if needed.


rtp_update ()

void        rtp_update                      (struct rtp *session);

Trawls through the internal data structures and performs housekeeping. This function should be called at least once per second. It uses an internal timer to limit the number of passes through the data structures to once per second, it can be safely called more frequently.

session : the session pointer (returned by rtp_init())


rtp_my_ssrc ()

uint32_t    rtp_my_ssrc                     (struct rtp *session);

session : The RTP Session.
Returns : The SSRC we are currently using in this session. Note that our SSRC can change at any time (due to collisions) so applications must not store the value returned, but rather should call this function each time they need it.


rtp_add_csrc ()

int         rtp_add_csrc                    (struct rtp *session,
                                             uint32_t csrc);

Adds csrc to list of contributing sources used in SDES items. Used by mixers and transcoders.

session : the session pointer (returned by rtp_init())
csrc : Constributing SSRC identifier
Returns : TRUE.


rtp_del_csrc ()

int         rtp_del_csrc                    (struct rtp *session,
                                             uint32_t csrc);

Removes csrc from list of contributing sources used in SDES items. Used by mixers and transcoders.

session : the session pointer (returned by rtp_init())
csrc : Constributing SSRC identifier
Returns : TRUE on success, FALSE if csrc is not a valid source.


rtp_set_sdes ()

int         rtp_set_sdes                    (struct rtp *session,
                                             uint32_t ssrc,
                                             rtcp_sdes_type type,
                                             const char *value,
                                             int length);

Sets session description information associated with participant ssrc. Under normal circumstances applications always use the ssrc of the local participant, this SDES information is transmitted in receiver reports. Setting SDES information for other participants affects the local SDES entries, but are not transmitted onto the network.

session : the session pointer (returned by rtp_init())
ssrc : the SSRC identifier of a participant
type : the SDES type represented by value
value : the SDES description
length : the length of the description
Returns : Returns TRUE if participant exists, FALSE otherwise.


rtp_get_sdes ()

const char* rtp_get_sdes                    (struct rtp *session,
                                             uint32_t ssrc,
                                             rtcp_sdes_type type);

Recovers session description (SDES) information on participant identified with ssrc. The SDES information associated with a source is updated when receiver reports are received. There are several different types of SDES information, e.g. username, location, phone, email. These are enumerated by rtcp_sdes_type.

session : the session pointer (returned by rtp_init())
ssrc : the SSRC identifier of a participant
type : the SDES information to retrieve
Returns : pointer to string containing SDES description if received, NULL otherwise.


rtp_get_sr ()

const rtcp_sr* rtp_get_sr                   (struct rtp *session,
                                             uint32_t ssrc);

Retrieve the latest sender report made by sender with ssrc identifier.

session : the session pointer (returned by rtp_init())
ssrc : identifier of source
Returns : A pointer to an rtcp_sr structure on success, NULL otherwise. The pointer must not be freed.


rtp_get_rr ()

const rtcp_rr* rtp_get_rr                   (struct rtp *session,
                                             uint32_t reporter,
                                             uint32_t reportee);

Retrieve the latest receiver report on reportee made by reporter. Provides an indication of other receivers reception service.

session : the session pointer (returned by rtp_init())
reporter : participant originating receiver report
reportee : participant included in receiver report
Returns : A pointer to a rtcp_rr structure on success, NULL otherwise. The pointer must not be freed.


rtp_set_encryption_key ()

int         rtp_set_encryption_key          (struct rtp *session,
                                             const char *passphrase);

Converts the user supplied key into a form suitable for use with RTP and install it as the active key. Passing in NULL as the passphrase disables encryption. The passphrase is converted into a DES key as specified in RFC1890, that is:

- convert to canonical form

- derive an MD5 hash of the canonical form

- take the first 56 bits of the MD5 hash

- add parity bits to form a 64 bit key

Note that versions of rat prior to 4.1.2 do not convert the passphrase to canonical form before taking the MD5 hash, and so will not be compatible for keys which are non-invarient under this step.

session : The RTP session.
passphrase : The user-provided "pass phrase" to map to an encryption key.
Returns : TRUE on success, FALSE on failure.


rtp_set_my_ssrc ()

int         rtp_set_my_ssrc                 (struct rtp *session,
                                             uint32_t ssrc);

This function coerces the local SSRC identifer to be ssrc. For this function to succeed it must be called immediately after rtp_init or rtp_init_if. The intended purpose of this function is to co-ordinate SSRC's between layered sessions, it should not be used otherwise.

session : the RTP session
ssrc : the SSRC to be used by the RTP session
Returns : TRUE on success, FALSE otherwise.


rtp_get_addr ()

char*       rtp_get_addr                    (struct rtp *session);

session : The RTP Session.
Returns : The session's destination address, as set when creating the session with rtp_init() or rtp_init_if().


rtp_get_rx_port ()

uint16_t    rtp_get_rx_port                 (struct rtp *session);

session : The RTP Session.
Returns : The UDP port to which this session is bound, as set when creating the session with rtp_init() or rtp_init_if().


rtp_get_tx_port ()

uint16_t    rtp_get_tx_port                 (struct rtp *session);

session : The RTP Session.
Returns : The UDP port to which RTP packets are transmitted, as set when creating the session with rtp_init() or rtp_init_if().


rtp_get_ttl ()

int         rtp_get_ttl                     (struct rtp *session);

session : The RTP Session.
Returns : The session's TTL, as set when creating the session with rtp_init() or rtp_init_if().


rtp_get_userdata ()

uint8_t*    rtp_get_userdata                (struct rtp *session);

This function returns the userdata pointer that was passed to the rtp_init() or rtp_init_if() function when creating this session.

session : The RTP session.
Returns : pointer to userdata.

See Also

uclmmbase-1.2.16.0/doc/html/uclmmbase.html0000644000175000017500000000625107261724475017254 0ustar enderenderOverview

Overview

Table of Contents
HMAC — cryptographic message authentication.
MD5 — Message Digest-5 algorithm.
NETUDP — A UDP interface for IPv4 and IPv6.
RTP — Real-Time Transport Protocol (RTP) Implementation.
Debug — Functions for outputing diagnostics.
Memory — Memory allocation and debugging functions.

The UCL Common Multimedia Library provides a number of useful features for multimedia applications. It includes several protocols and functions related to IETF multimedia applications.

uclmmbase-1.2.16.0/doc/Makefile.in0000644000175000017500000000124007252440037015475 0ustar enderender# # Makefile for the common code library project documentation. # This probably requires GNU make. # MODULE=uclmmbase SGML_TOPLEVEL=$(MODULE)-driver.sgml CODE_DIR=../src CODE_SRCS=$(CODE_DIR)/*.c $(CODE_DIR)/*.h html: sgml $(SGML_TOPLEVEL) -cd html && gtkdoc-mkhtml $(MODULE) ../$(SGML_TOPLEVEL) sgml: tmpl gtkdoc-mkdb --module=$(MODULE) --source-dir=$(CODE_DIR) tmpl: scan gtkdoc-mktmpl --module=$(MODULE) scan: $(CODE_SRCS) gtkdoc-scan --module=$(MODULE) --source-dir=$(CODE_DIR) clean: -rm -f *.bak sgml/*.bak *unused.txt distclean: clean -rm -f $(MODULE)-decl-list.txt $(MODULE)-decl.txt Makefile -rm -rf sgml/* .PHONY: html sgml tmpl clean distclean uclmmbase-1.2.16.0/doc/README0000644000175000017500000000573207252461033014321 0ustar enderender* --------------------------------------------------------------------------- * Introduction This project uses gtkdoc to build DocBook documentation out of source code and sgml files. By using DocBook the option exists to build documentation in a number of formats (html, man, ps), though we currently target html only. gtkdoc is part of the GNOME project, details on downloading and installing can be found at: http://developer.gnome.org/projects/gdp/ FreeBSD and Linux have standard packages to install DocBook and gtkdoc. * --------------------------------------------------------------------------- * Building the documentation On Unix, just type "make". We don't have plans to build docs on anything other than FreeBSD/Linux - it's just a time thing. * --------------------------------------------------------------------------- * Reading the documentation The repository contains the HTML files so documentation is available upon download and does not require users to build it. The toplevel document is: html/book1.html * --------------------------------------------------------------------------- * Rough Guidelines Here is some "lore" on using gtkdoc and how things are with this documentation. This is our first attempt at using gtkdoc, and our insight comes from reading the gtkdoc source code and various bits on docbook (so we're probably missing some of the intentions). If you spot anything that would improve the documentation, please let us know (mm-tools@cs.ucl.ac.uk). Okay, so here's the deal. There are a few "core" files: 1. uclmmbase-sections.txt The initial version of this file was generated by running gtkdoc-scan on files in the source directory and copying the file $MODULE-decl.txt to uclmmbase-sections.txt. The file contains all declarations found. It will need updating when declarations change. Don't worry about it too much as the error message following a change instructs on what to do. If you want '#include "foo.h"' message to appear with documentation associated with section foo, add it here (look for "INCLUDE" for an example). 2. uclmmbase-driver.sgml This is the top-level sgml document. It is manually created and edited. Most of what we need is already there. 3) everything in tmpl/* These are templates that go around the libraries. At the time of writing only tmpl/rtp.sgml has anything in. Take a look, the general idea of what will appear should be apparent from this. The code documentation method is somewhat akin to Sun's JavaDoc: special comments are embedded in source files, and these are converted into documentation. The form of gtkdoc comments is: /** * maybe_print_string: * @message: the string to be printed. * * This function prints the message on the terminal with a probability 0.5. * * Returns: TRUE if message is printed, FALSE otherwise. */ int may_print_string(char *message) { if (drand48() >= 0.5) { printf("%s\n", message); return TRUE; } return FALSE; } Okay, hopefully this is enough to get started...uclmmbase-1.2.16.0/doc/uclmmbase-driver.sgml0000644000175000017500000000133407261724467017575 0ustar enderender ]> UCL Common Library Reference Overview The UCL Common Multimedia Library provides a number of useful features for multimedia applications. It includes several protocols and functions related to IETF multimedia applications. &hmac; &md5; &netudp; &rtp; &debug; &memory; uclmmbase-1.2.16.0/doc/uclmmbase-sections.txt0000644000175000017500000001217507261724470020005 0ustar enderender
acconfig WORDS_SMALLENDIAN
addrinfo EAI_ADDRFAMILY EAI_AGAIN EAI_BADFLAGS EAI_FAIL EAI_FAMILY EAI_MEMORY EAI_NODATA EAI_NONAME EAI_SERVICE EAI_SOCKTYPE EAI_SYSTEM EAI_BADHINTS EAI_PROTOCOL EAI_MAX NETDB_INTERNAL AI_PASSIVE AI_CANONNAME AI_NUMERICHOST AI_MASK AI_ALL AI_V4MAPPED_CFG AI_ADDRCONFIG AI_V4MAPPED AI_DEFAULT NI_MAXHOST NI_MAXSERV NI_NOFQDN NI_NUMERICHOST NI_NAMEREQD NI_NUMERICSERV NI_DGRAM
addrsize IN6ADDRSZ
asarray asarray asarray_create asarray_destroy asarray_add asarray_remove asarray_lookup asarray_get_key_no
base64 base64encode base64decode
bittypes u_int8_t u_int16_t u_int32_t
btree btree_create btree_destroy btree_add btree_remove btree_find btree_get_min_key btree_get_max_key btree_get_next_key
cdecl_ext
config_unix WEXITSTATUS WIFEXITED IPV6_ADD_MEMBERSHIP IPV6_DROP_MEMBERSHIP ttl_t fd_t USERNAMELEN max min assert gettimeofday gethostname EXIT_SUCCESS EXIT_FAILURE
config_win32 ttl_t fd_t uint8_t uint16_t uint32_t int8_t int16_t int32_t int64_t in_addr_t USERNAMELEN WORDS_SMALLENDIAN NEED_INET_ATON NEED_DRAND48 NEED_GETTIMEOFDAY assert inline AUDIO_MICROPHONE AUDIO_LINE_IN AUDIO_CD AUDIO_SPEAKER AUDIO_HEADPHONE AUDIO_LINE_OUT srand48 lrand48 snprintf IN_CLASSD IN_MULTICAST caddr_t ssize_t MAXHOSTNAMELEN pid_t uid_t gid_t uname getopt strncasecmp srandom random gethostid getuid getgid getpid nice usleep time w32_make_version_info strcasecmp RegGetValue ShowMessage bcopy ECONNREFUSED ENETUNREACH EHOSTUNREACH EWOULDBLOCK EAFNOSUPPORT M_PI
crypt_random lbl_srandom lbl_random
debug debug.h UNUSED debug_msg debug_dump debug_set_core_dir
drand48 drand48
gettimeofday gettimeofday
hmac hmac.h hmac_md5
inet_ntop inet_ntop
inet_pton inet_pton
mbus MBUS_MESSAGE_LOST MBUS_DESTINATION_UNKNOWN MBUS_DESTINATION_NOT_UNIQUE mbus_cmd_handler mbus_exit mbus_addr_valid mbus_qmsg mbus_qmsgf mbus_send mbus_recv mbus_retransmit mbus_heartbeat mbus_waiting_ack mbus_sent_all mbus_rendezvous_waiting mbus_rendezvous_go
mbus_addr mbus_addr_match mbus_addr_identical strfind
mbus_config MBUS_CONFIG_VERSION SCOPE_HOSTLOCAL SCOPE_HOSTLOCAL_NAME SCOPE_LINKLOCAL SCOPE_LINKLOCAL_NAME MBUS_DEFAULT_NET_ADDR MBUS_DEFAULT_NET_PORT MBUS_DEFAULT_SCOPE MBUS_DEFAULT_SCOPE_NAME mbus_new_encrkey mbus_new_hashkey mbus_lock_config_file mbus_unlock_config_file mbus_get_encrkey mbus_get_hashkey mbus_get_net_addr mbus_get_version
mbus_parser mbus_parse_done mbus_parse_lst mbus_parse_str mbus_parse_sym mbus_parse_int mbus_parse_flt mbus_decode_str mbus_encode_str
md5 md5.h MD5_CTX MD5Init MD5Update MD5Final
memory memory.h xmalloc xrealloc xstrdup xdoneinit xmemchk xmemdmp xclaim xmemdist xfree
net_udp net_udp.h socket_udp udp_addr_valid udp_init udp_init_if udp_exit udp_send udp_recv udp_select udp_fd_zero udp_fd_set udp_fd_isset udp_host_addr udp_fd
ntp ntp64_to_ntp32 ntp32_sub ntp64_time
qfDES QFDES_what QFDES_mode QFDES_parity QFDES_generate qfDES qfDES_ECB_e qfDES_ECB_d qfDES_CBC_e qfDES_CBC_d qfDES_CFB_e qfDES_CFB_d qfDES_OFB_e qfDES_OFB_d qfDES_setPad qfDES_padSpace qfDES_padZero qfDES_plainTextSize qfDES_setParity qfDES_checkParity qfDES_generate qfDES_generateKey qfDES_generateIV qfDES_checkWeakKeys
rtp rtp.h RTP_VERSION RTP_MAX_PACKET_LEN rtp_packet RTP_PACKET_HEADER_SIZE rtcp_sr rtcp_rr rtcp_sdes_type rtcp_sdes_item rtcp_app rtcp_app_callback rtp_event_type rtp_event rtp_callback rtp_option rtp_init rtp_init_if rtp_send_bye rtp_done rtp_set_option rtp_get_option rtp_recv rtp_send_data rtp_send_ctrl rtp_update rtp_my_ssrc rtp_add_csrc rtp_del_csrc rtp_set_sdes rtp_get_sdes rtp_get_sr rtp_get_rr rtp_set_encryption_key rtp_set_my_ssrc rtp_get_addr rtp_get_rx_port rtp_get_tx_port rtp_get_ttl rtp_get_userdata
sockstorage
util block_alloc block_free block_release_all block_trash_check block_check purge_chars overlapping_words
version CCL_VERSION
vsnprintf vsnprintf
uclconf HAVE_SYS_WAIT_H STDC_HEADERS HAVE_DEV_URANDOM HAVE_ST_ADDRINFO HAVE_GETIPNODEBYNAME HAVE_VSNPRINTF NEED_INET_PTON NEED_INET_NTOP HAVE_INTTYPES_H HAVE_SYS_FILIO_H WORDS_SMALLENDIAN DEBUG DEBUG_MEM
uclmmbase-1.2.16.0/doc/tmpl/0000755000175000017500000000000010374735701014413 5ustar enderenderuclmmbase-1.2.16.0/doc/tmpl/acconfig.sgml0000644000175000017500000000042407252440045017043 0ustar enderender acconfig uclmmbase-1.2.16.0/doc/tmpl/addrinfo.sgml0000644000175000017500000000372407252440045017066 0ustar enderender addrinfo uclmmbase-1.2.16.0/doc/tmpl/addrsize.sgml0000644000175000017500000000041407252440046017077 0ustar enderender addrsize uclmmbase-1.2.16.0/doc/tmpl/asarray.sgml0000644000175000017500000000141507252440046016736 0ustar enderender asarray @ppa: @Returns: @ppa: @pa: @key: @value: @Returns: @pa: @key: @pa: @key: @value: @Returns: @pa: @index: @Returns: uclmmbase-1.2.16.0/doc/tmpl/base64.sgml0000644000175000017500000000071407252440047016362 0ustar enderender base64 @input: @input_length: @output: @output_length: @Returns: @input: @input_length: @output: @output_length: @Returns: uclmmbase-1.2.16.0/doc/tmpl/bittypes.sgml0000644000175000017500000000057607252440050017141 0ustar enderender bittypes uclmmbase-1.2.16.0/doc/tmpl/btree.sgml0000644000175000017500000000166107252440050016373 0ustar enderender btree @tree: @Returns: @tree: @Returns: @tree: @key: @data: @Returns: @tree: @key: @d: @Returns: @tree: @key: @d: @Returns: @tree: @key: @Returns: @tree: @key: @Returns: @tree: @cur_key: @next_key: @Returns: uclmmbase-1.2.16.0/doc/tmpl/cdecl_ext.sgml0000644000175000017500000000032507252440051017221 0ustar enderender cdecl_ext uclmmbase-1.2.16.0/doc/tmpl/config_unix.sgml0000644000175000017500000000214507252440051017601 0ustar enderender config_unix @stat_val: @stat_val: @a: @b: @a: @b: @x: @tp: @Param2: @Returns: @name: @namelen: @Returns: uclmmbase-1.2.16.0/doc/tmpl/config_win32.sgml0000644000175000017500000000741007252440052017561 0ustar enderender config_win32 @x: @i: @i: @Param1: @Returns: @Varargs: @Param2: @Param3: @Returns: @Param1: @Param2: @len: @Returns: @Varargs: @Returns: @Returns: @Returns: @Returns: @Returns: @Returns: @Varargs: @Returns: @Param1: @Returns: @Param1: @Returns: @rat_verion: @Returns: @Param1: @Param2: @Param3: @Param4: @Varargs: @Returns: @level: @msg: @from: @to: @len: uclmmbase-1.2.16.0/doc/tmpl/crypt_random.sgml0000644000175000017500000000054407252440052017774 0ustar enderender crypt_random @seed: @Returns: uclmmbase-1.2.16.0/doc/tmpl/debug.sgml0000644000175000017500000000302207261724476016372 0ustar enderender Debug Functions for outputing diagnostics. These functions relate to outputing diagnostic messages and information. Use of these functions requires DEBUG to be defined at compilation time. On Unix systems, the configure script has a command-line option . On Win32 a debug configuration exists. Available for use to prevent compiler warnings when a function argument is not used. Sometimes this is unavoidable because function has to conform to an interface. @x: unused function argument that generates compiler warning. When DEBUG is defined this will write a formatted message to the platform defined error stream. The format of the message has the same semantics as standard C library call printf(). The error message displayed is prepended by the process id, the file and the line number, where debug_msg() was called. On Unix the message is rendered on the standard error stream. On Win32 a debug message is created using the Win32 API function OutputDebugString(). @lp: @len: @argv0: uclmmbase-1.2.16.0/doc/tmpl/drand48.sgml0000644000175000017500000000042707252440053016540 0ustar enderender drand48 @Returns: uclmmbase-1.2.16.0/doc/tmpl/gettimeofday.sgml0000644000175000017500000000046107252440053017753 0ustar enderender gettimeofday @tp: @Param2: @Returns: uclmmbase-1.2.16.0/doc/tmpl/hmac.sgml0000644000175000017500000000122107252665771016215 0ustar enderender HMAC cryptographic message authentication. HMAC is a cryptographic mechanism for message authentication described in RFC2104. It allows a sender and receiver with a shared cryptographic key to verify the authenticity of a message. RFC2104 - HMAC: Keyed-Hashing for Message Authentication @data: @data_len: @key: @key_len: @digest: uclmmbase-1.2.16.0/doc/tmpl/inet_ntop.sgml0000644000175000017500000000046707252440055017301 0ustar enderender inet_ntop @af: @src: @dst: @size: @Returns: uclmmbase-1.2.16.0/doc/tmpl/inet_pton.sgml0000644000175000017500000000045707252440055017300 0ustar enderender inet_pton @af: @src: @dst: @Returns: uclmmbase-1.2.16.0/doc/tmpl/mbus.sgml0000644000175000017500000000302307252440056016240 0ustar enderender mbus @m: @cmd_handler: @m: @m: @addr: @Returns: @m: @dest: @cmnd: @args: @reliable: @m: @dest: @reliable: @cmnd: @format: @Varargs: @m: @m: @data: @timeout: @Returns: @m: @m: @interval: @m: @Returns: @m: @Returns: @m: @addr: @token: @data: @Returns: @m: @token: @data: @Returns: uclmmbase-1.2.16.0/doc/tmpl/mbus_addr.sgml0000644000175000017500000000076307252440056017242 0ustar enderender mbus_addr @a: @b: @Returns: @a: @b: @Returns: @haystack: @needle_start: @needle_end: @Returns: uclmmbase-1.2.16.0/doc/tmpl/mbus_config.sgml0000644000175000017500000000267107252440057017576 0ustar enderender mbus_config @Returns: @Returns: @m: @m: @m: @key: @m: @key: @m: @net_addr: @net_port: @net_scope: @m: @Returns: uclmmbase-1.2.16.0/doc/tmpl/mbus_parser.sgml0000644000175000017500000000155007252440057017620 0ustar enderender mbus_parser @m: @m: @l: @Returns: @m: @s: @Returns: @m: @s: @Returns: @m: @i: @Returns: @m: @d: @Returns: @s: @Returns: @s: @Returns: uclmmbase-1.2.16.0/doc/tmpl/md5.sgml0000644000175000017500000000242307252665771015777 0ustar enderender MD5 Message Digest-5 algorithm. The MD5 algorithm calculates a 128-bit digest of an arbitrary length stream of data. The digest is a fingerprint that can be used to verify the integrity of a transmitted message. The sender and receiver of the message independently calculate the message digest and compare values to ascertain the integrity of the message. The probability of two messages having the same digest is miniscule. The MD5 algorithm is the intellectual property of RSA Data Security, Inc. RFC1321 - The MD5 Message Digest Algorithm The state for the MD5 calculation. @context: @Param1: @context: @input: @inputLen: @Param1: @Param2: @Param3: @digest: @context: @Param1: @Param2: uclmmbase-1.2.16.0/doc/tmpl/memory.sgml0000644000175000017500000000360307261724477016622 0ustar enderender Memory Memory allocation and debugging functions. This set of functions is semantically similar functions to standard C library memory allocation routines. When memory debugging is enabled these functions include support to detect buffer overruns. When memory debugging is not enabled the allocation and free calls are wrappers around the standard C allocation routines, and checking routines are null ops. Memory debugging is enabled when DEBUG_MEM is defined at compilation time. On Unix systems, the configure script has a command-line option . On Win32, a memory debugging is enabled in the debug configuration. Allocates a block of memory. Semantically equivalent to malloc(). @x: size of allocation. Re-sizes a block of memory. Semantically equivalent to realloc(). @p: Pointer to block to be re-dimensioned. @x: New size. xmalloc()'s sufficient memory to store @str, copies @str into it, and returns pointer to new string. Semantically equivalent to strdup(). @str: @x: String to duplicate. @addr: @filen: @line: @p: @fp: @p: @x: uclmmbase-1.2.16.0/doc/tmpl/net_udp.sgml0000644000175000017500000000337207252665771016754 0ustar enderender NETUDP A UDP interface for IPv4 and IPv6. These functions provide a unified interface for sending are receiving UDP datagrams over IPv4 and IPv6 networks. For IPv6 addresses to work the common library must be built with IPv6 enabled. On UNIX, the configure script has an option for this purpose. On Win32, there is a project configuration to use the Microsoft IPv6 stack when installed. An opaque data structure containing information for a UDP session. @addr: @Returns: @addr: @rx_port: @tx_port: @ttl: @Returns: @addr: @iface: @rx_port: @tx_port: @ttl: @Returns: @s: @s: @buffer: @buflen: @Returns: @s: @buffer: @buflen: @Returns: @timeout: @Returns: @s: @s: @Returns: @s: @Returns: @s: @Returns: uclmmbase-1.2.16.0/doc/tmpl/ntp.sgml0000644000175000017500000000067507252440061016101 0ustar enderender ntp @ntp_sec: @ntp_frac: @now: @then: @ntp_sec: @ntp_frac: uclmmbase-1.2.16.0/doc/tmpl/qfDES.sgml0000644000175000017500000000423707252440062016241 0ustar enderender qfDES @qfDES_encrypt: @qfDES_decrypt: @qfDES_ecb: @qfDES_cbc: @qfDES_cfb: @qfDES_ofb: @qfDES_even: @qfDES_odd: @qfDES_key: @qfDES_iv: @key: @data: @size: @what: @mode: @initVec: @Returns: @_key: @_data: @_size: @_key: @_data: @_size: @_key: @_data: @_size: @_initVec: @_key: @_data: @_size: @_initVec: @_key: @_data: @_size: @_initVec: @_key: @_data: @_size: @_initVec: @_key: @_data: @_size: @_initVec: @_key: @_data: @_size: @_initVec: @pad: @Returns: @_ptr: @_size: @ptr: @size: @parity: @ptr: @size: @parity: @Returns: @what: @Returns: @key: @Returns: uclmmbase-1.2.16.0/doc/tmpl/rtp.sgml0000644000175000017500000002301707261724501016104 0ustar enderender RTP Real-Time Transport Protocol (RTP) Implementation. The Real-Time Transport Protocol (RTP) is a protocol for the transport of audio, video, and other real-time data across IP capable networks. RFC1889 - RTP: A Transport Protocol for Real-Time Applications RFC1890 - RTP Profile for Audio and Video Conferences with Minimal Control IETF Audio/Video Transport Group The struct begins with pointers to the data in the packet as it came off the wire. The packet is read in such that the header maps onto the latter part of this struct, and the fields in this first part of the struct point into it. The entire packet can be freed by freeing this struct, without having to free the csrc, data and extn blocks separately. WARNING: Don't change the size of the first portion of the struct without changing RTP_PACKET_HEADER_SIZE to match. This macro MUST resolve to the offset of the first packet field in the #rtp_packet struct, including all padding. If you change rtp_packet, make sure to change this too. Possible values of Session Description (SDES) identifiers. SDES items are announced via #rtp_callback (with RX_SDES events) when they are received. SDES items may be configured and queried with #rtp_set_sdes and #rtp_get_sdes. The RTP guidelines recommend keeping SDES items constant during an RTP session to avoid confusing end users. @RTCP_SDES_END: Indicates the end of SDES item processing when SDES data is received. Has no meaning with #rtp_set_sdes and #rtp_get_sdes. @RTCP_SDES_CNAME: The canonical name associated with participant. It is algorithmically derived and should never be changed. @RTCP_SDES_NAME: The local participant's name, typically displayed in RTP session participant list. The name can take any form, and should remain constant during a session to avoid confusion. @RTCP_SDES_EMAIL: The local participant's email address (optional). @RTCP_SDES_PHONE: The local participant's telephone number (optional). @RTCP_SDES_LOC: The local participant's geographic location (optional). @RTCP_SDES_TOOL: The local participant's tool (optional). @RTCP_SDES_NOTE: Any additional information the local participant wishes to communicate about themselves (optional). @RTCP_SDES_PRIV: Private extension SDES item see RFC1889 for details. This callback function crafts an RTCP APP packet to be sent with an RTCP RR. @session: the session pointer (returned by rtp_init()) @rtp_ts: the current time expressed in units of the media timestamp. @max_size: the max allowed size of an APP packet. @Returns: A fully-formed RTCP APP packet as an #rtcp_app, or NULL (???) if no APP packet needs to be sent at this time. The possible values for the type field in #rtp_event. Each value represents an event in RTP or RTCP processing. @RX_RTP: An RTP data packet was received. The ssrc field contains the RTP data packet's SSRC. The data field points to a #rtp_packet containing the RTP data packet. The callback must free the rtp_packet when it's done with it using the xfree() function. @RX_SR: An RTCP SR packet was received. The ssrc field contains the SR packet's SSRC. The data field points to an #rtcp_sr. @RX_RR: An RTCP RR packet was received. The ssrc field contains the RR packet's SSRC. The data field points to an #rtcp_rr. @RX_SDES: An RTCP SDES packet was received. The ssrc field contains the SDES packet's SSRC. The data field points to an #rtcp_sdes_item. @RX_BYE: An RTCP BYE packet was received. The ssrc field contains the BYE packet's SSRC. @SOURCE_CREATED: A new session participant was heard from. The ssrc field contains the new participant's SSRC. @SOURCE_DELETED: A source was deleted from the database. The ssrc field contains the ex-participant's SSRC. @RX_RR_EMPTY: An RTCP RR packet with no sources listed was received. The ssrc field contains the RR packet's SSRC. @RX_RTCP_START: Called at the start of parsing an RTCP packet. Neither the ssrc nor data fields are valid. @RX_RTCP_FINISH: Called at the end of parsing an RTCP packet. Neither the ssrc nor data fields are valid. @RR_TIMEOUT: An RR from the given receiver has not been refreshed recently enough. The ssrc field contains the RR packet's SSRC. The data field points to the expiring #rtcp_rr. @RX_APP: An APP packet was received. The ssrc field contains the APP packet's SSRC. The data field points to an #rtcp_app. The callback must free the app packet when it's done with it. The event structure as passed to rtp_callback(). The callback type is carried in the type field; see #rtp_event_type for a description of each callback. Unless otherwise noted, the ssrc field contains the SSRC of the participant triggering this callback. The data field points to any data contained in this callback; it must be cast to the appropriate type. The ts field contains the timestamp of the packet reception that caused this event. Handles RTP events in an application-specific way. See #rtp_event for a description of the possible events and how rtp_callback() should handle each. @session: The RTP Session. @e: The RTP Event information. See #rtp_event. The possible options for a session that affect which RTP packets are passed to the application and when internal state for sources is created. @RTP_OPT_PROMISC: Pass RTP packets to application irrespective of whether a sender report has been received. Normally, participant state is created when a sender report is received and RTP packets that arrive prior to the sender report are discarded. @RTP_OPT_WEAK_VALIDATION: Create source state when RTP packets arrive if none exists. This option is set by default. Disabling the option means source state is only created when sender reports are received. @RTP_OPT_FILTER_MY_PACKETS: Filter out packets from local participant if they are received. With multicast sessions, packets may be looped back, causing senders packets to be received locally. This may be filtered out with this option. @addr: @rx_port: @tx_port: @ttl: @rtcp_bw: @callback: @userdata: @Returns: @addr: @iface: @rx_port: @tx_port: @ttl: @rtcp_bw: @callback: @userdata: @Returns: @session: @session: @session: @optname: @optval: @Returns: @session: @optname: @optval: @Returns: @session: @timeout: @curr_rtp_ts: @Returns: @session: @rtp_ts: @pt: @m: @cc: @csrc: @data: @data_len: @extn: @extn_len: @extn_type: @Returns: @session: @rtp_ts: @appcallback: @session: @session: @Returns: @session: @csrc: @Returns: @session: @csrc: @Returns: @session: @ssrc: @type: @value: @length: @Returns: @session: @ssrc: @type: @Returns: @session: @ssrc: @Returns: @session: @reporter: @reportee: @Returns: @session: @passphrase: @Returns: @session: @ssrc: @Returns: @session: @Returns: @session: @Returns: @session: @Returns: @session: @Returns: @session: @Returns: uclmmbase-1.2.16.0/doc/tmpl/sockstorage.sgml0000644000175000017500000000032707252440063017620 0ustar enderender sockstorage uclmmbase-1.2.16.0/doc/tmpl/uclconf.sgml0000644000175000017500000000175507261724502016736 0ustar enderender uclconf uclmmbase-1.2.16.0/doc/tmpl/uclmmbase-unused.sgml0000644000175000017500000000574707261724503020564 0ustar enderender test_net_udp test_mbus_parser test_base64 test_mbus_addr test_md5 @session: @ssrc: @Returns: test_des test_memory @session: @optname: @optval: @Returns: @session: @optname: @optval: @Returns: uclmmbase-1.2.16.0/doc/tmpl/util.sgml0000644000175000017500000000131607252440064016251 0ustar enderender util @x: @x: @y: @p: @src: @to_go: @s1: @s2: @max_words: @Returns: uclmmbase-1.2.16.0/doc/tmpl/version.sgml0000644000175000017500000000041507252440065016761 0ustar enderender version uclmmbase-1.2.16.0/doc/tmpl/vsnprintf.sgml0000644000175000017500000000047407252440065017332 0ustar enderender vsnprintf @s: @buf_size: @format: @ap: @Returns: uclmmbase-1.2.16.0/doc/Makefile0000644000175000017500000000133107777571205015107 0ustar enderender# Generated automatically from Makefile.in by configure. # # Makefile for the common code library project documentation. # This probably requires GNU make. # MODULE=uclmmbase SGML_TOPLEVEL=$(MODULE)-driver.sgml CODE_DIR=../src CODE_SRCS=$(CODE_DIR)/*.c $(CODE_DIR)/*.h html: sgml $(SGML_TOPLEVEL) -cd html && gtkdoc-mkhtml $(MODULE) ../$(SGML_TOPLEVEL) sgml: tmpl gtkdoc-mkdb --module=$(MODULE) --source-dir=$(CODE_DIR) tmpl: scan gtkdoc-mktmpl --module=$(MODULE) scan: $(CODE_SRCS) gtkdoc-scan --module=$(MODULE) --source-dir=$(CODE_DIR) clean: -rm -f *.bak sgml/*.bak *unused.txt distclean: clean -rm -f $(MODULE)-decl-list.txt $(MODULE)-decl.txt Makefile -rm -rf sgml/* .PHONY: html sgml tmpl clean distclean uclmmbase-1.2.16.0/src/0000755000175000017500000000000010374736110013454 5ustar enderenderuclmmbase-1.2.16.0/src/win32/0000755000175000017500000000000010374735701014423 5ustar enderenderuclmmbase-1.2.16.0/src/win32/echo.txt0000644000175000017500000000005707042073503016075 0ustar enderenderecho #define CCL_VERSION "v%v%" > version.h uclmmbase-1.2.16.0/src/win32/null.txt0000644000175000017500000000000207042073504016120 0ustar enderender uclmmbase-1.2.16.0/src/win32/set.txt0000644000175000017500000000000607042073504015745 0ustar enderenderset v=uclmmbase-1.2.16.0/src/Makefile.in0000640000175000017500000000201407665117720015523 0ustar enderender# # Makefile for the common code library project. # This probably requires GNU make. # DEFS = @DEFS@ CFLAGS = @CFLAGS@ $(DEFS) LIBS = @LIBS@ CC = @CC@ AR = ar RANLIB = @RANLIB@ HOST = @host@ TARGET = libuclmmbase.a exec_prefix=@exec_prefix@ OBJS = crypt_random.o debug.o md5.o memory.o net_udp.o qfDES.o util.o hmac.o \ base64.o ntp.o rtp.o drand48.o mbus_parser.o mbus_config.o mbus_addr.o \ mbus.o btree.o asarray.o @LIBOBJS@ rijndael-alg-fst.o \ rijndael-api-fst.o sdp.o sap.o SRCS = $(OBJS:%.o=%.c) all: version.h $(TARGET) $(TARGET): $(OBJS) $(AR) r $(TARGET) $(OBJS) $(RANLIB) $(TARGET) version.h: ../VERSION sed -e 's/.*/#define CCL_VERSION "v&"/' $? > version.h .c.o: $(CC) $(CFLAGS) $(INC) -c $< clean: -rm -f $(OBJS) version.h $(TARGET) tags distclean: clean -rm -f Makefile config.status config.cache uclconf.h etags: etags *.[ch] ctags: ctags *.[ch] release: cvs tag release-`cat ../VERSION | sed "s/\./-/g"` depend: $(SRCS) makedepend $(DEFS) $(INC) $(SRCS) uclmmbase-1.2.16.0/src/README.qfdes0000640000175000017500000001265106715017760015445 0ustar enderenderThe qfDES code is derived from Saleem Bhatti's code, but has been significantly revised, debugged and updated. The following is the original README, followed by some other information which may be useful, taken from Eric Young's libdes. =============================================================================== This is yet another implementation of DES in software, for those of us that don't have access to DES hardware. The library is fairly (but not quite) complete, as are the two progs, qf-des and qf-key. However, debugging and testing is still proceeding ... Quickie Roadmap --------------- qf-des: Do DES on files (qf-des.c) qf-key: Generate keys and IVs (qf-key.c) libqfDES.a: library of DES stuff qfDES.h: Interface file for libqfDES.a qfDES.c: The DES function qfDES-print.c: For generating some of the DES macros and S-Box/P transforms qfDES-key.c: Key and IV generation qfDES-memory.c: Fiddling around with memory Disclaimer ---------- This version of the qfDES is for me only, so if you have it and are not me, then I take no responsibility for what happens when you use it! TTFN, --/Saleem =============================================================================== Modes of DES Quite a bit of the following information has been taken from AS 2805.5.2 Australian Standard Electronic funds transfer - Requirements for interfaces, Part 5.2: Modes of operation for an n-bit block cipher algorithm Appendix A There are several different modes in which DES can be used, they are as follows. Electronic Codebook Mode (ECB) (des_ecb_encrypt()) - 64 bits are enciphered at a time. - The order of the blocks can be rearranged without detection. - The same plaintext block always produces the same ciphertext block (for the same key) making it vulnerable to a 'dictionary attack'. - An error will only affect one ciphertext block. Cipher Block Chaining Mode (CBC) (des_cbc_encrypt()) - a multiple of 64 bits are enciphered at a time. - The CBC mode produces the same ciphertext whenever the same plaintext is encrypted using the same key and starting variable. - The chaining operation makes the ciphertext blocks dependent on the current and all preceding plaintext blocks and therefore blocks can not be rearranged. - The use of different starting variables prevents the same plaintext enciphering to the same ciphertext. - An error will affect the current and the following ciphertext blocks. Cipher Feedback Mode (CFB) (des_cfb_encrypt()) - a number of bits (j) <= 64 are enciphered at a time. - The CFB mode produces the same ciphertext whenever the same plaintext is encrypted using the same key and starting variable. - The chaining operation makes the ciphertext variables dependent on the current and all preceding variables and therefore j-bit variables are chained together and con not be rearranged. - The use of different starting variables prevents the same plaintext enciphering to the same ciphertext. - The strength of the CFB mode depends on the size of k (maximal if j == k). In my implementation this is always the case. - Selection of a small value for j will require more cycles through the encipherment algorithm per unit of plaintext and thus cause greater processing overheads. - Only multiples of j bits can be enciphered. - An error will affect the current and the following ciphertext variables. Output Feedback Mode (OFB) (des_ofb_encrypt()) - a number of bits (j) <= 64 are enciphered at a time. - The OFB mode produces the same ciphertext whenever the same plaintext enciphered using the same key and starting variable. More over, in the OFB mode the same key stream is produced when the same key and start variable are used. Consequently, for security reasons a specific start variable should be used only once for a given key. - The absence of chaining makes the OFB more vulnerable to specific attacks. - The use of different start variables values prevents the same plaintext enciphering to the same ciphertext, by producing different key streams. - Selection of a small value for j will require more cycles through the encipherment algorithm per unit of plaintext and thus cause greater processing overheads. - Only multiples of j bits can be enciphered. - OFB mode of operation does not extend ciphertext errors in the resultant plaintext output. Every bit error in the ciphertext causes only one bit to be in error in the deciphered plaintext. - OFB mode is not self-synchronising. If the two operation of encipherment and decipherment get out of synchronism, the system needs to be re-initialised. - Each re-initialisation should use a value of the start variable different from the start variable values used before with the same key. The reason for this is that an identical bit stream would be produced each time from the same parameters. This would be susceptible to a ' known plaintext' attack. Triple ECB Mode (des_3ecb_encrypt()) - Encrypt with key1, decrypt with key2 and encrypt with key1 again. - As for ECB encryption but increases the effective key length to 112 bits. - If both keys are the same it is equivalent to encrypting once with just one key. Triple CBC Mode (des_3cbc_encrypt()) - Encrypt with key1, decrypt with key2 and encrypt with key1 again. - As for CBC encryption but increases the effective key length to 112 bits. - If both keys are the same it is equivalent to encrypting once with just one key. =============================================================================== uclmmbase-1.2.16.0/src/acconfig.h0000644000175000017500000000151707060714006015400 0ustar enderender/* * Define this if you have a /dev/urandom which can supply good random numbers. */ #undef HAVE_DEV_URANDOM /* * Define this if you want IPv6 support. */ #undef HAVE_IPv6 /* * V6 structures that host may or may not be present. */ #undef HAVE_ST_ADDRINFO #undef HAVE_GETIPNODEBYNAME #undef HAVE_SIN6_LEN /* * Define these if your C library is missing some functions... */ #undef NEED_VSNPRINTF #undef NEED_INET_PTON #undef NEED_INET_NTOP /* * If you don't have these types in , #define these to be * the types you do have. */ #undef int8_t #undef int16_t #undef int32_t #undef int64_t #undef uint8_t #undef uint16_t #undef uint32_t /* * Debugging: * DEBUG: general debugging * DEBUG_MEM: debug memory allocation */ #undef DEBUG #undef DEBUG_MEM @BOTTOM@ #ifndef WORDS_BIGENDIAN #define WORDS_SMALLENDIAN #endif uclmmbase-1.2.16.0/src/addrinfo.h0000644000175000017500000001126307057740731015426 0ustar enderender/* * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ /* $Id: addrinfo.h,v 1.1 2000/03/03 13:44:57 piers Exp $ */ #ifndef HAVE_ADDRINFO /* * Error return codes from getaddrinfo() */ #define EAI_ADDRFAMILY 1 /* address family for hostname not supported */ #define EAI_AGAIN 2 /* temporary failure in name resolution */ #define EAI_BADFLAGS 3 /* invalid value for ai_flags */ #define EAI_FAIL 4 /* non-recoverable failure in name resolution */ #define EAI_FAMILY 5 /* ai_family not supported */ #define EAI_MEMORY 6 /* memory allocation failure */ #define EAI_NODATA 7 /* no address associated with hostname */ #define EAI_NONAME 8 /* hostname nor servname provided, or not known */ #define EAI_SERVICE 9 /* servname not supported for ai_socktype */ #define EAI_SOCKTYPE 10 /* ai_socktype not supported */ #define EAI_SYSTEM 11 /* system error returned in errno */ #define EAI_BADHINTS 12 #define EAI_PROTOCOL 13 #define EAI_MAX 14 /* internal error */ #define NETDB_INTERNAL -1 /* see errno */ /* * Flag values for getaddrinfo() */ #define AI_PASSIVE 0x00000001 /* get address to use bind() */ #define AI_CANONNAME 0x00000002 /* fill ai_canonname */ #define AI_NUMERICHOST 0x00000004 /* prevent name resolution */ /* valid flags for addrinfo */ #define AI_MASK (AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST) #define AI_ALL 0x00000100 /* IPv6 and IPv4-mapped (with AI_V4MAPPED) */ #define AI_V4MAPPED_CFG 0x00000200 /* accept IPv4-mapped if kernel supports */ #define AI_ADDRCONFIG 0x00000400 /* only if any address is assigned */ #define AI_V4MAPPED 0x00000800 /* accept IPv4-mapped IPv6 address */ /* special recommended flags for getipnodebyname */ #define AI_DEFAULT (AI_V4MAPPED_CFG | AI_ADDRCONFIG) struct addrinfo { int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ int ai_family; /* PF_xxx */ int ai_socktype; /* SOCK_xxx */ int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ size_t ai_addrlen; /* length of ai_addr */ char *ai_canonname; /* canonical name for hostname */ struct sockaddr *ai_addr; /* binary address */ struct addrinfo *ai_next; /* next structure in linked list */ }; extern void freeaddrinfo __P((struct addrinfo *)); extern void freehostent __P((struct hostent *)); extern char *gai_strerror __P((int)); extern int getaddrinfo __P((const char *, const char *, const struct addrinfo *, struct addrinfo **)); extern int getnameinfo __P((const struct sockaddr *, size_t, char *, size_t, char *, size_t, int)); extern struct hostent *getipnodebyaddr __P((const void *, size_t, int, int *)); extern struct hostent *getipnodebyname __P((const char *, int, int, int *)); extern int inet_pton __P((int, const char *, void *)); extern const char *inet_ntop __P((int, const void *, char *, size_t)); #endif /* HAVE_ADDRINFO */ /* * Constants for getnameinfo() */ #ifndef NI_MAXHOST #define NI_MAXHOST 1025 #endif #ifndef NI_MAXSERV #define NI_MAXSERV 32 #endif /* * Flag values for getnameinfo() */ #ifndef NI_NOFQDN #define NI_NOFQDN 0x00000001 #endif #ifndef NI_NUMERICHOST #define NI_NUMERICHOST 0x00000002 #endif #ifndef NI_NAMEREQD #define NI_NAMEREQD 0x00000004 #endif #ifndef NI_NUMERICSERV #define NI_NUMERICSERV 0x00000008 #endif #ifndef NI_DGRAM #define NI_DGRAM 0x00000010 #endif uclmmbase-1.2.16.0/src/addrsize.h0000644000175000017500000000322207057740731015441 0ustar enderender/* * Copyright (C) 1999 WIDE Project. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ #ifndef INADDRSZ #define INADDRSZ 4 /* IPv4 T_A */ #endif #ifndef IN6ADDRSZ #define IN6ADDRSZ 16 /* IPv6 T_AAAA */ #endif uclmmbase-1.2.16.0/src/asarray.c0000644000175000017500000001000707051053047015257 0ustar enderender/* * FILE: asarray.c * * AUTHORS: Orion Hodson * * Copyright (c) 1999-2000 University College London * All rights reserved. */ #ifndef HIDE_SOURCE_STRINGS static const char cvsid[] = "$Id: asarray.c,v 1.1 2000/02/11 18:34:15 ucacoxh Exp $"; #endif /* HIDE_SOURCE_STRINGS */ #include "config_unix.h" #include "config_win32.h" #include "debug.h" #include "memory.h" #include "util.h" #include "asarray.h" typedef struct s_hash_tuple { uint32_t hash; char *key; char *value; struct s_hash_tuple *next; } hash_tuple; #define ASARRAY_SIZE 11 struct _asarray { hash_tuple *table[ASARRAY_SIZE]; int32_t nitems[ASARRAY_SIZE]; }; static uint32_t asarray_hash(const char *key) { uint32_t hash = 0; while(*key != '\0') { hash = hash * 31; hash += ((uint32_t)*key) + 1; key++; } return hash; } int32_t asarray_add(asarray *pa, const char *key, const char *value) { hash_tuple *t; int row; t = (hash_tuple*)xmalloc(sizeof(hash_tuple)); if (t) { /* transfer values */ t->hash = asarray_hash(key); t->key = xstrdup(key); t->value = xstrdup(value); /* Add to table */ row = t->hash % ASARRAY_SIZE; t->next = pa->table[row]; pa->table[row] = t; pa->nitems[row]++; return TRUE; } return FALSE; } void asarray_remove(asarray *pa, const char *key) { hash_tuple **t, *e; uint32_t hash; int row; hash = asarray_hash(key); row = hash % ASARRAY_SIZE; t = &pa->table[row]; while((*t) != NULL) { if ((hash == (*t)->hash) && (strcmp(key, (*t)->key) == 0)) { e = *t; *t = e->next; xfree(e->key); xfree(e->value); xfree(e); pa->nitems[row]--; assert(pa->nitems[row] >= 0); break; } else { t = &(*t)->next; } } } const char* asarray_get_key_no(asarray *pa, int32_t index) { int32_t row = 0; index += 1; while (row < ASARRAY_SIZE && index > pa->nitems[row]) { index -= pa->nitems[row]; row++; } if (row < ASARRAY_SIZE) { hash_tuple *t; t = pa->table[row]; while(--index > 0) { assert(t->next != NULL); t = t->next; } return t->key; } return NULL; } /* asarray_lookup points value at actual value */ /* and return TRUE if key found. */ int32_t asarray_lookup(asarray *pa, const char *key, char **value) { hash_tuple *t; int row; uint32_t hash; hash = asarray_hash(key); row = hash % ASARRAY_SIZE; t = pa->table[row]; while(t != NULL) { if (t->hash == hash && strcmp(key, t->key) == 0) { *value = t->value; return TRUE; } t = t->next; } *value = NULL; return FALSE; } int32_t asarray_create(asarray **ppa) { asarray *pa; pa = (asarray*)xmalloc(sizeof(asarray)); if (pa != NULL) { memset(pa, 0, sizeof(asarray)); *ppa = pa; return TRUE; } return FALSE; } void asarray_destroy(asarray **ppa) { asarray *pa; const char *key; pa = *ppa; assert(pa != NULL); while ((key = asarray_get_key_no(pa, 0)) != NULL) { asarray_remove(pa, key); } xfree(pa); *ppa = NULL; xmemchk(); } uclmmbase-1.2.16.0/src/asarray.h0000644000175000017500000000242207051053050015260 0ustar enderender/* * FILE: asarray.h * AUTHORS: Orion Hodson * * Associative array for strings. Perloined from RAT settings code. * * Copyright (c) 1999-2000 University College London * All rights reserved. * * $Id: asarray.h,v 1.1 2000/02/11 18:34:16 ucacoxh Exp $ */ #ifndef __AS_ARRAY_H #define __AS_ARRAY_H typedef struct _asarray asarray; #if defined(__cplusplus) extern "C" { #endif /* Associative array for strings only. Makes own internal copies of * keys and values. * * Functions that return use TRUE for success and FALSE for failure. * Double pointers in arguments are filled in by the function being * called. */ int32_t asarray_create (asarray **ppa); void asarray_destroy (asarray **ppa); int32_t asarray_add (asarray *pa, const char *key, const char *value); void asarray_remove (asarray *pa, const char *key); int32_t asarray_lookup (asarray *pa, const char *key, char **value); /* asarray_get_key - gets key corresponding to index'th entry in * internal representation, has not relation to order * tuples added in. This function exists to provide easy way to drain * array one item at a time. */ const char* asarray_get_key_no(asarray *pa, int32_t index); #if defined(__cplusplus) } #endif #endif /* __AS_ARRAY_H */ uclmmbase-1.2.16.0/src/base64.c0000640000175000017500000001317607051621147014711 0ustar enderender/* * FILE: base64.c * AUTHOR: Colin Perkins * * MIME base64 encoder/decoder described in rfc1521. This code is derived * from version 2.7 of the Bellcore metamail package. * * Copyright (c) 1998-2000 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Science * Department at University College London * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. * * Copyright (c) 1991 Bell Communications Research, Inc. (Bellcore) * * Permission to use, copy, modify, and distribute this material * for any purpose and without fee is hereby granted, provided * that the above copyright notice and this permission notice * appear in all copies, and that the name of Bellcore not be * used in advertising or publicity pertaining to this * material without the specific, prior written permission * of an authorized representative of Bellcore. BELLCORE * MAKES NO REPRESENTATIONS ABOUT THE ACCURACY OR SUITABILITY * OF THIS MATERIAL FOR ANY PURPOSE. IT IS PROVIDED "AS IS", * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. * */ #include "config_unix.h" #include "config_win32.h" #include "debug.h" #include "base64.h" static unsigned char basis_64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; int base64encode(const unsigned char *input, int input_length, unsigned char *output, int output_length) { int i = 0, j = 0; int pad; assert(output_length >= (input_length * 4 / 3)); while (i < input_length) { pad = 3 - (input_length - i); if (pad == 2) { output[j ] = basis_64[input[i]>>2]; output[j+1] = basis_64[(input[i] & 0x03) << 4]; output[j+2] = '='; output[j+3] = '='; } else if (pad == 1) { output[j ] = basis_64[input[i]>>2]; output[j+1] = basis_64[((input[i] & 0x03) << 4) | ((input[i+1] & 0xf0) >> 4)]; output[j+2] = basis_64[(input[i+1] & 0x0f) << 2]; output[j+3] = '='; } else{ output[j ] = basis_64[input[i]>>2]; output[j+1] = basis_64[((input[i] & 0x03) << 4) | ((input[i+1] & 0xf0) >> 4)]; output[j+2] = basis_64[((input[i+1] & 0x0f) << 2) | ((input[i+2] & 0xc0) >> 6)]; output[j+3] = basis_64[input[i+2] & 0x3f]; } i += 3; j += 4; } return j; } /* This assumes that an unsigned char is exactly 8 bits. Not portable code! :-) */ static unsigned char index_64[128] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 62, 0xff, 0xff, 0xff, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0xff, 0xff, 0xff, 0xff, 0xff }; #define char64(c) ((c > 127) ? 0xff : index_64[(c)]) int base64decode(const unsigned char *input, int input_length, unsigned char *output, int output_length) { int i = 0, j = 0, pad; unsigned char c[4]; assert(output_length >= (input_length * 3 / 4)); assert((input_length % 4) == 0); while ((i + 3) < input_length) { pad = 0; c[0] = char64(input[i ]); pad += (c[0] == 0xff); c[1] = char64(input[i+1]); pad += (c[1] == 0xff); c[2] = char64(input[i+2]); pad += (c[2] == 0xff); c[3] = char64(input[i+3]); pad += (c[3] == 0xff); if (pad == 2) { output[j++] = (c[0] << 2) | ((c[1] & 0x30) >> 4); output[j] = (c[1] & 0x0f) << 4; } else if (pad == 1) { output[j++] = (c[0] << 2) | ((c[1] & 0x30) >> 4); output[j++] = ((c[1] & 0x0f) << 4) | ((c[2] & 0x3c) >> 2); output[j] = (c[2] & 0x03) << 6; } else { output[j++] = (c[0] << 2) | ((c[1] & 0x30) >> 4); output[j++] = ((c[1] & 0x0f) << 4) | ((c[2] & 0x3c) >> 2); output[j++] = ((c[2] & 0x03) << 6) | (c[3] & 0x3f); } i += 4; } return j; } uclmmbase-1.2.16.0/src/base64.h0000640000175000017500000000403007051621147014703 0ustar enderender/* * FILE: base64.h * AUTHORS: Colin Perkins * * Copyright (c) 1998-2000 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Science * Department at University College London * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ int base64encode(const unsigned char *input, int input_length, unsigned char *output, int output_length); int base64decode(const unsigned char *input, int input_length, unsigned char *output, int output_length); uclmmbase-1.2.16.0/src/bittypes.h0000644000175000017500000000451107057740732015502 0ustar enderender/* * Copyright (C) 1999 WIDE Project. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ #ifndef HAVE_U_INT8_T #if SIZEOF_CHAR == 1 typedef unsigned char u_int8_t; #elif SIZEOF_INT == 1 typedef unsigned int u_int8_t; #else /* XXX */ #error "there's no appropriate type for u_int8_t" #endif #endif /* HAVE_U_INT8_T */ #ifndef HAVE_U_INT16_T #if SIZEOF_SHORT == 2 typedef unsigned short u_int16_t; #elif SIZEOF_INT == 2 typedef unsigned int u_int16_t; #elif SIZEOF_CHAR == 2 typedef unsigned char u_int16_t; #else /* XXX */ #error "there's no appropriate type for u_int16_t" #endif #endif /* HAVE_U_INT16_T */ #ifndef HAVE_U_INT32_T #if SIZEOF_INT == 4 typedef unsigned int u_int32_t; #elif SIZEOF_LONG == 4 typedef unsigned long u_int32_t; #elif SIZEOF_SHORT == 4 typedef unsigned short u_int32_t; #else /* XXX */ #error "there's no appropriate type for u_int32_t" #endif #endif /* HAVE_U_INT32_T */ uclmmbase-1.2.16.0/src/boxes-fst.dat0000644000175000017500000022430407272137407016074 0ustar enderenderword8 S[256] = { 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117, 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132, 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207, 208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168, 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210, 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115, 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22 }; #ifdef INTERMEDIATE_VALUE_KAT word8 Si[256] = { 82, 9, 106, 213, 48, 54, 165, 56, 191, 64, 163, 158, 129, 243, 215, 251, 124, 227, 57, 130, 155, 47, 255, 135, 52, 142, 67, 68, 196, 222, 233, 203, 84, 123, 148, 50, 166, 194, 35, 61, 238, 76, 149, 11, 66, 250, 195, 78, 8, 46, 161, 102, 40, 217, 36, 178, 118, 91, 162, 73, 109, 139, 209, 37, 114, 248, 246, 100, 134, 104, 152, 22, 212, 164, 92, 204, 93, 101, 182, 146, 108, 112, 72, 80, 253, 237, 185, 218, 94, 21, 70, 87, 167, 141, 157, 132, 144, 216, 171, 0, 140, 188, 211, 10, 247, 228, 88, 5, 184, 179, 69, 6, 208, 44, 30, 143, 202, 63, 15, 2, 193, 175, 189, 3, 1, 19, 138, 107, 58, 145, 17, 65, 79, 103, 220, 234, 151, 242, 207, 206, 240, 180, 230, 115, 150, 172, 116, 34, 231, 173, 53, 133, 226, 249, 55, 232, 28, 117, 223, 110, 71, 241, 26, 113, 29, 41, 197, 137, 111, 183, 98, 14, 170, 24, 190, 27, 252, 86, 62, 75, 198, 210, 121, 32, 154, 219, 192, 254, 120, 205, 90, 244, 31, 221, 168, 51, 136, 7, 199, 49, 177, 18, 16, 89, 39, 128, 236, 95, 96, 81, 127, 169, 25, 181, 74, 13, 45, 229, 122, 159, 147, 201, 156, 239, 160, 224, 59, 77, 174, 42, 245, 176, 200, 235, 187, 60, 131, 83, 153, 97, 23, 43, 4, 126, 186, 119, 214, 38, 225, 105, 20, 99, 85, 33, 12, 125 }; #endif /* INTERMEDIATE_VALUE_KAT */ word8 T1[256][4] = { {0xc6,0x63,0x63,0xa5}, {0xf8,0x7c,0x7c,0x84}, {0xee,0x77,0x77,0x99}, {0xf6,0x7b,0x7b,0x8d}, {0xff,0xf2,0xf2,0x0d}, {0xd6,0x6b,0x6b,0xbd}, {0xde,0x6f,0x6f,0xb1}, {0x91,0xc5,0xc5,0x54}, {0x60,0x30,0x30,0x50}, {0x02,0x01,0x01,0x03}, {0xce,0x67,0x67,0xa9}, {0x56,0x2b,0x2b,0x7d}, {0xe7,0xfe,0xfe,0x19}, {0xb5,0xd7,0xd7,0x62}, {0x4d,0xab,0xab,0xe6}, {0xec,0x76,0x76,0x9a}, {0x8f,0xca,0xca,0x45}, {0x1f,0x82,0x82,0x9d}, {0x89,0xc9,0xc9,0x40}, {0xfa,0x7d,0x7d,0x87}, {0xef,0xfa,0xfa,0x15}, {0xb2,0x59,0x59,0xeb}, {0x8e,0x47,0x47,0xc9}, {0xfb,0xf0,0xf0,0x0b}, {0x41,0xad,0xad,0xec}, {0xb3,0xd4,0xd4,0x67}, {0x5f,0xa2,0xa2,0xfd}, {0x45,0xaf,0xaf,0xea}, {0x23,0x9c,0x9c,0xbf}, {0x53,0xa4,0xa4,0xf7}, {0xe4,0x72,0x72,0x96}, {0x9b,0xc0,0xc0,0x5b}, {0x75,0xb7,0xb7,0xc2}, {0xe1,0xfd,0xfd,0x1c}, {0x3d,0x93,0x93,0xae}, {0x4c,0x26,0x26,0x6a}, {0x6c,0x36,0x36,0x5a}, {0x7e,0x3f,0x3f,0x41}, {0xf5,0xf7,0xf7,0x02}, {0x83,0xcc,0xcc,0x4f}, {0x68,0x34,0x34,0x5c}, {0x51,0xa5,0xa5,0xf4}, {0xd1,0xe5,0xe5,0x34}, {0xf9,0xf1,0xf1,0x08}, {0xe2,0x71,0x71,0x93}, {0xab,0xd8,0xd8,0x73}, {0x62,0x31,0x31,0x53}, {0x2a,0x15,0x15,0x3f}, {0x08,0x04,0x04,0x0c}, {0x95,0xc7,0xc7,0x52}, {0x46,0x23,0x23,0x65}, {0x9d,0xc3,0xc3,0x5e}, {0x30,0x18,0x18,0x28}, {0x37,0x96,0x96,0xa1}, {0x0a,0x05,0x05,0x0f}, {0x2f,0x9a,0x9a,0xb5}, {0x0e,0x07,0x07,0x09}, {0x24,0x12,0x12,0x36}, {0x1b,0x80,0x80,0x9b}, {0xdf,0xe2,0xe2,0x3d}, {0xcd,0xeb,0xeb,0x26}, {0x4e,0x27,0x27,0x69}, {0x7f,0xb2,0xb2,0xcd}, {0xea,0x75,0x75,0x9f}, {0x12,0x09,0x09,0x1b}, {0x1d,0x83,0x83,0x9e}, {0x58,0x2c,0x2c,0x74}, {0x34,0x1a,0x1a,0x2e}, {0x36,0x1b,0x1b,0x2d}, {0xdc,0x6e,0x6e,0xb2}, {0xb4,0x5a,0x5a,0xee}, {0x5b,0xa0,0xa0,0xfb}, {0xa4,0x52,0x52,0xf6}, {0x76,0x3b,0x3b,0x4d}, {0xb7,0xd6,0xd6,0x61}, {0x7d,0xb3,0xb3,0xce}, {0x52,0x29,0x29,0x7b}, {0xdd,0xe3,0xe3,0x3e}, {0x5e,0x2f,0x2f,0x71}, {0x13,0x84,0x84,0x97}, {0xa6,0x53,0x53,0xf5}, {0xb9,0xd1,0xd1,0x68}, {0x00,0x00,0x00,0x00}, {0xc1,0xed,0xed,0x2c}, {0x40,0x20,0x20,0x60}, {0xe3,0xfc,0xfc,0x1f}, {0x79,0xb1,0xb1,0xc8}, {0xb6,0x5b,0x5b,0xed}, {0xd4,0x6a,0x6a,0xbe}, {0x8d,0xcb,0xcb,0x46}, {0x67,0xbe,0xbe,0xd9}, {0x72,0x39,0x39,0x4b}, {0x94,0x4a,0x4a,0xde}, {0x98,0x4c,0x4c,0xd4}, {0xb0,0x58,0x58,0xe8}, {0x85,0xcf,0xcf,0x4a}, {0xbb,0xd0,0xd0,0x6b}, {0xc5,0xef,0xef,0x2a}, {0x4f,0xaa,0xaa,0xe5}, {0xed,0xfb,0xfb,0x16}, {0x86,0x43,0x43,0xc5}, {0x9a,0x4d,0x4d,0xd7}, {0x66,0x33,0x33,0x55}, {0x11,0x85,0x85,0x94}, {0x8a,0x45,0x45,0xcf}, {0xe9,0xf9,0xf9,0x10}, {0x04,0x02,0x02,0x06}, {0xfe,0x7f,0x7f,0x81}, {0xa0,0x50,0x50,0xf0}, {0x78,0x3c,0x3c,0x44}, {0x25,0x9f,0x9f,0xba}, {0x4b,0xa8,0xa8,0xe3}, {0xa2,0x51,0x51,0xf3}, {0x5d,0xa3,0xa3,0xfe}, {0x80,0x40,0x40,0xc0}, {0x05,0x8f,0x8f,0x8a}, {0x3f,0x92,0x92,0xad}, {0x21,0x9d,0x9d,0xbc}, {0x70,0x38,0x38,0x48}, {0xf1,0xf5,0xf5,0x04}, {0x63,0xbc,0xbc,0xdf}, {0x77,0xb6,0xb6,0xc1}, {0xaf,0xda,0xda,0x75}, {0x42,0x21,0x21,0x63}, {0x20,0x10,0x10,0x30}, {0xe5,0xff,0xff,0x1a}, {0xfd,0xf3,0xf3,0x0e}, {0xbf,0xd2,0xd2,0x6d}, {0x81,0xcd,0xcd,0x4c}, {0x18,0x0c,0x0c,0x14}, {0x26,0x13,0x13,0x35}, {0xc3,0xec,0xec,0x2f}, {0xbe,0x5f,0x5f,0xe1}, {0x35,0x97,0x97,0xa2}, {0x88,0x44,0x44,0xcc}, {0x2e,0x17,0x17,0x39}, {0x93,0xc4,0xc4,0x57}, {0x55,0xa7,0xa7,0xf2}, {0xfc,0x7e,0x7e,0x82}, {0x7a,0x3d,0x3d,0x47}, {0xc8,0x64,0x64,0xac}, {0xba,0x5d,0x5d,0xe7}, {0x32,0x19,0x19,0x2b}, {0xe6,0x73,0x73,0x95}, {0xc0,0x60,0x60,0xa0}, {0x19,0x81,0x81,0x98}, {0x9e,0x4f,0x4f,0xd1}, {0xa3,0xdc,0xdc,0x7f}, {0x44,0x22,0x22,0x66}, {0x54,0x2a,0x2a,0x7e}, {0x3b,0x90,0x90,0xab}, {0x0b,0x88,0x88,0x83}, {0x8c,0x46,0x46,0xca}, {0xc7,0xee,0xee,0x29}, {0x6b,0xb8,0xb8,0xd3}, {0x28,0x14,0x14,0x3c}, {0xa7,0xde,0xde,0x79}, {0xbc,0x5e,0x5e,0xe2}, {0x16,0x0b,0x0b,0x1d}, {0xad,0xdb,0xdb,0x76}, {0xdb,0xe0,0xe0,0x3b}, {0x64,0x32,0x32,0x56}, {0x74,0x3a,0x3a,0x4e}, {0x14,0x0a,0x0a,0x1e}, {0x92,0x49,0x49,0xdb}, {0x0c,0x06,0x06,0x0a}, {0x48,0x24,0x24,0x6c}, {0xb8,0x5c,0x5c,0xe4}, {0x9f,0xc2,0xc2,0x5d}, {0xbd,0xd3,0xd3,0x6e}, {0x43,0xac,0xac,0xef}, {0xc4,0x62,0x62,0xa6}, {0x39,0x91,0x91,0xa8}, {0x31,0x95,0x95,0xa4}, {0xd3,0xe4,0xe4,0x37}, {0xf2,0x79,0x79,0x8b}, {0xd5,0xe7,0xe7,0x32}, {0x8b,0xc8,0xc8,0x43}, {0x6e,0x37,0x37,0x59}, {0xda,0x6d,0x6d,0xb7}, {0x01,0x8d,0x8d,0x8c}, {0xb1,0xd5,0xd5,0x64}, {0x9c,0x4e,0x4e,0xd2}, {0x49,0xa9,0xa9,0xe0}, {0xd8,0x6c,0x6c,0xb4}, {0xac,0x56,0x56,0xfa}, {0xf3,0xf4,0xf4,0x07}, {0xcf,0xea,0xea,0x25}, {0xca,0x65,0x65,0xaf}, {0xf4,0x7a,0x7a,0x8e}, {0x47,0xae,0xae,0xe9}, {0x10,0x08,0x08,0x18}, {0x6f,0xba,0xba,0xd5}, {0xf0,0x78,0x78,0x88}, {0x4a,0x25,0x25,0x6f}, {0x5c,0x2e,0x2e,0x72}, {0x38,0x1c,0x1c,0x24}, {0x57,0xa6,0xa6,0xf1}, {0x73,0xb4,0xb4,0xc7}, {0x97,0xc6,0xc6,0x51}, {0xcb,0xe8,0xe8,0x23}, {0xa1,0xdd,0xdd,0x7c}, {0xe8,0x74,0x74,0x9c}, {0x3e,0x1f,0x1f,0x21}, {0x96,0x4b,0x4b,0xdd}, {0x61,0xbd,0xbd,0xdc}, {0x0d,0x8b,0x8b,0x86}, {0x0f,0x8a,0x8a,0x85}, {0xe0,0x70,0x70,0x90}, {0x7c,0x3e,0x3e,0x42}, {0x71,0xb5,0xb5,0xc4}, {0xcc,0x66,0x66,0xaa}, {0x90,0x48,0x48,0xd8}, {0x06,0x03,0x03,0x05}, {0xf7,0xf6,0xf6,0x01}, {0x1c,0x0e,0x0e,0x12}, {0xc2,0x61,0x61,0xa3}, {0x6a,0x35,0x35,0x5f}, {0xae,0x57,0x57,0xf9}, {0x69,0xb9,0xb9,0xd0}, {0x17,0x86,0x86,0x91}, {0x99,0xc1,0xc1,0x58}, {0x3a,0x1d,0x1d,0x27}, {0x27,0x9e,0x9e,0xb9}, {0xd9,0xe1,0xe1,0x38}, {0xeb,0xf8,0xf8,0x13}, {0x2b,0x98,0x98,0xb3}, {0x22,0x11,0x11,0x33}, {0xd2,0x69,0x69,0xbb}, {0xa9,0xd9,0xd9,0x70}, {0x07,0x8e,0x8e,0x89}, {0x33,0x94,0x94,0xa7}, {0x2d,0x9b,0x9b,0xb6}, {0x3c,0x1e,0x1e,0x22}, {0x15,0x87,0x87,0x92}, {0xc9,0xe9,0xe9,0x20}, {0x87,0xce,0xce,0x49}, {0xaa,0x55,0x55,0xff}, {0x50,0x28,0x28,0x78}, {0xa5,0xdf,0xdf,0x7a}, {0x03,0x8c,0x8c,0x8f}, {0x59,0xa1,0xa1,0xf8}, {0x09,0x89,0x89,0x80}, {0x1a,0x0d,0x0d,0x17}, {0x65,0xbf,0xbf,0xda}, {0xd7,0xe6,0xe6,0x31}, {0x84,0x42,0x42,0xc6}, {0xd0,0x68,0x68,0xb8}, {0x82,0x41,0x41,0xc3}, {0x29,0x99,0x99,0xb0}, {0x5a,0x2d,0x2d,0x77}, {0x1e,0x0f,0x0f,0x11}, {0x7b,0xb0,0xb0,0xcb}, {0xa8,0x54,0x54,0xfc}, {0x6d,0xbb,0xbb,0xd6}, {0x2c,0x16,0x16,0x3a} }; word8 T2[256][4] = { {0xa5,0xc6,0x63,0x63}, {0x84,0xf8,0x7c,0x7c}, {0x99,0xee,0x77,0x77}, {0x8d,0xf6,0x7b,0x7b}, {0x0d,0xff,0xf2,0xf2}, {0xbd,0xd6,0x6b,0x6b}, {0xb1,0xde,0x6f,0x6f}, {0x54,0x91,0xc5,0xc5}, {0x50,0x60,0x30,0x30}, {0x03,0x02,0x01,0x01}, {0xa9,0xce,0x67,0x67}, {0x7d,0x56,0x2b,0x2b}, {0x19,0xe7,0xfe,0xfe}, {0x62,0xb5,0xd7,0xd7}, {0xe6,0x4d,0xab,0xab}, {0x9a,0xec,0x76,0x76}, {0x45,0x8f,0xca,0xca}, {0x9d,0x1f,0x82,0x82}, {0x40,0x89,0xc9,0xc9}, {0x87,0xfa,0x7d,0x7d}, {0x15,0xef,0xfa,0xfa}, {0xeb,0xb2,0x59,0x59}, {0xc9,0x8e,0x47,0x47}, {0x0b,0xfb,0xf0,0xf0}, {0xec,0x41,0xad,0xad}, {0x67,0xb3,0xd4,0xd4}, {0xfd,0x5f,0xa2,0xa2}, {0xea,0x45,0xaf,0xaf}, {0xbf,0x23,0x9c,0x9c}, {0xf7,0x53,0xa4,0xa4}, {0x96,0xe4,0x72,0x72}, {0x5b,0x9b,0xc0,0xc0}, {0xc2,0x75,0xb7,0xb7}, {0x1c,0xe1,0xfd,0xfd}, {0xae,0x3d,0x93,0x93}, {0x6a,0x4c,0x26,0x26}, {0x5a,0x6c,0x36,0x36}, {0x41,0x7e,0x3f,0x3f}, {0x02,0xf5,0xf7,0xf7}, {0x4f,0x83,0xcc,0xcc}, {0x5c,0x68,0x34,0x34}, {0xf4,0x51,0xa5,0xa5}, {0x34,0xd1,0xe5,0xe5}, {0x08,0xf9,0xf1,0xf1}, {0x93,0xe2,0x71,0x71}, {0x73,0xab,0xd8,0xd8}, {0x53,0x62,0x31,0x31}, {0x3f,0x2a,0x15,0x15}, {0x0c,0x08,0x04,0x04}, {0x52,0x95,0xc7,0xc7}, {0x65,0x46,0x23,0x23}, {0x5e,0x9d,0xc3,0xc3}, {0x28,0x30,0x18,0x18}, {0xa1,0x37,0x96,0x96}, {0x0f,0x0a,0x05,0x05}, {0xb5,0x2f,0x9a,0x9a}, {0x09,0x0e,0x07,0x07}, {0x36,0x24,0x12,0x12}, {0x9b,0x1b,0x80,0x80}, {0x3d,0xdf,0xe2,0xe2}, {0x26,0xcd,0xeb,0xeb}, {0x69,0x4e,0x27,0x27}, {0xcd,0x7f,0xb2,0xb2}, {0x9f,0xea,0x75,0x75}, {0x1b,0x12,0x09,0x09}, {0x9e,0x1d,0x83,0x83}, {0x74,0x58,0x2c,0x2c}, {0x2e,0x34,0x1a,0x1a}, {0x2d,0x36,0x1b,0x1b}, {0xb2,0xdc,0x6e,0x6e}, {0xee,0xb4,0x5a,0x5a}, {0xfb,0x5b,0xa0,0xa0}, {0xf6,0xa4,0x52,0x52}, {0x4d,0x76,0x3b,0x3b}, {0x61,0xb7,0xd6,0xd6}, {0xce,0x7d,0xb3,0xb3}, {0x7b,0x52,0x29,0x29}, {0x3e,0xdd,0xe3,0xe3}, {0x71,0x5e,0x2f,0x2f}, {0x97,0x13,0x84,0x84}, {0xf5,0xa6,0x53,0x53}, {0x68,0xb9,0xd1,0xd1}, {0x00,0x00,0x00,0x00}, {0x2c,0xc1,0xed,0xed}, {0x60,0x40,0x20,0x20}, {0x1f,0xe3,0xfc,0xfc}, {0xc8,0x79,0xb1,0xb1}, {0xed,0xb6,0x5b,0x5b}, {0xbe,0xd4,0x6a,0x6a}, {0x46,0x8d,0xcb,0xcb}, {0xd9,0x67,0xbe,0xbe}, {0x4b,0x72,0x39,0x39}, {0xde,0x94,0x4a,0x4a}, {0xd4,0x98,0x4c,0x4c}, {0xe8,0xb0,0x58,0x58}, {0x4a,0x85,0xcf,0xcf}, {0x6b,0xbb,0xd0,0xd0}, {0x2a,0xc5,0xef,0xef}, {0xe5,0x4f,0xaa,0xaa}, {0x16,0xed,0xfb,0xfb}, {0xc5,0x86,0x43,0x43}, {0xd7,0x9a,0x4d,0x4d}, {0x55,0x66,0x33,0x33}, {0x94,0x11,0x85,0x85}, {0xcf,0x8a,0x45,0x45}, {0x10,0xe9,0xf9,0xf9}, {0x06,0x04,0x02,0x02}, {0x81,0xfe,0x7f,0x7f}, {0xf0,0xa0,0x50,0x50}, {0x44,0x78,0x3c,0x3c}, {0xba,0x25,0x9f,0x9f}, {0xe3,0x4b,0xa8,0xa8}, {0xf3,0xa2,0x51,0x51}, {0xfe,0x5d,0xa3,0xa3}, {0xc0,0x80,0x40,0x40}, {0x8a,0x05,0x8f,0x8f}, {0xad,0x3f,0x92,0x92}, {0xbc,0x21,0x9d,0x9d}, {0x48,0x70,0x38,0x38}, {0x04,0xf1,0xf5,0xf5}, {0xdf,0x63,0xbc,0xbc}, {0xc1,0x77,0xb6,0xb6}, {0x75,0xaf,0xda,0xda}, {0x63,0x42,0x21,0x21}, {0x30,0x20,0x10,0x10}, {0x1a,0xe5,0xff,0xff}, {0x0e,0xfd,0xf3,0xf3}, {0x6d,0xbf,0xd2,0xd2}, {0x4c,0x81,0xcd,0xcd}, {0x14,0x18,0x0c,0x0c}, {0x35,0x26,0x13,0x13}, {0x2f,0xc3,0xec,0xec}, {0xe1,0xbe,0x5f,0x5f}, {0xa2,0x35,0x97,0x97}, {0xcc,0x88,0x44,0x44}, {0x39,0x2e,0x17,0x17}, {0x57,0x93,0xc4,0xc4}, {0xf2,0x55,0xa7,0xa7}, {0x82,0xfc,0x7e,0x7e}, {0x47,0x7a,0x3d,0x3d}, {0xac,0xc8,0x64,0x64}, {0xe7,0xba,0x5d,0x5d}, {0x2b,0x32,0x19,0x19}, {0x95,0xe6,0x73,0x73}, {0xa0,0xc0,0x60,0x60}, {0x98,0x19,0x81,0x81}, {0xd1,0x9e,0x4f,0x4f}, {0x7f,0xa3,0xdc,0xdc}, {0x66,0x44,0x22,0x22}, {0x7e,0x54,0x2a,0x2a}, {0xab,0x3b,0x90,0x90}, {0x83,0x0b,0x88,0x88}, {0xca,0x8c,0x46,0x46}, {0x29,0xc7,0xee,0xee}, {0xd3,0x6b,0xb8,0xb8}, {0x3c,0x28,0x14,0x14}, {0x79,0xa7,0xde,0xde}, {0xe2,0xbc,0x5e,0x5e}, {0x1d,0x16,0x0b,0x0b}, {0x76,0xad,0xdb,0xdb}, {0x3b,0xdb,0xe0,0xe0}, {0x56,0x64,0x32,0x32}, {0x4e,0x74,0x3a,0x3a}, {0x1e,0x14,0x0a,0x0a}, {0xdb,0x92,0x49,0x49}, {0x0a,0x0c,0x06,0x06}, {0x6c,0x48,0x24,0x24}, {0xe4,0xb8,0x5c,0x5c}, {0x5d,0x9f,0xc2,0xc2}, {0x6e,0xbd,0xd3,0xd3}, {0xef,0x43,0xac,0xac}, {0xa6,0xc4,0x62,0x62}, {0xa8,0x39,0x91,0x91}, {0xa4,0x31,0x95,0x95}, {0x37,0xd3,0xe4,0xe4}, {0x8b,0xf2,0x79,0x79}, {0x32,0xd5,0xe7,0xe7}, {0x43,0x8b,0xc8,0xc8}, {0x59,0x6e,0x37,0x37}, {0xb7,0xda,0x6d,0x6d}, {0x8c,0x01,0x8d,0x8d}, {0x64,0xb1,0xd5,0xd5}, {0xd2,0x9c,0x4e,0x4e}, {0xe0,0x49,0xa9,0xa9}, {0xb4,0xd8,0x6c,0x6c}, {0xfa,0xac,0x56,0x56}, {0x07,0xf3,0xf4,0xf4}, {0x25,0xcf,0xea,0xea}, {0xaf,0xca,0x65,0x65}, {0x8e,0xf4,0x7a,0x7a}, {0xe9,0x47,0xae,0xae}, {0x18,0x10,0x08,0x08}, {0xd5,0x6f,0xba,0xba}, {0x88,0xf0,0x78,0x78}, {0x6f,0x4a,0x25,0x25}, {0x72,0x5c,0x2e,0x2e}, {0x24,0x38,0x1c,0x1c}, {0xf1,0x57,0xa6,0xa6}, {0xc7,0x73,0xb4,0xb4}, {0x51,0x97,0xc6,0xc6}, {0x23,0xcb,0xe8,0xe8}, {0x7c,0xa1,0xdd,0xdd}, {0x9c,0xe8,0x74,0x74}, {0x21,0x3e,0x1f,0x1f}, {0xdd,0x96,0x4b,0x4b}, {0xdc,0x61,0xbd,0xbd}, {0x86,0x0d,0x8b,0x8b}, {0x85,0x0f,0x8a,0x8a}, {0x90,0xe0,0x70,0x70}, {0x42,0x7c,0x3e,0x3e}, {0xc4,0x71,0xb5,0xb5}, {0xaa,0xcc,0x66,0x66}, {0xd8,0x90,0x48,0x48}, {0x05,0x06,0x03,0x03}, {0x01,0xf7,0xf6,0xf6}, {0x12,0x1c,0x0e,0x0e}, {0xa3,0xc2,0x61,0x61}, {0x5f,0x6a,0x35,0x35}, {0xf9,0xae,0x57,0x57}, {0xd0,0x69,0xb9,0xb9}, {0x91,0x17,0x86,0x86}, {0x58,0x99,0xc1,0xc1}, {0x27,0x3a,0x1d,0x1d}, {0xb9,0x27,0x9e,0x9e}, {0x38,0xd9,0xe1,0xe1}, {0x13,0xeb,0xf8,0xf8}, {0xb3,0x2b,0x98,0x98}, {0x33,0x22,0x11,0x11}, {0xbb,0xd2,0x69,0x69}, {0x70,0xa9,0xd9,0xd9}, {0x89,0x07,0x8e,0x8e}, {0xa7,0x33,0x94,0x94}, {0xb6,0x2d,0x9b,0x9b}, {0x22,0x3c,0x1e,0x1e}, {0x92,0x15,0x87,0x87}, {0x20,0xc9,0xe9,0xe9}, {0x49,0x87,0xce,0xce}, {0xff,0xaa,0x55,0x55}, {0x78,0x50,0x28,0x28}, {0x7a,0xa5,0xdf,0xdf}, {0x8f,0x03,0x8c,0x8c}, {0xf8,0x59,0xa1,0xa1}, {0x80,0x09,0x89,0x89}, {0x17,0x1a,0x0d,0x0d}, {0xda,0x65,0xbf,0xbf}, {0x31,0xd7,0xe6,0xe6}, {0xc6,0x84,0x42,0x42}, {0xb8,0xd0,0x68,0x68}, {0xc3,0x82,0x41,0x41}, {0xb0,0x29,0x99,0x99}, {0x77,0x5a,0x2d,0x2d}, {0x11,0x1e,0x0f,0x0f}, {0xcb,0x7b,0xb0,0xb0}, {0xfc,0xa8,0x54,0x54}, {0xd6,0x6d,0xbb,0xbb}, {0x3a,0x2c,0x16,0x16} }; word8 T3[256][4] = { {0x63,0xa5,0xc6,0x63}, {0x7c,0x84,0xf8,0x7c}, {0x77,0x99,0xee,0x77}, {0x7b,0x8d,0xf6,0x7b}, {0xf2,0x0d,0xff,0xf2}, {0x6b,0xbd,0xd6,0x6b}, {0x6f,0xb1,0xde,0x6f}, {0xc5,0x54,0x91,0xc5}, {0x30,0x50,0x60,0x30}, {0x01,0x03,0x02,0x01}, {0x67,0xa9,0xce,0x67}, {0x2b,0x7d,0x56,0x2b}, {0xfe,0x19,0xe7,0xfe}, {0xd7,0x62,0xb5,0xd7}, {0xab,0xe6,0x4d,0xab}, {0x76,0x9a,0xec,0x76}, {0xca,0x45,0x8f,0xca}, {0x82,0x9d,0x1f,0x82}, {0xc9,0x40,0x89,0xc9}, {0x7d,0x87,0xfa,0x7d}, {0xfa,0x15,0xef,0xfa}, {0x59,0xeb,0xb2,0x59}, {0x47,0xc9,0x8e,0x47}, {0xf0,0x0b,0xfb,0xf0}, {0xad,0xec,0x41,0xad}, {0xd4,0x67,0xb3,0xd4}, {0xa2,0xfd,0x5f,0xa2}, {0xaf,0xea,0x45,0xaf}, {0x9c,0xbf,0x23,0x9c}, {0xa4,0xf7,0x53,0xa4}, {0x72,0x96,0xe4,0x72}, {0xc0,0x5b,0x9b,0xc0}, {0xb7,0xc2,0x75,0xb7}, {0xfd,0x1c,0xe1,0xfd}, {0x93,0xae,0x3d,0x93}, {0x26,0x6a,0x4c,0x26}, {0x36,0x5a,0x6c,0x36}, {0x3f,0x41,0x7e,0x3f}, {0xf7,0x02,0xf5,0xf7}, {0xcc,0x4f,0x83,0xcc}, {0x34,0x5c,0x68,0x34}, {0xa5,0xf4,0x51,0xa5}, {0xe5,0x34,0xd1,0xe5}, {0xf1,0x08,0xf9,0xf1}, {0x71,0x93,0xe2,0x71}, {0xd8,0x73,0xab,0xd8}, {0x31,0x53,0x62,0x31}, {0x15,0x3f,0x2a,0x15}, {0x04,0x0c,0x08,0x04}, {0xc7,0x52,0x95,0xc7}, {0x23,0x65,0x46,0x23}, {0xc3,0x5e,0x9d,0xc3}, {0x18,0x28,0x30,0x18}, {0x96,0xa1,0x37,0x96}, {0x05,0x0f,0x0a,0x05}, {0x9a,0xb5,0x2f,0x9a}, {0x07,0x09,0x0e,0x07}, {0x12,0x36,0x24,0x12}, {0x80,0x9b,0x1b,0x80}, {0xe2,0x3d,0xdf,0xe2}, {0xeb,0x26,0xcd,0xeb}, {0x27,0x69,0x4e,0x27}, {0xb2,0xcd,0x7f,0xb2}, {0x75,0x9f,0xea,0x75}, {0x09,0x1b,0x12,0x09}, {0x83,0x9e,0x1d,0x83}, {0x2c,0x74,0x58,0x2c}, {0x1a,0x2e,0x34,0x1a}, {0x1b,0x2d,0x36,0x1b}, {0x6e,0xb2,0xdc,0x6e}, {0x5a,0xee,0xb4,0x5a}, {0xa0,0xfb,0x5b,0xa0}, {0x52,0xf6,0xa4,0x52}, {0x3b,0x4d,0x76,0x3b}, {0xd6,0x61,0xb7,0xd6}, {0xb3,0xce,0x7d,0xb3}, {0x29,0x7b,0x52,0x29}, {0xe3,0x3e,0xdd,0xe3}, {0x2f,0x71,0x5e,0x2f}, {0x84,0x97,0x13,0x84}, {0x53,0xf5,0xa6,0x53}, {0xd1,0x68,0xb9,0xd1}, {0x00,0x00,0x00,0x00}, {0xed,0x2c,0xc1,0xed}, {0x20,0x60,0x40,0x20}, {0xfc,0x1f,0xe3,0xfc}, {0xb1,0xc8,0x79,0xb1}, {0x5b,0xed,0xb6,0x5b}, {0x6a,0xbe,0xd4,0x6a}, {0xcb,0x46,0x8d,0xcb}, {0xbe,0xd9,0x67,0xbe}, {0x39,0x4b,0x72,0x39}, {0x4a,0xde,0x94,0x4a}, {0x4c,0xd4,0x98,0x4c}, {0x58,0xe8,0xb0,0x58}, {0xcf,0x4a,0x85,0xcf}, {0xd0,0x6b,0xbb,0xd0}, {0xef,0x2a,0xc5,0xef}, {0xaa,0xe5,0x4f,0xaa}, {0xfb,0x16,0xed,0xfb}, {0x43,0xc5,0x86,0x43}, {0x4d,0xd7,0x9a,0x4d}, {0x33,0x55,0x66,0x33}, {0x85,0x94,0x11,0x85}, {0x45,0xcf,0x8a,0x45}, {0xf9,0x10,0xe9,0xf9}, {0x02,0x06,0x04,0x02}, {0x7f,0x81,0xfe,0x7f}, {0x50,0xf0,0xa0,0x50}, {0x3c,0x44,0x78,0x3c}, {0x9f,0xba,0x25,0x9f}, {0xa8,0xe3,0x4b,0xa8}, {0x51,0xf3,0xa2,0x51}, {0xa3,0xfe,0x5d,0xa3}, {0x40,0xc0,0x80,0x40}, {0x8f,0x8a,0x05,0x8f}, {0x92,0xad,0x3f,0x92}, {0x9d,0xbc,0x21,0x9d}, {0x38,0x48,0x70,0x38}, {0xf5,0x04,0xf1,0xf5}, {0xbc,0xdf,0x63,0xbc}, {0xb6,0xc1,0x77,0xb6}, {0xda,0x75,0xaf,0xda}, {0x21,0x63,0x42,0x21}, {0x10,0x30,0x20,0x10}, {0xff,0x1a,0xe5,0xff}, {0xf3,0x0e,0xfd,0xf3}, {0xd2,0x6d,0xbf,0xd2}, {0xcd,0x4c,0x81,0xcd}, {0x0c,0x14,0x18,0x0c}, {0x13,0x35,0x26,0x13}, {0xec,0x2f,0xc3,0xec}, {0x5f,0xe1,0xbe,0x5f}, {0x97,0xa2,0x35,0x97}, {0x44,0xcc,0x88,0x44}, {0x17,0x39,0x2e,0x17}, {0xc4,0x57,0x93,0xc4}, {0xa7,0xf2,0x55,0xa7}, {0x7e,0x82,0xfc,0x7e}, {0x3d,0x47,0x7a,0x3d}, {0x64,0xac,0xc8,0x64}, {0x5d,0xe7,0xba,0x5d}, {0x19,0x2b,0x32,0x19}, {0x73,0x95,0xe6,0x73}, {0x60,0xa0,0xc0,0x60}, {0x81,0x98,0x19,0x81}, {0x4f,0xd1,0x9e,0x4f}, {0xdc,0x7f,0xa3,0xdc}, {0x22,0x66,0x44,0x22}, {0x2a,0x7e,0x54,0x2a}, {0x90,0xab,0x3b,0x90}, {0x88,0x83,0x0b,0x88}, {0x46,0xca,0x8c,0x46}, {0xee,0x29,0xc7,0xee}, {0xb8,0xd3,0x6b,0xb8}, {0x14,0x3c,0x28,0x14}, {0xde,0x79,0xa7,0xde}, {0x5e,0xe2,0xbc,0x5e}, {0x0b,0x1d,0x16,0x0b}, {0xdb,0x76,0xad,0xdb}, {0xe0,0x3b,0xdb,0xe0}, {0x32,0x56,0x64,0x32}, {0x3a,0x4e,0x74,0x3a}, {0x0a,0x1e,0x14,0x0a}, {0x49,0xdb,0x92,0x49}, {0x06,0x0a,0x0c,0x06}, {0x24,0x6c,0x48,0x24}, {0x5c,0xe4,0xb8,0x5c}, {0xc2,0x5d,0x9f,0xc2}, {0xd3,0x6e,0xbd,0xd3}, {0xac,0xef,0x43,0xac}, {0x62,0xa6,0xc4,0x62}, {0x91,0xa8,0x39,0x91}, {0x95,0xa4,0x31,0x95}, {0xe4,0x37,0xd3,0xe4}, {0x79,0x8b,0xf2,0x79}, {0xe7,0x32,0xd5,0xe7}, {0xc8,0x43,0x8b,0xc8}, {0x37,0x59,0x6e,0x37}, {0x6d,0xb7,0xda,0x6d}, {0x8d,0x8c,0x01,0x8d}, {0xd5,0x64,0xb1,0xd5}, {0x4e,0xd2,0x9c,0x4e}, {0xa9,0xe0,0x49,0xa9}, {0x6c,0xb4,0xd8,0x6c}, {0x56,0xfa,0xac,0x56}, {0xf4,0x07,0xf3,0xf4}, {0xea,0x25,0xcf,0xea}, {0x65,0xaf,0xca,0x65}, {0x7a,0x8e,0xf4,0x7a}, {0xae,0xe9,0x47,0xae}, {0x08,0x18,0x10,0x08}, {0xba,0xd5,0x6f,0xba}, {0x78,0x88,0xf0,0x78}, {0x25,0x6f,0x4a,0x25}, {0x2e,0x72,0x5c,0x2e}, {0x1c,0x24,0x38,0x1c}, {0xa6,0xf1,0x57,0xa6}, {0xb4,0xc7,0x73,0xb4}, {0xc6,0x51,0x97,0xc6}, {0xe8,0x23,0xcb,0xe8}, {0xdd,0x7c,0xa1,0xdd}, {0x74,0x9c,0xe8,0x74}, {0x1f,0x21,0x3e,0x1f}, {0x4b,0xdd,0x96,0x4b}, {0xbd,0xdc,0x61,0xbd}, {0x8b,0x86,0x0d,0x8b}, {0x8a,0x85,0x0f,0x8a}, {0x70,0x90,0xe0,0x70}, {0x3e,0x42,0x7c,0x3e}, {0xb5,0xc4,0x71,0xb5}, {0x66,0xaa,0xcc,0x66}, {0x48,0xd8,0x90,0x48}, {0x03,0x05,0x06,0x03}, {0xf6,0x01,0xf7,0xf6}, {0x0e,0x12,0x1c,0x0e}, {0x61,0xa3,0xc2,0x61}, {0x35,0x5f,0x6a,0x35}, {0x57,0xf9,0xae,0x57}, {0xb9,0xd0,0x69,0xb9}, {0x86,0x91,0x17,0x86}, {0xc1,0x58,0x99,0xc1}, {0x1d,0x27,0x3a,0x1d}, {0x9e,0xb9,0x27,0x9e}, {0xe1,0x38,0xd9,0xe1}, {0xf8,0x13,0xeb,0xf8}, {0x98,0xb3,0x2b,0x98}, {0x11,0x33,0x22,0x11}, {0x69,0xbb,0xd2,0x69}, {0xd9,0x70,0xa9,0xd9}, {0x8e,0x89,0x07,0x8e}, {0x94,0xa7,0x33,0x94}, {0x9b,0xb6,0x2d,0x9b}, {0x1e,0x22,0x3c,0x1e}, {0x87,0x92,0x15,0x87}, {0xe9,0x20,0xc9,0xe9}, {0xce,0x49,0x87,0xce}, {0x55,0xff,0xaa,0x55}, {0x28,0x78,0x50,0x28}, {0xdf,0x7a,0xa5,0xdf}, {0x8c,0x8f,0x03,0x8c}, {0xa1,0xf8,0x59,0xa1}, {0x89,0x80,0x09,0x89}, {0x0d,0x17,0x1a,0x0d}, {0xbf,0xda,0x65,0xbf}, {0xe6,0x31,0xd7,0xe6}, {0x42,0xc6,0x84,0x42}, {0x68,0xb8,0xd0,0x68}, {0x41,0xc3,0x82,0x41}, {0x99,0xb0,0x29,0x99}, {0x2d,0x77,0x5a,0x2d}, {0x0f,0x11,0x1e,0x0f}, {0xb0,0xcb,0x7b,0xb0}, {0x54,0xfc,0xa8,0x54}, {0xbb,0xd6,0x6d,0xbb}, {0x16,0x3a,0x2c,0x16} }; word8 T4[256][4] = { {0x63,0x63,0xa5,0xc6}, {0x7c,0x7c,0x84,0xf8}, {0x77,0x77,0x99,0xee}, {0x7b,0x7b,0x8d,0xf6}, {0xf2,0xf2,0x0d,0xff}, {0x6b,0x6b,0xbd,0xd6}, {0x6f,0x6f,0xb1,0xde}, {0xc5,0xc5,0x54,0x91}, {0x30,0x30,0x50,0x60}, {0x01,0x01,0x03,0x02}, {0x67,0x67,0xa9,0xce}, {0x2b,0x2b,0x7d,0x56}, {0xfe,0xfe,0x19,0xe7}, {0xd7,0xd7,0x62,0xb5}, {0xab,0xab,0xe6,0x4d}, {0x76,0x76,0x9a,0xec}, {0xca,0xca,0x45,0x8f}, {0x82,0x82,0x9d,0x1f}, {0xc9,0xc9,0x40,0x89}, {0x7d,0x7d,0x87,0xfa}, {0xfa,0xfa,0x15,0xef}, {0x59,0x59,0xeb,0xb2}, {0x47,0x47,0xc9,0x8e}, {0xf0,0xf0,0x0b,0xfb}, {0xad,0xad,0xec,0x41}, {0xd4,0xd4,0x67,0xb3}, {0xa2,0xa2,0xfd,0x5f}, {0xaf,0xaf,0xea,0x45}, {0x9c,0x9c,0xbf,0x23}, {0xa4,0xa4,0xf7,0x53}, {0x72,0x72,0x96,0xe4}, {0xc0,0xc0,0x5b,0x9b}, {0xb7,0xb7,0xc2,0x75}, {0xfd,0xfd,0x1c,0xe1}, {0x93,0x93,0xae,0x3d}, {0x26,0x26,0x6a,0x4c}, {0x36,0x36,0x5a,0x6c}, {0x3f,0x3f,0x41,0x7e}, {0xf7,0xf7,0x02,0xf5}, {0xcc,0xcc,0x4f,0x83}, {0x34,0x34,0x5c,0x68}, {0xa5,0xa5,0xf4,0x51}, {0xe5,0xe5,0x34,0xd1}, {0xf1,0xf1,0x08,0xf9}, {0x71,0x71,0x93,0xe2}, {0xd8,0xd8,0x73,0xab}, {0x31,0x31,0x53,0x62}, {0x15,0x15,0x3f,0x2a}, {0x04,0x04,0x0c,0x08}, {0xc7,0xc7,0x52,0x95}, {0x23,0x23,0x65,0x46}, {0xc3,0xc3,0x5e,0x9d}, {0x18,0x18,0x28,0x30}, {0x96,0x96,0xa1,0x37}, {0x05,0x05,0x0f,0x0a}, {0x9a,0x9a,0xb5,0x2f}, {0x07,0x07,0x09,0x0e}, {0x12,0x12,0x36,0x24}, {0x80,0x80,0x9b,0x1b}, {0xe2,0xe2,0x3d,0xdf}, {0xeb,0xeb,0x26,0xcd}, {0x27,0x27,0x69,0x4e}, {0xb2,0xb2,0xcd,0x7f}, {0x75,0x75,0x9f,0xea}, {0x09,0x09,0x1b,0x12}, {0x83,0x83,0x9e,0x1d}, {0x2c,0x2c,0x74,0x58}, {0x1a,0x1a,0x2e,0x34}, {0x1b,0x1b,0x2d,0x36}, {0x6e,0x6e,0xb2,0xdc}, {0x5a,0x5a,0xee,0xb4}, {0xa0,0xa0,0xfb,0x5b}, {0x52,0x52,0xf6,0xa4}, {0x3b,0x3b,0x4d,0x76}, {0xd6,0xd6,0x61,0xb7}, {0xb3,0xb3,0xce,0x7d}, {0x29,0x29,0x7b,0x52}, {0xe3,0xe3,0x3e,0xdd}, {0x2f,0x2f,0x71,0x5e}, {0x84,0x84,0x97,0x13}, {0x53,0x53,0xf5,0xa6}, {0xd1,0xd1,0x68,0xb9}, {0x00,0x00,0x00,0x00}, {0xed,0xed,0x2c,0xc1}, {0x20,0x20,0x60,0x40}, {0xfc,0xfc,0x1f,0xe3}, {0xb1,0xb1,0xc8,0x79}, {0x5b,0x5b,0xed,0xb6}, {0x6a,0x6a,0xbe,0xd4}, {0xcb,0xcb,0x46,0x8d}, {0xbe,0xbe,0xd9,0x67}, {0x39,0x39,0x4b,0x72}, {0x4a,0x4a,0xde,0x94}, {0x4c,0x4c,0xd4,0x98}, {0x58,0x58,0xe8,0xb0}, {0xcf,0xcf,0x4a,0x85}, {0xd0,0xd0,0x6b,0xbb}, {0xef,0xef,0x2a,0xc5}, {0xaa,0xaa,0xe5,0x4f}, {0xfb,0xfb,0x16,0xed}, {0x43,0x43,0xc5,0x86}, {0x4d,0x4d,0xd7,0x9a}, {0x33,0x33,0x55,0x66}, {0x85,0x85,0x94,0x11}, {0x45,0x45,0xcf,0x8a}, {0xf9,0xf9,0x10,0xe9}, {0x02,0x02,0x06,0x04}, {0x7f,0x7f,0x81,0xfe}, {0x50,0x50,0xf0,0xa0}, {0x3c,0x3c,0x44,0x78}, {0x9f,0x9f,0xba,0x25}, {0xa8,0xa8,0xe3,0x4b}, {0x51,0x51,0xf3,0xa2}, {0xa3,0xa3,0xfe,0x5d}, {0x40,0x40,0xc0,0x80}, {0x8f,0x8f,0x8a,0x05}, {0x92,0x92,0xad,0x3f}, {0x9d,0x9d,0xbc,0x21}, {0x38,0x38,0x48,0x70}, {0xf5,0xf5,0x04,0xf1}, {0xbc,0xbc,0xdf,0x63}, {0xb6,0xb6,0xc1,0x77}, {0xda,0xda,0x75,0xaf}, {0x21,0x21,0x63,0x42}, {0x10,0x10,0x30,0x20}, {0xff,0xff,0x1a,0xe5}, {0xf3,0xf3,0x0e,0xfd}, {0xd2,0xd2,0x6d,0xbf}, {0xcd,0xcd,0x4c,0x81}, {0x0c,0x0c,0x14,0x18}, {0x13,0x13,0x35,0x26}, {0xec,0xec,0x2f,0xc3}, {0x5f,0x5f,0xe1,0xbe}, {0x97,0x97,0xa2,0x35}, {0x44,0x44,0xcc,0x88}, {0x17,0x17,0x39,0x2e}, {0xc4,0xc4,0x57,0x93}, {0xa7,0xa7,0xf2,0x55}, {0x7e,0x7e,0x82,0xfc}, {0x3d,0x3d,0x47,0x7a}, {0x64,0x64,0xac,0xc8}, {0x5d,0x5d,0xe7,0xba}, {0x19,0x19,0x2b,0x32}, {0x73,0x73,0x95,0xe6}, {0x60,0x60,0xa0,0xc0}, {0x81,0x81,0x98,0x19}, {0x4f,0x4f,0xd1,0x9e}, {0xdc,0xdc,0x7f,0xa3}, {0x22,0x22,0x66,0x44}, {0x2a,0x2a,0x7e,0x54}, {0x90,0x90,0xab,0x3b}, {0x88,0x88,0x83,0x0b}, {0x46,0x46,0xca,0x8c}, {0xee,0xee,0x29,0xc7}, {0xb8,0xb8,0xd3,0x6b}, {0x14,0x14,0x3c,0x28}, {0xde,0xde,0x79,0xa7}, {0x5e,0x5e,0xe2,0xbc}, {0x0b,0x0b,0x1d,0x16}, {0xdb,0xdb,0x76,0xad}, {0xe0,0xe0,0x3b,0xdb}, {0x32,0x32,0x56,0x64}, {0x3a,0x3a,0x4e,0x74}, {0x0a,0x0a,0x1e,0x14}, {0x49,0x49,0xdb,0x92}, {0x06,0x06,0x0a,0x0c}, {0x24,0x24,0x6c,0x48}, {0x5c,0x5c,0xe4,0xb8}, {0xc2,0xc2,0x5d,0x9f}, {0xd3,0xd3,0x6e,0xbd}, {0xac,0xac,0xef,0x43}, {0x62,0x62,0xa6,0xc4}, {0x91,0x91,0xa8,0x39}, {0x95,0x95,0xa4,0x31}, {0xe4,0xe4,0x37,0xd3}, {0x79,0x79,0x8b,0xf2}, {0xe7,0xe7,0x32,0xd5}, {0xc8,0xc8,0x43,0x8b}, {0x37,0x37,0x59,0x6e}, {0x6d,0x6d,0xb7,0xda}, {0x8d,0x8d,0x8c,0x01}, {0xd5,0xd5,0x64,0xb1}, {0x4e,0x4e,0xd2,0x9c}, {0xa9,0xa9,0xe0,0x49}, {0x6c,0x6c,0xb4,0xd8}, {0x56,0x56,0xfa,0xac}, {0xf4,0xf4,0x07,0xf3}, {0xea,0xea,0x25,0xcf}, {0x65,0x65,0xaf,0xca}, {0x7a,0x7a,0x8e,0xf4}, {0xae,0xae,0xe9,0x47}, {0x08,0x08,0x18,0x10}, {0xba,0xba,0xd5,0x6f}, {0x78,0x78,0x88,0xf0}, {0x25,0x25,0x6f,0x4a}, {0x2e,0x2e,0x72,0x5c}, {0x1c,0x1c,0x24,0x38}, {0xa6,0xa6,0xf1,0x57}, {0xb4,0xb4,0xc7,0x73}, {0xc6,0xc6,0x51,0x97}, {0xe8,0xe8,0x23,0xcb}, {0xdd,0xdd,0x7c,0xa1}, {0x74,0x74,0x9c,0xe8}, {0x1f,0x1f,0x21,0x3e}, {0x4b,0x4b,0xdd,0x96}, {0xbd,0xbd,0xdc,0x61}, {0x8b,0x8b,0x86,0x0d}, {0x8a,0x8a,0x85,0x0f}, {0x70,0x70,0x90,0xe0}, {0x3e,0x3e,0x42,0x7c}, {0xb5,0xb5,0xc4,0x71}, {0x66,0x66,0xaa,0xcc}, {0x48,0x48,0xd8,0x90}, {0x03,0x03,0x05,0x06}, {0xf6,0xf6,0x01,0xf7}, {0x0e,0x0e,0x12,0x1c}, {0x61,0x61,0xa3,0xc2}, {0x35,0x35,0x5f,0x6a}, {0x57,0x57,0xf9,0xae}, {0xb9,0xb9,0xd0,0x69}, {0x86,0x86,0x91,0x17}, {0xc1,0xc1,0x58,0x99}, {0x1d,0x1d,0x27,0x3a}, {0x9e,0x9e,0xb9,0x27}, {0xe1,0xe1,0x38,0xd9}, {0xf8,0xf8,0x13,0xeb}, {0x98,0x98,0xb3,0x2b}, {0x11,0x11,0x33,0x22}, {0x69,0x69,0xbb,0xd2}, {0xd9,0xd9,0x70,0xa9}, {0x8e,0x8e,0x89,0x07}, {0x94,0x94,0xa7,0x33}, {0x9b,0x9b,0xb6,0x2d}, {0x1e,0x1e,0x22,0x3c}, {0x87,0x87,0x92,0x15}, {0xe9,0xe9,0x20,0xc9}, {0xce,0xce,0x49,0x87}, {0x55,0x55,0xff,0xaa}, {0x28,0x28,0x78,0x50}, {0xdf,0xdf,0x7a,0xa5}, {0x8c,0x8c,0x8f,0x03}, {0xa1,0xa1,0xf8,0x59}, {0x89,0x89,0x80,0x09}, {0x0d,0x0d,0x17,0x1a}, {0xbf,0xbf,0xda,0x65}, {0xe6,0xe6,0x31,0xd7}, {0x42,0x42,0xc6,0x84}, {0x68,0x68,0xb8,0xd0}, {0x41,0x41,0xc3,0x82}, {0x99,0x99,0xb0,0x29}, {0x2d,0x2d,0x77,0x5a}, {0x0f,0x0f,0x11,0x1e}, {0xb0,0xb0,0xcb,0x7b}, {0x54,0x54,0xfc,0xa8}, {0xbb,0xbb,0xd6,0x6d}, {0x16,0x16,0x3a,0x2c}, }; word8 T5[256][4] = { {0x51,0xf4,0xa7,0x50}, {0x7e,0x41,0x65,0x53}, {0x1a,0x17,0xa4,0xc3}, {0x3a,0x27,0x5e,0x96}, {0x3b,0xab,0x6b,0xcb}, {0x1f,0x9d,0x45,0xf1}, {0xac,0xfa,0x58,0xab}, {0x4b,0xe3,0x03,0x93}, {0x20,0x30,0xfa,0x55}, {0xad,0x76,0x6d,0xf6}, {0x88,0xcc,0x76,0x91}, {0xf5,0x02,0x4c,0x25}, {0x4f,0xe5,0xd7,0xfc}, {0xc5,0x2a,0xcb,0xd7}, {0x26,0x35,0x44,0x80}, {0xb5,0x62,0xa3,0x8f}, {0xde,0xb1,0x5a,0x49}, {0x25,0xba,0x1b,0x67}, {0x45,0xea,0x0e,0x98}, {0x5d,0xfe,0xc0,0xe1}, {0xc3,0x2f,0x75,0x02}, {0x81,0x4c,0xf0,0x12}, {0x8d,0x46,0x97,0xa3}, {0x6b,0xd3,0xf9,0xc6}, {0x03,0x8f,0x5f,0xe7}, {0x15,0x92,0x9c,0x95}, {0xbf,0x6d,0x7a,0xeb}, {0x95,0x52,0x59,0xda}, {0xd4,0xbe,0x83,0x2d}, {0x58,0x74,0x21,0xd3}, {0x49,0xe0,0x69,0x29}, {0x8e,0xc9,0xc8,0x44}, {0x75,0xc2,0x89,0x6a}, {0xf4,0x8e,0x79,0x78}, {0x99,0x58,0x3e,0x6b}, {0x27,0xb9,0x71,0xdd}, {0xbe,0xe1,0x4f,0xb6}, {0xf0,0x88,0xad,0x17}, {0xc9,0x20,0xac,0x66}, {0x7d,0xce,0x3a,0xb4}, {0x63,0xdf,0x4a,0x18}, {0xe5,0x1a,0x31,0x82}, {0x97,0x51,0x33,0x60}, {0x62,0x53,0x7f,0x45}, {0xb1,0x64,0x77,0xe0}, {0xbb,0x6b,0xae,0x84}, {0xfe,0x81,0xa0,0x1c}, {0xf9,0x08,0x2b,0x94}, {0x70,0x48,0x68,0x58}, {0x8f,0x45,0xfd,0x19}, {0x94,0xde,0x6c,0x87}, {0x52,0x7b,0xf8,0xb7}, {0xab,0x73,0xd3,0x23}, {0x72,0x4b,0x02,0xe2}, {0xe3,0x1f,0x8f,0x57}, {0x66,0x55,0xab,0x2a}, {0xb2,0xeb,0x28,0x07}, {0x2f,0xb5,0xc2,0x03}, {0x86,0xc5,0x7b,0x9a}, {0xd3,0x37,0x08,0xa5}, {0x30,0x28,0x87,0xf2}, {0x23,0xbf,0xa5,0xb2}, {0x02,0x03,0x6a,0xba}, {0xed,0x16,0x82,0x5c}, {0x8a,0xcf,0x1c,0x2b}, {0xa7,0x79,0xb4,0x92}, {0xf3,0x07,0xf2,0xf0}, {0x4e,0x69,0xe2,0xa1}, {0x65,0xda,0xf4,0xcd}, {0x06,0x05,0xbe,0xd5}, {0xd1,0x34,0x62,0x1f}, {0xc4,0xa6,0xfe,0x8a}, {0x34,0x2e,0x53,0x9d}, {0xa2,0xf3,0x55,0xa0}, {0x05,0x8a,0xe1,0x32}, {0xa4,0xf6,0xeb,0x75}, {0x0b,0x83,0xec,0x39}, {0x40,0x60,0xef,0xaa}, {0x5e,0x71,0x9f,0x06}, {0xbd,0x6e,0x10,0x51}, {0x3e,0x21,0x8a,0xf9}, {0x96,0xdd,0x06,0x3d}, {0xdd,0x3e,0x05,0xae}, {0x4d,0xe6,0xbd,0x46}, {0x91,0x54,0x8d,0xb5}, {0x71,0xc4,0x5d,0x05}, {0x04,0x06,0xd4,0x6f}, {0x60,0x50,0x15,0xff}, {0x19,0x98,0xfb,0x24}, {0xd6,0xbd,0xe9,0x97}, {0x89,0x40,0x43,0xcc}, {0x67,0xd9,0x9e,0x77}, {0xb0,0xe8,0x42,0xbd}, {0x07,0x89,0x8b,0x88}, {0xe7,0x19,0x5b,0x38}, {0x79,0xc8,0xee,0xdb}, {0xa1,0x7c,0x0a,0x47}, {0x7c,0x42,0x0f,0xe9}, {0xf8,0x84,0x1e,0xc9}, {0x00,0x00,0x00,0x00}, {0x09,0x80,0x86,0x83}, {0x32,0x2b,0xed,0x48}, {0x1e,0x11,0x70,0xac}, {0x6c,0x5a,0x72,0x4e}, {0xfd,0x0e,0xff,0xfb}, {0x0f,0x85,0x38,0x56}, {0x3d,0xae,0xd5,0x1e}, {0x36,0x2d,0x39,0x27}, {0x0a,0x0f,0xd9,0x64}, {0x68,0x5c,0xa6,0x21}, {0x9b,0x5b,0x54,0xd1}, {0x24,0x36,0x2e,0x3a}, {0x0c,0x0a,0x67,0xb1}, {0x93,0x57,0xe7,0x0f}, {0xb4,0xee,0x96,0xd2}, {0x1b,0x9b,0x91,0x9e}, {0x80,0xc0,0xc5,0x4f}, {0x61,0xdc,0x20,0xa2}, {0x5a,0x77,0x4b,0x69}, {0x1c,0x12,0x1a,0x16}, {0xe2,0x93,0xba,0x0a}, {0xc0,0xa0,0x2a,0xe5}, {0x3c,0x22,0xe0,0x43}, {0x12,0x1b,0x17,0x1d}, {0x0e,0x09,0x0d,0x0b}, {0xf2,0x8b,0xc7,0xad}, {0x2d,0xb6,0xa8,0xb9}, {0x14,0x1e,0xa9,0xc8}, {0x57,0xf1,0x19,0x85}, {0xaf,0x75,0x07,0x4c}, {0xee,0x99,0xdd,0xbb}, {0xa3,0x7f,0x60,0xfd}, {0xf7,0x01,0x26,0x9f}, {0x5c,0x72,0xf5,0xbc}, {0x44,0x66,0x3b,0xc5}, {0x5b,0xfb,0x7e,0x34}, {0x8b,0x43,0x29,0x76}, {0xcb,0x23,0xc6,0xdc}, {0xb6,0xed,0xfc,0x68}, {0xb8,0xe4,0xf1,0x63}, {0xd7,0x31,0xdc,0xca}, {0x42,0x63,0x85,0x10}, {0x13,0x97,0x22,0x40}, {0x84,0xc6,0x11,0x20}, {0x85,0x4a,0x24,0x7d}, {0xd2,0xbb,0x3d,0xf8}, {0xae,0xf9,0x32,0x11}, {0xc7,0x29,0xa1,0x6d}, {0x1d,0x9e,0x2f,0x4b}, {0xdc,0xb2,0x30,0xf3}, {0x0d,0x86,0x52,0xec}, {0x77,0xc1,0xe3,0xd0}, {0x2b,0xb3,0x16,0x6c}, {0xa9,0x70,0xb9,0x99}, {0x11,0x94,0x48,0xfa}, {0x47,0xe9,0x64,0x22}, {0xa8,0xfc,0x8c,0xc4}, {0xa0,0xf0,0x3f,0x1a}, {0x56,0x7d,0x2c,0xd8}, {0x22,0x33,0x90,0xef}, {0x87,0x49,0x4e,0xc7}, {0xd9,0x38,0xd1,0xc1}, {0x8c,0xca,0xa2,0xfe}, {0x98,0xd4,0x0b,0x36}, {0xa6,0xf5,0x81,0xcf}, {0xa5,0x7a,0xde,0x28}, {0xda,0xb7,0x8e,0x26}, {0x3f,0xad,0xbf,0xa4}, {0x2c,0x3a,0x9d,0xe4}, {0x50,0x78,0x92,0x0d}, {0x6a,0x5f,0xcc,0x9b}, {0x54,0x7e,0x46,0x62}, {0xf6,0x8d,0x13,0xc2}, {0x90,0xd8,0xb8,0xe8}, {0x2e,0x39,0xf7,0x5e}, {0x82,0xc3,0xaf,0xf5}, {0x9f,0x5d,0x80,0xbe}, {0x69,0xd0,0x93,0x7c}, {0x6f,0xd5,0x2d,0xa9}, {0xcf,0x25,0x12,0xb3}, {0xc8,0xac,0x99,0x3b}, {0x10,0x18,0x7d,0xa7}, {0xe8,0x9c,0x63,0x6e}, {0xdb,0x3b,0xbb,0x7b}, {0xcd,0x26,0x78,0x09}, {0x6e,0x59,0x18,0xf4}, {0xec,0x9a,0xb7,0x01}, {0x83,0x4f,0x9a,0xa8}, {0xe6,0x95,0x6e,0x65}, {0xaa,0xff,0xe6,0x7e}, {0x21,0xbc,0xcf,0x08}, {0xef,0x15,0xe8,0xe6}, {0xba,0xe7,0x9b,0xd9}, {0x4a,0x6f,0x36,0xce}, {0xea,0x9f,0x09,0xd4}, {0x29,0xb0,0x7c,0xd6}, {0x31,0xa4,0xb2,0xaf}, {0x2a,0x3f,0x23,0x31}, {0xc6,0xa5,0x94,0x30}, {0x35,0xa2,0x66,0xc0}, {0x74,0x4e,0xbc,0x37}, {0xfc,0x82,0xca,0xa6}, {0xe0,0x90,0xd0,0xb0}, {0x33,0xa7,0xd8,0x15}, {0xf1,0x04,0x98,0x4a}, {0x41,0xec,0xda,0xf7}, {0x7f,0xcd,0x50,0x0e}, {0x17,0x91,0xf6,0x2f}, {0x76,0x4d,0xd6,0x8d}, {0x43,0xef,0xb0,0x4d}, {0xcc,0xaa,0x4d,0x54}, {0xe4,0x96,0x04,0xdf}, {0x9e,0xd1,0xb5,0xe3}, {0x4c,0x6a,0x88,0x1b}, {0xc1,0x2c,0x1f,0xb8}, {0x46,0x65,0x51,0x7f}, {0x9d,0x5e,0xea,0x04}, {0x01,0x8c,0x35,0x5d}, {0xfa,0x87,0x74,0x73}, {0xfb,0x0b,0x41,0x2e}, {0xb3,0x67,0x1d,0x5a}, {0x92,0xdb,0xd2,0x52}, {0xe9,0x10,0x56,0x33}, {0x6d,0xd6,0x47,0x13}, {0x9a,0xd7,0x61,0x8c}, {0x37,0xa1,0x0c,0x7a}, {0x59,0xf8,0x14,0x8e}, {0xeb,0x13,0x3c,0x89}, {0xce,0xa9,0x27,0xee}, {0xb7,0x61,0xc9,0x35}, {0xe1,0x1c,0xe5,0xed}, {0x7a,0x47,0xb1,0x3c}, {0x9c,0xd2,0xdf,0x59}, {0x55,0xf2,0x73,0x3f}, {0x18,0x14,0xce,0x79}, {0x73,0xc7,0x37,0xbf}, {0x53,0xf7,0xcd,0xea}, {0x5f,0xfd,0xaa,0x5b}, {0xdf,0x3d,0x6f,0x14}, {0x78,0x44,0xdb,0x86}, {0xca,0xaf,0xf3,0x81}, {0xb9,0x68,0xc4,0x3e}, {0x38,0x24,0x34,0x2c}, {0xc2,0xa3,0x40,0x5f}, {0x16,0x1d,0xc3,0x72}, {0xbc,0xe2,0x25,0x0c}, {0x28,0x3c,0x49,0x8b}, {0xff,0x0d,0x95,0x41}, {0x39,0xa8,0x01,0x71}, {0x08,0x0c,0xb3,0xde}, {0xd8,0xb4,0xe4,0x9c}, {0x64,0x56,0xc1,0x90}, {0x7b,0xcb,0x84,0x61}, {0xd5,0x32,0xb6,0x70}, {0x48,0x6c,0x5c,0x74}, {0xd0,0xb8,0x57,0x42} }; word8 T6[256][4] = { {0x50,0x51,0xf4,0xa7}, {0x53,0x7e,0x41,0x65}, {0xc3,0x1a,0x17,0xa4}, {0x96,0x3a,0x27,0x5e}, {0xcb,0x3b,0xab,0x6b}, {0xf1,0x1f,0x9d,0x45}, {0xab,0xac,0xfa,0x58}, {0x93,0x4b,0xe3,0x03}, {0x55,0x20,0x30,0xfa}, {0xf6,0xad,0x76,0x6d}, {0x91,0x88,0xcc,0x76}, {0x25,0xf5,0x02,0x4c}, {0xfc,0x4f,0xe5,0xd7}, {0xd7,0xc5,0x2a,0xcb}, {0x80,0x26,0x35,0x44}, {0x8f,0xb5,0x62,0xa3}, {0x49,0xde,0xb1,0x5a}, {0x67,0x25,0xba,0x1b}, {0x98,0x45,0xea,0x0e}, {0xe1,0x5d,0xfe,0xc0}, {0x02,0xc3,0x2f,0x75}, {0x12,0x81,0x4c,0xf0}, {0xa3,0x8d,0x46,0x97}, {0xc6,0x6b,0xd3,0xf9}, {0xe7,0x03,0x8f,0x5f}, {0x95,0x15,0x92,0x9c}, {0xeb,0xbf,0x6d,0x7a}, {0xda,0x95,0x52,0x59}, {0x2d,0xd4,0xbe,0x83}, {0xd3,0x58,0x74,0x21}, {0x29,0x49,0xe0,0x69}, {0x44,0x8e,0xc9,0xc8}, {0x6a,0x75,0xc2,0x89}, {0x78,0xf4,0x8e,0x79}, {0x6b,0x99,0x58,0x3e}, {0xdd,0x27,0xb9,0x71}, {0xb6,0xbe,0xe1,0x4f}, {0x17,0xf0,0x88,0xad}, {0x66,0xc9,0x20,0xac}, {0xb4,0x7d,0xce,0x3a}, {0x18,0x63,0xdf,0x4a}, {0x82,0xe5,0x1a,0x31}, {0x60,0x97,0x51,0x33}, {0x45,0x62,0x53,0x7f}, {0xe0,0xb1,0x64,0x77}, {0x84,0xbb,0x6b,0xae}, {0x1c,0xfe,0x81,0xa0}, {0x94,0xf9,0x08,0x2b}, {0x58,0x70,0x48,0x68}, {0x19,0x8f,0x45,0xfd}, {0x87,0x94,0xde,0x6c}, {0xb7,0x52,0x7b,0xf8}, {0x23,0xab,0x73,0xd3}, {0xe2,0x72,0x4b,0x02}, {0x57,0xe3,0x1f,0x8f}, {0x2a,0x66,0x55,0xab}, {0x07,0xb2,0xeb,0x28}, {0x03,0x2f,0xb5,0xc2}, {0x9a,0x86,0xc5,0x7b}, {0xa5,0xd3,0x37,0x08}, {0xf2,0x30,0x28,0x87}, {0xb2,0x23,0xbf,0xa5}, {0xba,0x02,0x03,0x6a}, {0x5c,0xed,0x16,0x82}, {0x2b,0x8a,0xcf,0x1c}, {0x92,0xa7,0x79,0xb4}, {0xf0,0xf3,0x07,0xf2}, {0xa1,0x4e,0x69,0xe2}, {0xcd,0x65,0xda,0xf4}, {0xd5,0x06,0x05,0xbe}, {0x1f,0xd1,0x34,0x62}, {0x8a,0xc4,0xa6,0xfe}, {0x9d,0x34,0x2e,0x53}, {0xa0,0xa2,0xf3,0x55}, {0x32,0x05,0x8a,0xe1}, {0x75,0xa4,0xf6,0xeb}, {0x39,0x0b,0x83,0xec}, {0xaa,0x40,0x60,0xef}, {0x06,0x5e,0x71,0x9f}, {0x51,0xbd,0x6e,0x10}, {0xf9,0x3e,0x21,0x8a}, {0x3d,0x96,0xdd,0x06}, {0xae,0xdd,0x3e,0x05}, {0x46,0x4d,0xe6,0xbd}, {0xb5,0x91,0x54,0x8d}, {0x05,0x71,0xc4,0x5d}, {0x6f,0x04,0x06,0xd4}, {0xff,0x60,0x50,0x15}, {0x24,0x19,0x98,0xfb}, {0x97,0xd6,0xbd,0xe9}, {0xcc,0x89,0x40,0x43}, {0x77,0x67,0xd9,0x9e}, {0xbd,0xb0,0xe8,0x42}, {0x88,0x07,0x89,0x8b}, {0x38,0xe7,0x19,0x5b}, {0xdb,0x79,0xc8,0xee}, {0x47,0xa1,0x7c,0x0a}, {0xe9,0x7c,0x42,0x0f}, {0xc9,0xf8,0x84,0x1e}, {0x00,0x00,0x00,0x00}, {0x83,0x09,0x80,0x86}, {0x48,0x32,0x2b,0xed}, {0xac,0x1e,0x11,0x70}, {0x4e,0x6c,0x5a,0x72}, {0xfb,0xfd,0x0e,0xff}, {0x56,0x0f,0x85,0x38}, {0x1e,0x3d,0xae,0xd5}, {0x27,0x36,0x2d,0x39}, {0x64,0x0a,0x0f,0xd9}, {0x21,0x68,0x5c,0xa6}, {0xd1,0x9b,0x5b,0x54}, {0x3a,0x24,0x36,0x2e}, {0xb1,0x0c,0x0a,0x67}, {0x0f,0x93,0x57,0xe7}, {0xd2,0xb4,0xee,0x96}, {0x9e,0x1b,0x9b,0x91}, {0x4f,0x80,0xc0,0xc5}, {0xa2,0x61,0xdc,0x20}, {0x69,0x5a,0x77,0x4b}, {0x16,0x1c,0x12,0x1a}, {0x0a,0xe2,0x93,0xba}, {0xe5,0xc0,0xa0,0x2a}, {0x43,0x3c,0x22,0xe0}, {0x1d,0x12,0x1b,0x17}, {0x0b,0x0e,0x09,0x0d}, {0xad,0xf2,0x8b,0xc7}, {0xb9,0x2d,0xb6,0xa8}, {0xc8,0x14,0x1e,0xa9}, {0x85,0x57,0xf1,0x19}, {0x4c,0xaf,0x75,0x07}, {0xbb,0xee,0x99,0xdd}, {0xfd,0xa3,0x7f,0x60}, {0x9f,0xf7,0x01,0x26}, {0xbc,0x5c,0x72,0xf5}, {0xc5,0x44,0x66,0x3b}, {0x34,0x5b,0xfb,0x7e}, {0x76,0x8b,0x43,0x29}, {0xdc,0xcb,0x23,0xc6}, {0x68,0xb6,0xed,0xfc}, {0x63,0xb8,0xe4,0xf1}, {0xca,0xd7,0x31,0xdc}, {0x10,0x42,0x63,0x85}, {0x40,0x13,0x97,0x22}, {0x20,0x84,0xc6,0x11}, {0x7d,0x85,0x4a,0x24}, {0xf8,0xd2,0xbb,0x3d}, {0x11,0xae,0xf9,0x32}, {0x6d,0xc7,0x29,0xa1}, {0x4b,0x1d,0x9e,0x2f}, {0xf3,0xdc,0xb2,0x30}, {0xec,0x0d,0x86,0x52}, {0xd0,0x77,0xc1,0xe3}, {0x6c,0x2b,0xb3,0x16}, {0x99,0xa9,0x70,0xb9}, {0xfa,0x11,0x94,0x48}, {0x22,0x47,0xe9,0x64}, {0xc4,0xa8,0xfc,0x8c}, {0x1a,0xa0,0xf0,0x3f}, {0xd8,0x56,0x7d,0x2c}, {0xef,0x22,0x33,0x90}, {0xc7,0x87,0x49,0x4e}, {0xc1,0xd9,0x38,0xd1}, {0xfe,0x8c,0xca,0xa2}, {0x36,0x98,0xd4,0x0b}, {0xcf,0xa6,0xf5,0x81}, {0x28,0xa5,0x7a,0xde}, {0x26,0xda,0xb7,0x8e}, {0xa4,0x3f,0xad,0xbf}, {0xe4,0x2c,0x3a,0x9d}, {0x0d,0x50,0x78,0x92}, {0x9b,0x6a,0x5f,0xcc}, {0x62,0x54,0x7e,0x46}, {0xc2,0xf6,0x8d,0x13}, {0xe8,0x90,0xd8,0xb8}, {0x5e,0x2e,0x39,0xf7}, {0xf5,0x82,0xc3,0xaf}, {0xbe,0x9f,0x5d,0x80}, {0x7c,0x69,0xd0,0x93}, {0xa9,0x6f,0xd5,0x2d}, {0xb3,0xcf,0x25,0x12}, {0x3b,0xc8,0xac,0x99}, {0xa7,0x10,0x18,0x7d}, {0x6e,0xe8,0x9c,0x63}, {0x7b,0xdb,0x3b,0xbb}, {0x09,0xcd,0x26,0x78}, {0xf4,0x6e,0x59,0x18}, {0x01,0xec,0x9a,0xb7}, {0xa8,0x83,0x4f,0x9a}, {0x65,0xe6,0x95,0x6e}, {0x7e,0xaa,0xff,0xe6}, {0x08,0x21,0xbc,0xcf}, {0xe6,0xef,0x15,0xe8}, {0xd9,0xba,0xe7,0x9b}, {0xce,0x4a,0x6f,0x36}, {0xd4,0xea,0x9f,0x09}, {0xd6,0x29,0xb0,0x7c}, {0xaf,0x31,0xa4,0xb2}, {0x31,0x2a,0x3f,0x23}, {0x30,0xc6,0xa5,0x94}, {0xc0,0x35,0xa2,0x66}, {0x37,0x74,0x4e,0xbc}, {0xa6,0xfc,0x82,0xca}, {0xb0,0xe0,0x90,0xd0}, {0x15,0x33,0xa7,0xd8}, {0x4a,0xf1,0x04,0x98}, {0xf7,0x41,0xec,0xda}, {0x0e,0x7f,0xcd,0x50}, {0x2f,0x17,0x91,0xf6}, {0x8d,0x76,0x4d,0xd6}, {0x4d,0x43,0xef,0xb0}, {0x54,0xcc,0xaa,0x4d}, {0xdf,0xe4,0x96,0x04}, {0xe3,0x9e,0xd1,0xb5}, {0x1b,0x4c,0x6a,0x88}, {0xb8,0xc1,0x2c,0x1f}, {0x7f,0x46,0x65,0x51}, {0x04,0x9d,0x5e,0xea}, {0x5d,0x01,0x8c,0x35}, {0x73,0xfa,0x87,0x74}, {0x2e,0xfb,0x0b,0x41}, {0x5a,0xb3,0x67,0x1d}, {0x52,0x92,0xdb,0xd2}, {0x33,0xe9,0x10,0x56}, {0x13,0x6d,0xd6,0x47}, {0x8c,0x9a,0xd7,0x61}, {0x7a,0x37,0xa1,0x0c}, {0x8e,0x59,0xf8,0x14}, {0x89,0xeb,0x13,0x3c}, {0xee,0xce,0xa9,0x27}, {0x35,0xb7,0x61,0xc9}, {0xed,0xe1,0x1c,0xe5}, {0x3c,0x7a,0x47,0xb1}, {0x59,0x9c,0xd2,0xdf}, {0x3f,0x55,0xf2,0x73}, {0x79,0x18,0x14,0xce}, {0xbf,0x73,0xc7,0x37}, {0xea,0x53,0xf7,0xcd}, {0x5b,0x5f,0xfd,0xaa}, {0x14,0xdf,0x3d,0x6f}, {0x86,0x78,0x44,0xdb}, {0x81,0xca,0xaf,0xf3}, {0x3e,0xb9,0x68,0xc4}, {0x2c,0x38,0x24,0x34}, {0x5f,0xc2,0xa3,0x40}, {0x72,0x16,0x1d,0xc3}, {0x0c,0xbc,0xe2,0x25}, {0x8b,0x28,0x3c,0x49}, {0x41,0xff,0x0d,0x95}, {0x71,0x39,0xa8,0x01}, {0xde,0x08,0x0c,0xb3}, {0x9c,0xd8,0xb4,0xe4}, {0x90,0x64,0x56,0xc1}, {0x61,0x7b,0xcb,0x84}, {0x70,0xd5,0x32,0xb6}, {0x74,0x48,0x6c,0x5c}, {0x42,0xd0,0xb8,0x57}, }; word8 T7[256][4] = { {0xa7,0x50,0x51,0xf4}, {0x65,0x53,0x7e,0x41}, {0xa4,0xc3,0x1a,0x17}, {0x5e,0x96,0x3a,0x27}, {0x6b,0xcb,0x3b,0xab}, {0x45,0xf1,0x1f,0x9d}, {0x58,0xab,0xac,0xfa}, {0x03,0x93,0x4b,0xe3}, {0xfa,0x55,0x20,0x30}, {0x6d,0xf6,0xad,0x76}, {0x76,0x91,0x88,0xcc}, {0x4c,0x25,0xf5,0x02}, {0xd7,0xfc,0x4f,0xe5}, {0xcb,0xd7,0xc5,0x2a}, {0x44,0x80,0x26,0x35}, {0xa3,0x8f,0xb5,0x62}, {0x5a,0x49,0xde,0xb1}, {0x1b,0x67,0x25,0xba}, {0x0e,0x98,0x45,0xea}, {0xc0,0xe1,0x5d,0xfe}, {0x75,0x02,0xc3,0x2f}, {0xf0,0x12,0x81,0x4c}, {0x97,0xa3,0x8d,0x46}, {0xf9,0xc6,0x6b,0xd3}, {0x5f,0xe7,0x03,0x8f}, {0x9c,0x95,0x15,0x92}, {0x7a,0xeb,0xbf,0x6d}, {0x59,0xda,0x95,0x52}, {0x83,0x2d,0xd4,0xbe}, {0x21,0xd3,0x58,0x74}, {0x69,0x29,0x49,0xe0}, {0xc8,0x44,0x8e,0xc9}, {0x89,0x6a,0x75,0xc2}, {0x79,0x78,0xf4,0x8e}, {0x3e,0x6b,0x99,0x58}, {0x71,0xdd,0x27,0xb9}, {0x4f,0xb6,0xbe,0xe1}, {0xad,0x17,0xf0,0x88}, {0xac,0x66,0xc9,0x20}, {0x3a,0xb4,0x7d,0xce}, {0x4a,0x18,0x63,0xdf}, {0x31,0x82,0xe5,0x1a}, {0x33,0x60,0x97,0x51}, {0x7f,0x45,0x62,0x53}, {0x77,0xe0,0xb1,0x64}, {0xae,0x84,0xbb,0x6b}, {0xa0,0x1c,0xfe,0x81}, {0x2b,0x94,0xf9,0x08}, {0x68,0x58,0x70,0x48}, {0xfd,0x19,0x8f,0x45}, {0x6c,0x87,0x94,0xde}, {0xf8,0xb7,0x52,0x7b}, {0xd3,0x23,0xab,0x73}, {0x02,0xe2,0x72,0x4b}, {0x8f,0x57,0xe3,0x1f}, {0xab,0x2a,0x66,0x55}, {0x28,0x07,0xb2,0xeb}, {0xc2,0x03,0x2f,0xb5}, {0x7b,0x9a,0x86,0xc5}, {0x08,0xa5,0xd3,0x37}, {0x87,0xf2,0x30,0x28}, {0xa5,0xb2,0x23,0xbf}, {0x6a,0xba,0x02,0x03}, {0x82,0x5c,0xed,0x16}, {0x1c,0x2b,0x8a,0xcf}, {0xb4,0x92,0xa7,0x79}, {0xf2,0xf0,0xf3,0x07}, {0xe2,0xa1,0x4e,0x69}, {0xf4,0xcd,0x65,0xda}, {0xbe,0xd5,0x06,0x05}, {0x62,0x1f,0xd1,0x34}, {0xfe,0x8a,0xc4,0xa6}, {0x53,0x9d,0x34,0x2e}, {0x55,0xa0,0xa2,0xf3}, {0xe1,0x32,0x05,0x8a}, {0xeb,0x75,0xa4,0xf6}, {0xec,0x39,0x0b,0x83}, {0xef,0xaa,0x40,0x60}, {0x9f,0x06,0x5e,0x71}, {0x10,0x51,0xbd,0x6e}, {0x8a,0xf9,0x3e,0x21}, {0x06,0x3d,0x96,0xdd}, {0x05,0xae,0xdd,0x3e}, {0xbd,0x46,0x4d,0xe6}, {0x8d,0xb5,0x91,0x54}, {0x5d,0x05,0x71,0xc4}, {0xd4,0x6f,0x04,0x06}, {0x15,0xff,0x60,0x50}, {0xfb,0x24,0x19,0x98}, {0xe9,0x97,0xd6,0xbd}, {0x43,0xcc,0x89,0x40}, {0x9e,0x77,0x67,0xd9}, {0x42,0xbd,0xb0,0xe8}, {0x8b,0x88,0x07,0x89}, {0x5b,0x38,0xe7,0x19}, {0xee,0xdb,0x79,0xc8}, {0x0a,0x47,0xa1,0x7c}, {0x0f,0xe9,0x7c,0x42}, {0x1e,0xc9,0xf8,0x84}, {0x00,0x00,0x00,0x00}, {0x86,0x83,0x09,0x80}, {0xed,0x48,0x32,0x2b}, {0x70,0xac,0x1e,0x11}, {0x72,0x4e,0x6c,0x5a}, {0xff,0xfb,0xfd,0x0e}, {0x38,0x56,0x0f,0x85}, {0xd5,0x1e,0x3d,0xae}, {0x39,0x27,0x36,0x2d}, {0xd9,0x64,0x0a,0x0f}, {0xa6,0x21,0x68,0x5c}, {0x54,0xd1,0x9b,0x5b}, {0x2e,0x3a,0x24,0x36}, {0x67,0xb1,0x0c,0x0a}, {0xe7,0x0f,0x93,0x57}, {0x96,0xd2,0xb4,0xee}, {0x91,0x9e,0x1b,0x9b}, {0xc5,0x4f,0x80,0xc0}, {0x20,0xa2,0x61,0xdc}, {0x4b,0x69,0x5a,0x77}, {0x1a,0x16,0x1c,0x12}, {0xba,0x0a,0xe2,0x93}, {0x2a,0xe5,0xc0,0xa0}, {0xe0,0x43,0x3c,0x22}, {0x17,0x1d,0x12,0x1b}, {0x0d,0x0b,0x0e,0x09}, {0xc7,0xad,0xf2,0x8b}, {0xa8,0xb9,0x2d,0xb6}, {0xa9,0xc8,0x14,0x1e}, {0x19,0x85,0x57,0xf1}, {0x07,0x4c,0xaf,0x75}, {0xdd,0xbb,0xee,0x99}, {0x60,0xfd,0xa3,0x7f}, {0x26,0x9f,0xf7,0x01}, {0xf5,0xbc,0x5c,0x72}, {0x3b,0xc5,0x44,0x66}, {0x7e,0x34,0x5b,0xfb}, {0x29,0x76,0x8b,0x43}, {0xc6,0xdc,0xcb,0x23}, {0xfc,0x68,0xb6,0xed}, {0xf1,0x63,0xb8,0xe4}, {0xdc,0xca,0xd7,0x31}, {0x85,0x10,0x42,0x63}, {0x22,0x40,0x13,0x97}, {0x11,0x20,0x84,0xc6}, {0x24,0x7d,0x85,0x4a}, {0x3d,0xf8,0xd2,0xbb}, {0x32,0x11,0xae,0xf9}, {0xa1,0x6d,0xc7,0x29}, {0x2f,0x4b,0x1d,0x9e}, {0x30,0xf3,0xdc,0xb2}, {0x52,0xec,0x0d,0x86}, {0xe3,0xd0,0x77,0xc1}, {0x16,0x6c,0x2b,0xb3}, {0xb9,0x99,0xa9,0x70}, {0x48,0xfa,0x11,0x94}, {0x64,0x22,0x47,0xe9}, {0x8c,0xc4,0xa8,0xfc}, {0x3f,0x1a,0xa0,0xf0}, {0x2c,0xd8,0x56,0x7d}, {0x90,0xef,0x22,0x33}, {0x4e,0xc7,0x87,0x49}, {0xd1,0xc1,0xd9,0x38}, {0xa2,0xfe,0x8c,0xca}, {0x0b,0x36,0x98,0xd4}, {0x81,0xcf,0xa6,0xf5}, {0xde,0x28,0xa5,0x7a}, {0x8e,0x26,0xda,0xb7}, {0xbf,0xa4,0x3f,0xad}, {0x9d,0xe4,0x2c,0x3a}, {0x92,0x0d,0x50,0x78}, {0xcc,0x9b,0x6a,0x5f}, {0x46,0x62,0x54,0x7e}, {0x13,0xc2,0xf6,0x8d}, {0xb8,0xe8,0x90,0xd8}, {0xf7,0x5e,0x2e,0x39}, {0xaf,0xf5,0x82,0xc3}, {0x80,0xbe,0x9f,0x5d}, {0x93,0x7c,0x69,0xd0}, {0x2d,0xa9,0x6f,0xd5}, {0x12,0xb3,0xcf,0x25}, {0x99,0x3b,0xc8,0xac}, {0x7d,0xa7,0x10,0x18}, {0x63,0x6e,0xe8,0x9c}, {0xbb,0x7b,0xdb,0x3b}, {0x78,0x09,0xcd,0x26}, {0x18,0xf4,0x6e,0x59}, {0xb7,0x01,0xec,0x9a}, {0x9a,0xa8,0x83,0x4f}, {0x6e,0x65,0xe6,0x95}, {0xe6,0x7e,0xaa,0xff}, {0xcf,0x08,0x21,0xbc}, {0xe8,0xe6,0xef,0x15}, {0x9b,0xd9,0xba,0xe7}, {0x36,0xce,0x4a,0x6f}, {0x09,0xd4,0xea,0x9f}, {0x7c,0xd6,0x29,0xb0}, {0xb2,0xaf,0x31,0xa4}, {0x23,0x31,0x2a,0x3f}, {0x94,0x30,0xc6,0xa5}, {0x66,0xc0,0x35,0xa2}, {0xbc,0x37,0x74,0x4e}, {0xca,0xa6,0xfc,0x82}, {0xd0,0xb0,0xe0,0x90}, {0xd8,0x15,0x33,0xa7}, {0x98,0x4a,0xf1,0x04}, {0xda,0xf7,0x41,0xec}, {0x50,0x0e,0x7f,0xcd}, {0xf6,0x2f,0x17,0x91}, {0xd6,0x8d,0x76,0x4d}, {0xb0,0x4d,0x43,0xef}, {0x4d,0x54,0xcc,0xaa}, {0x04,0xdf,0xe4,0x96}, {0xb5,0xe3,0x9e,0xd1}, {0x88,0x1b,0x4c,0x6a}, {0x1f,0xb8,0xc1,0x2c}, {0x51,0x7f,0x46,0x65}, {0xea,0x04,0x9d,0x5e}, {0x35,0x5d,0x01,0x8c}, {0x74,0x73,0xfa,0x87}, {0x41,0x2e,0xfb,0x0b}, {0x1d,0x5a,0xb3,0x67}, {0xd2,0x52,0x92,0xdb}, {0x56,0x33,0xe9,0x10}, {0x47,0x13,0x6d,0xd6}, {0x61,0x8c,0x9a,0xd7}, {0x0c,0x7a,0x37,0xa1}, {0x14,0x8e,0x59,0xf8}, {0x3c,0x89,0xeb,0x13}, {0x27,0xee,0xce,0xa9}, {0xc9,0x35,0xb7,0x61}, {0xe5,0xed,0xe1,0x1c}, {0xb1,0x3c,0x7a,0x47}, {0xdf,0x59,0x9c,0xd2}, {0x73,0x3f,0x55,0xf2}, {0xce,0x79,0x18,0x14}, {0x37,0xbf,0x73,0xc7}, {0xcd,0xea,0x53,0xf7}, {0xaa,0x5b,0x5f,0xfd}, {0x6f,0x14,0xdf,0x3d}, {0xdb,0x86,0x78,0x44}, {0xf3,0x81,0xca,0xaf}, {0xc4,0x3e,0xb9,0x68}, {0x34,0x2c,0x38,0x24}, {0x40,0x5f,0xc2,0xa3}, {0xc3,0x72,0x16,0x1d}, {0x25,0x0c,0xbc,0xe2}, {0x49,0x8b,0x28,0x3c}, {0x95,0x41,0xff,0x0d}, {0x01,0x71,0x39,0xa8}, {0xb3,0xde,0x08,0x0c}, {0xe4,0x9c,0xd8,0xb4}, {0xc1,0x90,0x64,0x56}, {0x84,0x61,0x7b,0xcb}, {0xb6,0x70,0xd5,0x32}, {0x5c,0x74,0x48,0x6c}, {0x57,0x42,0xd0,0xb8}, }; word8 T8[256][4] = { {0xf4,0xa7,0x50,0x51}, {0x41,0x65,0x53,0x7e}, {0x17,0xa4,0xc3,0x1a}, {0x27,0x5e,0x96,0x3a}, {0xab,0x6b,0xcb,0x3b}, {0x9d,0x45,0xf1,0x1f}, {0xfa,0x58,0xab,0xac}, {0xe3,0x03,0x93,0x4b}, {0x30,0xfa,0x55,0x20}, {0x76,0x6d,0xf6,0xad}, {0xcc,0x76,0x91,0x88}, {0x02,0x4c,0x25,0xf5}, {0xe5,0xd7,0xfc,0x4f}, {0x2a,0xcb,0xd7,0xc5}, {0x35,0x44,0x80,0x26}, {0x62,0xa3,0x8f,0xb5}, {0xb1,0x5a,0x49,0xde}, {0xba,0x1b,0x67,0x25}, {0xea,0x0e,0x98,0x45}, {0xfe,0xc0,0xe1,0x5d}, {0x2f,0x75,0x02,0xc3}, {0x4c,0xf0,0x12,0x81}, {0x46,0x97,0xa3,0x8d}, {0xd3,0xf9,0xc6,0x6b}, {0x8f,0x5f,0xe7,0x03}, {0x92,0x9c,0x95,0x15}, {0x6d,0x7a,0xeb,0xbf}, {0x52,0x59,0xda,0x95}, {0xbe,0x83,0x2d,0xd4}, {0x74,0x21,0xd3,0x58}, {0xe0,0x69,0x29,0x49}, {0xc9,0xc8,0x44,0x8e}, {0xc2,0x89,0x6a,0x75}, {0x8e,0x79,0x78,0xf4}, {0x58,0x3e,0x6b,0x99}, {0xb9,0x71,0xdd,0x27}, {0xe1,0x4f,0xb6,0xbe}, {0x88,0xad,0x17,0xf0}, {0x20,0xac,0x66,0xc9}, {0xce,0x3a,0xb4,0x7d}, {0xdf,0x4a,0x18,0x63}, {0x1a,0x31,0x82,0xe5}, {0x51,0x33,0x60,0x97}, {0x53,0x7f,0x45,0x62}, {0x64,0x77,0xe0,0xb1}, {0x6b,0xae,0x84,0xbb}, {0x81,0xa0,0x1c,0xfe}, {0x08,0x2b,0x94,0xf9}, {0x48,0x68,0x58,0x70}, {0x45,0xfd,0x19,0x8f}, {0xde,0x6c,0x87,0x94}, {0x7b,0xf8,0xb7,0x52}, {0x73,0xd3,0x23,0xab}, {0x4b,0x02,0xe2,0x72}, {0x1f,0x8f,0x57,0xe3}, {0x55,0xab,0x2a,0x66}, {0xeb,0x28,0x07,0xb2}, {0xb5,0xc2,0x03,0x2f}, {0xc5,0x7b,0x9a,0x86}, {0x37,0x08,0xa5,0xd3}, {0x28,0x87,0xf2,0x30}, {0xbf,0xa5,0xb2,0x23}, {0x03,0x6a,0xba,0x02}, {0x16,0x82,0x5c,0xed}, {0xcf,0x1c,0x2b,0x8a}, {0x79,0xb4,0x92,0xa7}, {0x07,0xf2,0xf0,0xf3}, {0x69,0xe2,0xa1,0x4e}, {0xda,0xf4,0xcd,0x65}, {0x05,0xbe,0xd5,0x06}, {0x34,0x62,0x1f,0xd1}, {0xa6,0xfe,0x8a,0xc4}, {0x2e,0x53,0x9d,0x34}, {0xf3,0x55,0xa0,0xa2}, {0x8a,0xe1,0x32,0x05}, {0xf6,0xeb,0x75,0xa4}, {0x83,0xec,0x39,0x0b}, {0x60,0xef,0xaa,0x40}, {0x71,0x9f,0x06,0x5e}, {0x6e,0x10,0x51,0xbd}, {0x21,0x8a,0xf9,0x3e}, {0xdd,0x06,0x3d,0x96}, {0x3e,0x05,0xae,0xdd}, {0xe6,0xbd,0x46,0x4d}, {0x54,0x8d,0xb5,0x91}, {0xc4,0x5d,0x05,0x71}, {0x06,0xd4,0x6f,0x04}, {0x50,0x15,0xff,0x60}, {0x98,0xfb,0x24,0x19}, {0xbd,0xe9,0x97,0xd6}, {0x40,0x43,0xcc,0x89}, {0xd9,0x9e,0x77,0x67}, {0xe8,0x42,0xbd,0xb0}, {0x89,0x8b,0x88,0x07}, {0x19,0x5b,0x38,0xe7}, {0xc8,0xee,0xdb,0x79}, {0x7c,0x0a,0x47,0xa1}, {0x42,0x0f,0xe9,0x7c}, {0x84,0x1e,0xc9,0xf8}, {0x00,0x00,0x00,0x00}, {0x80,0x86,0x83,0x09}, {0x2b,0xed,0x48,0x32}, {0x11,0x70,0xac,0x1e}, {0x5a,0x72,0x4e,0x6c}, {0x0e,0xff,0xfb,0xfd}, {0x85,0x38,0x56,0x0f}, {0xae,0xd5,0x1e,0x3d}, {0x2d,0x39,0x27,0x36}, {0x0f,0xd9,0x64,0x0a}, {0x5c,0xa6,0x21,0x68}, {0x5b,0x54,0xd1,0x9b}, {0x36,0x2e,0x3a,0x24}, {0x0a,0x67,0xb1,0x0c}, {0x57,0xe7,0x0f,0x93}, {0xee,0x96,0xd2,0xb4}, {0x9b,0x91,0x9e,0x1b}, {0xc0,0xc5,0x4f,0x80}, {0xdc,0x20,0xa2,0x61}, {0x77,0x4b,0x69,0x5a}, {0x12,0x1a,0x16,0x1c}, {0x93,0xba,0x0a,0xe2}, {0xa0,0x2a,0xe5,0xc0}, {0x22,0xe0,0x43,0x3c}, {0x1b,0x17,0x1d,0x12}, {0x09,0x0d,0x0b,0x0e}, {0x8b,0xc7,0xad,0xf2}, {0xb6,0xa8,0xb9,0x2d}, {0x1e,0xa9,0xc8,0x14}, {0xf1,0x19,0x85,0x57}, {0x75,0x07,0x4c,0xaf}, {0x99,0xdd,0xbb,0xee}, {0x7f,0x60,0xfd,0xa3}, {0x01,0x26,0x9f,0xf7}, {0x72,0xf5,0xbc,0x5c}, {0x66,0x3b,0xc5,0x44}, {0xfb,0x7e,0x34,0x5b}, {0x43,0x29,0x76,0x8b}, {0x23,0xc6,0xdc,0xcb}, {0xed,0xfc,0x68,0xb6}, {0xe4,0xf1,0x63,0xb8}, {0x31,0xdc,0xca,0xd7}, {0x63,0x85,0x10,0x42}, {0x97,0x22,0x40,0x13}, {0xc6,0x11,0x20,0x84}, {0x4a,0x24,0x7d,0x85}, {0xbb,0x3d,0xf8,0xd2}, {0xf9,0x32,0x11,0xae}, {0x29,0xa1,0x6d,0xc7}, {0x9e,0x2f,0x4b,0x1d}, {0xb2,0x30,0xf3,0xdc}, {0x86,0x52,0xec,0x0d}, {0xc1,0xe3,0xd0,0x77}, {0xb3,0x16,0x6c,0x2b}, {0x70,0xb9,0x99,0xa9}, {0x94,0x48,0xfa,0x11}, {0xe9,0x64,0x22,0x47}, {0xfc,0x8c,0xc4,0xa8}, {0xf0,0x3f,0x1a,0xa0}, {0x7d,0x2c,0xd8,0x56}, {0x33,0x90,0xef,0x22}, {0x49,0x4e,0xc7,0x87}, {0x38,0xd1,0xc1,0xd9}, {0xca,0xa2,0xfe,0x8c}, {0xd4,0x0b,0x36,0x98}, {0xf5,0x81,0xcf,0xa6}, {0x7a,0xde,0x28,0xa5}, {0xb7,0x8e,0x26,0xda}, {0xad,0xbf,0xa4,0x3f}, {0x3a,0x9d,0xe4,0x2c}, {0x78,0x92,0x0d,0x50}, {0x5f,0xcc,0x9b,0x6a}, {0x7e,0x46,0x62,0x54}, {0x8d,0x13,0xc2,0xf6}, {0xd8,0xb8,0xe8,0x90}, {0x39,0xf7,0x5e,0x2e}, {0xc3,0xaf,0xf5,0x82}, {0x5d,0x80,0xbe,0x9f}, {0xd0,0x93,0x7c,0x69}, {0xd5,0x2d,0xa9,0x6f}, {0x25,0x12,0xb3,0xcf}, {0xac,0x99,0x3b,0xc8}, {0x18,0x7d,0xa7,0x10}, {0x9c,0x63,0x6e,0xe8}, {0x3b,0xbb,0x7b,0xdb}, {0x26,0x78,0x09,0xcd}, {0x59,0x18,0xf4,0x6e}, {0x9a,0xb7,0x01,0xec}, {0x4f,0x9a,0xa8,0x83}, {0x95,0x6e,0x65,0xe6}, {0xff,0xe6,0x7e,0xaa}, {0xbc,0xcf,0x08,0x21}, {0x15,0xe8,0xe6,0xef}, {0xe7,0x9b,0xd9,0xba}, {0x6f,0x36,0xce,0x4a}, {0x9f,0x09,0xd4,0xea}, {0xb0,0x7c,0xd6,0x29}, {0xa4,0xb2,0xaf,0x31}, {0x3f,0x23,0x31,0x2a}, {0xa5,0x94,0x30,0xc6}, {0xa2,0x66,0xc0,0x35}, {0x4e,0xbc,0x37,0x74}, {0x82,0xca,0xa6,0xfc}, {0x90,0xd0,0xb0,0xe0}, {0xa7,0xd8,0x15,0x33}, {0x04,0x98,0x4a,0xf1}, {0xec,0xda,0xf7,0x41}, {0xcd,0x50,0x0e,0x7f}, {0x91,0xf6,0x2f,0x17}, {0x4d,0xd6,0x8d,0x76}, {0xef,0xb0,0x4d,0x43}, {0xaa,0x4d,0x54,0xcc}, {0x96,0x04,0xdf,0xe4}, {0xd1,0xb5,0xe3,0x9e}, {0x6a,0x88,0x1b,0x4c}, {0x2c,0x1f,0xb8,0xc1}, {0x65,0x51,0x7f,0x46}, {0x5e,0xea,0x04,0x9d}, {0x8c,0x35,0x5d,0x01}, {0x87,0x74,0x73,0xfa}, {0x0b,0x41,0x2e,0xfb}, {0x67,0x1d,0x5a,0xb3}, {0xdb,0xd2,0x52,0x92}, {0x10,0x56,0x33,0xe9}, {0xd6,0x47,0x13,0x6d}, {0xd7,0x61,0x8c,0x9a}, {0xa1,0x0c,0x7a,0x37}, {0xf8,0x14,0x8e,0x59}, {0x13,0x3c,0x89,0xeb}, {0xa9,0x27,0xee,0xce}, {0x61,0xc9,0x35,0xb7}, {0x1c,0xe5,0xed,0xe1}, {0x47,0xb1,0x3c,0x7a}, {0xd2,0xdf,0x59,0x9c}, {0xf2,0x73,0x3f,0x55}, {0x14,0xce,0x79,0x18}, {0xc7,0x37,0xbf,0x73}, {0xf7,0xcd,0xea,0x53}, {0xfd,0xaa,0x5b,0x5f}, {0x3d,0x6f,0x14,0xdf}, {0x44,0xdb,0x86,0x78}, {0xaf,0xf3,0x81,0xca}, {0x68,0xc4,0x3e,0xb9}, {0x24,0x34,0x2c,0x38}, {0xa3,0x40,0x5f,0xc2}, {0x1d,0xc3,0x72,0x16}, {0xe2,0x25,0x0c,0xbc}, {0x3c,0x49,0x8b,0x28}, {0x0d,0x95,0x41,0xff}, {0xa8,0x01,0x71,0x39}, {0x0c,0xb3,0xde,0x08}, {0xb4,0xe4,0x9c,0xd8}, {0x56,0xc1,0x90,0x64}, {0xcb,0x84,0x61,0x7b}, {0x32,0xb6,0x70,0xd5}, {0x6c,0x5c,0x74,0x48}, {0xb8,0x57,0x42,0xd0}, }; word8 S5[256] = { 0x52,0x09,0x6a,0xd5, 0x30,0x36,0xa5,0x38, 0xbf,0x40,0xa3,0x9e, 0x81,0xf3,0xd7,0xfb, 0x7c,0xe3,0x39,0x82, 0x9b,0x2f,0xff,0x87, 0x34,0x8e,0x43,0x44, 0xc4,0xde,0xe9,0xcb, 0x54,0x7b,0x94,0x32, 0xa6,0xc2,0x23,0x3d, 0xee,0x4c,0x95,0x0b, 0x42,0xfa,0xc3,0x4e, 0x08,0x2e,0xa1,0x66, 0x28,0xd9,0x24,0xb2, 0x76,0x5b,0xa2,0x49, 0x6d,0x8b,0xd1,0x25, 0x72,0xf8,0xf6,0x64, 0x86,0x68,0x98,0x16, 0xd4,0xa4,0x5c,0xcc, 0x5d,0x65,0xb6,0x92, 0x6c,0x70,0x48,0x50, 0xfd,0xed,0xb9,0xda, 0x5e,0x15,0x46,0x57, 0xa7,0x8d,0x9d,0x84, 0x90,0xd8,0xab,0x00, 0x8c,0xbc,0xd3,0x0a, 0xf7,0xe4,0x58,0x05, 0xb8,0xb3,0x45,0x06, 0xd0,0x2c,0x1e,0x8f, 0xca,0x3f,0x0f,0x02, 0xc1,0xaf,0xbd,0x03, 0x01,0x13,0x8a,0x6b, 0x3a,0x91,0x11,0x41, 0x4f,0x67,0xdc,0xea, 0x97,0xf2,0xcf,0xce, 0xf0,0xb4,0xe6,0x73, 0x96,0xac,0x74,0x22, 0xe7,0xad,0x35,0x85, 0xe2,0xf9,0x37,0xe8, 0x1c,0x75,0xdf,0x6e, 0x47,0xf1,0x1a,0x71, 0x1d,0x29,0xc5,0x89, 0x6f,0xb7,0x62,0x0e, 0xaa,0x18,0xbe,0x1b, 0xfc,0x56,0x3e,0x4b, 0xc6,0xd2,0x79,0x20, 0x9a,0xdb,0xc0,0xfe, 0x78,0xcd,0x5a,0xf4, 0x1f,0xdd,0xa8,0x33, 0x88,0x07,0xc7,0x31, 0xb1,0x12,0x10,0x59, 0x27,0x80,0xec,0x5f, 0x60,0x51,0x7f,0xa9, 0x19,0xb5,0x4a,0x0d, 0x2d,0xe5,0x7a,0x9f, 0x93,0xc9,0x9c,0xef, 0xa0,0xe0,0x3b,0x4d, 0xae,0x2a,0xf5,0xb0, 0xc8,0xeb,0xbb,0x3c, 0x83,0x53,0x99,0x61, 0x17,0x2b,0x04,0x7e, 0xba,0x77,0xd6,0x26, 0xe1,0x69,0x14,0x63, 0x55,0x21,0x0c,0x7d }; word8 U1[256][4] = { {0x00,0x00,0x00,0x00}, {0x0e,0x09,0x0d,0x0b}, {0x1c,0x12,0x1a,0x16}, {0x12,0x1b,0x17,0x1d}, {0x38,0x24,0x34,0x2c}, {0x36,0x2d,0x39,0x27}, {0x24,0x36,0x2e,0x3a}, {0x2a,0x3f,0x23,0x31}, {0x70,0x48,0x68,0x58}, {0x7e,0x41,0x65,0x53}, {0x6c,0x5a,0x72,0x4e}, {0x62,0x53,0x7f,0x45}, {0x48,0x6c,0x5c,0x74}, {0x46,0x65,0x51,0x7f}, {0x54,0x7e,0x46,0x62}, {0x5a,0x77,0x4b,0x69}, {0xe0,0x90,0xd0,0xb0}, {0xee,0x99,0xdd,0xbb}, {0xfc,0x82,0xca,0xa6}, {0xf2,0x8b,0xc7,0xad}, {0xd8,0xb4,0xe4,0x9c}, {0xd6,0xbd,0xe9,0x97}, {0xc4,0xa6,0xfe,0x8a}, {0xca,0xaf,0xf3,0x81}, {0x90,0xd8,0xb8,0xe8}, {0x9e,0xd1,0xb5,0xe3}, {0x8c,0xca,0xa2,0xfe}, {0x82,0xc3,0xaf,0xf5}, {0xa8,0xfc,0x8c,0xc4}, {0xa6,0xf5,0x81,0xcf}, {0xb4,0xee,0x96,0xd2}, {0xba,0xe7,0x9b,0xd9}, {0xdb,0x3b,0xbb,0x7b}, {0xd5,0x32,0xb6,0x70}, {0xc7,0x29,0xa1,0x6d}, {0xc9,0x20,0xac,0x66}, {0xe3,0x1f,0x8f,0x57}, {0xed,0x16,0x82,0x5c}, {0xff,0x0d,0x95,0x41}, {0xf1,0x04,0x98,0x4a}, {0xab,0x73,0xd3,0x23}, {0xa5,0x7a,0xde,0x28}, {0xb7,0x61,0xc9,0x35}, {0xb9,0x68,0xc4,0x3e}, {0x93,0x57,0xe7,0x0f}, {0x9d,0x5e,0xea,0x04}, {0x8f,0x45,0xfd,0x19}, {0x81,0x4c,0xf0,0x12}, {0x3b,0xab,0x6b,0xcb}, {0x35,0xa2,0x66,0xc0}, {0x27,0xb9,0x71,0xdd}, {0x29,0xb0,0x7c,0xd6}, {0x03,0x8f,0x5f,0xe7}, {0x0d,0x86,0x52,0xec}, {0x1f,0x9d,0x45,0xf1}, {0x11,0x94,0x48,0xfa}, {0x4b,0xe3,0x03,0x93}, {0x45,0xea,0x0e,0x98}, {0x57,0xf1,0x19,0x85}, {0x59,0xf8,0x14,0x8e}, {0x73,0xc7,0x37,0xbf}, {0x7d,0xce,0x3a,0xb4}, {0x6f,0xd5,0x2d,0xa9}, {0x61,0xdc,0x20,0xa2}, {0xad,0x76,0x6d,0xf6}, {0xa3,0x7f,0x60,0xfd}, {0xb1,0x64,0x77,0xe0}, {0xbf,0x6d,0x7a,0xeb}, {0x95,0x52,0x59,0xda}, {0x9b,0x5b,0x54,0xd1}, {0x89,0x40,0x43,0xcc}, {0x87,0x49,0x4e,0xc7}, {0xdd,0x3e,0x05,0xae}, {0xd3,0x37,0x08,0xa5}, {0xc1,0x2c,0x1f,0xb8}, {0xcf,0x25,0x12,0xb3}, {0xe5,0x1a,0x31,0x82}, {0xeb,0x13,0x3c,0x89}, {0xf9,0x08,0x2b,0x94}, {0xf7,0x01,0x26,0x9f}, {0x4d,0xe6,0xbd,0x46}, {0x43,0xef,0xb0,0x4d}, {0x51,0xf4,0xa7,0x50}, {0x5f,0xfd,0xaa,0x5b}, {0x75,0xc2,0x89,0x6a}, {0x7b,0xcb,0x84,0x61}, {0x69,0xd0,0x93,0x7c}, {0x67,0xd9,0x9e,0x77}, {0x3d,0xae,0xd5,0x1e}, {0x33,0xa7,0xd8,0x15}, {0x21,0xbc,0xcf,0x08}, {0x2f,0xb5,0xc2,0x03}, {0x05,0x8a,0xe1,0x32}, {0x0b,0x83,0xec,0x39}, {0x19,0x98,0xfb,0x24}, {0x17,0x91,0xf6,0x2f}, {0x76,0x4d,0xd6,0x8d}, {0x78,0x44,0xdb,0x86}, {0x6a,0x5f,0xcc,0x9b}, {0x64,0x56,0xc1,0x90}, {0x4e,0x69,0xe2,0xa1}, {0x40,0x60,0xef,0xaa}, {0x52,0x7b,0xf8,0xb7}, {0x5c,0x72,0xf5,0xbc}, {0x06,0x05,0xbe,0xd5}, {0x08,0x0c,0xb3,0xde}, {0x1a,0x17,0xa4,0xc3}, {0x14,0x1e,0xa9,0xc8}, {0x3e,0x21,0x8a,0xf9}, {0x30,0x28,0x87,0xf2}, {0x22,0x33,0x90,0xef}, {0x2c,0x3a,0x9d,0xe4}, {0x96,0xdd,0x06,0x3d}, {0x98,0xd4,0x0b,0x36}, {0x8a,0xcf,0x1c,0x2b}, {0x84,0xc6,0x11,0x20}, {0xae,0xf9,0x32,0x11}, {0xa0,0xf0,0x3f,0x1a}, {0xb2,0xeb,0x28,0x07}, {0xbc,0xe2,0x25,0x0c}, {0xe6,0x95,0x6e,0x65}, {0xe8,0x9c,0x63,0x6e}, {0xfa,0x87,0x74,0x73}, {0xf4,0x8e,0x79,0x78}, {0xde,0xb1,0x5a,0x49}, {0xd0,0xb8,0x57,0x42}, {0xc2,0xa3,0x40,0x5f}, {0xcc,0xaa,0x4d,0x54}, {0x41,0xec,0xda,0xf7}, {0x4f,0xe5,0xd7,0xfc}, {0x5d,0xfe,0xc0,0xe1}, {0x53,0xf7,0xcd,0xea}, {0x79,0xc8,0xee,0xdb}, {0x77,0xc1,0xe3,0xd0}, {0x65,0xda,0xf4,0xcd}, {0x6b,0xd3,0xf9,0xc6}, {0x31,0xa4,0xb2,0xaf}, {0x3f,0xad,0xbf,0xa4}, {0x2d,0xb6,0xa8,0xb9}, {0x23,0xbf,0xa5,0xb2}, {0x09,0x80,0x86,0x83}, {0x07,0x89,0x8b,0x88}, {0x15,0x92,0x9c,0x95}, {0x1b,0x9b,0x91,0x9e}, {0xa1,0x7c,0x0a,0x47}, {0xaf,0x75,0x07,0x4c}, {0xbd,0x6e,0x10,0x51}, {0xb3,0x67,0x1d,0x5a}, {0x99,0x58,0x3e,0x6b}, {0x97,0x51,0x33,0x60}, {0x85,0x4a,0x24,0x7d}, {0x8b,0x43,0x29,0x76}, {0xd1,0x34,0x62,0x1f}, {0xdf,0x3d,0x6f,0x14}, {0xcd,0x26,0x78,0x09}, {0xc3,0x2f,0x75,0x02}, {0xe9,0x10,0x56,0x33}, {0xe7,0x19,0x5b,0x38}, {0xf5,0x02,0x4c,0x25}, {0xfb,0x0b,0x41,0x2e}, {0x9a,0xd7,0x61,0x8c}, {0x94,0xde,0x6c,0x87}, {0x86,0xc5,0x7b,0x9a}, {0x88,0xcc,0x76,0x91}, {0xa2,0xf3,0x55,0xa0}, {0xac,0xfa,0x58,0xab}, {0xbe,0xe1,0x4f,0xb6}, {0xb0,0xe8,0x42,0xbd}, {0xea,0x9f,0x09,0xd4}, {0xe4,0x96,0x04,0xdf}, {0xf6,0x8d,0x13,0xc2}, {0xf8,0x84,0x1e,0xc9}, {0xd2,0xbb,0x3d,0xf8}, {0xdc,0xb2,0x30,0xf3}, {0xce,0xa9,0x27,0xee}, {0xc0,0xa0,0x2a,0xe5}, {0x7a,0x47,0xb1,0x3c}, {0x74,0x4e,0xbc,0x37}, {0x66,0x55,0xab,0x2a}, {0x68,0x5c,0xa6,0x21}, {0x42,0x63,0x85,0x10}, {0x4c,0x6a,0x88,0x1b}, {0x5e,0x71,0x9f,0x06}, {0x50,0x78,0x92,0x0d}, {0x0a,0x0f,0xd9,0x64}, {0x04,0x06,0xd4,0x6f}, {0x16,0x1d,0xc3,0x72}, {0x18,0x14,0xce,0x79}, {0x32,0x2b,0xed,0x48}, {0x3c,0x22,0xe0,0x43}, {0x2e,0x39,0xf7,0x5e}, {0x20,0x30,0xfa,0x55}, {0xec,0x9a,0xb7,0x01}, {0xe2,0x93,0xba,0x0a}, {0xf0,0x88,0xad,0x17}, {0xfe,0x81,0xa0,0x1c}, {0xd4,0xbe,0x83,0x2d}, {0xda,0xb7,0x8e,0x26}, {0xc8,0xac,0x99,0x3b}, {0xc6,0xa5,0x94,0x30}, {0x9c,0xd2,0xdf,0x59}, {0x92,0xdb,0xd2,0x52}, {0x80,0xc0,0xc5,0x4f}, {0x8e,0xc9,0xc8,0x44}, {0xa4,0xf6,0xeb,0x75}, {0xaa,0xff,0xe6,0x7e}, {0xb8,0xe4,0xf1,0x63}, {0xb6,0xed,0xfc,0x68}, {0x0c,0x0a,0x67,0xb1}, {0x02,0x03,0x6a,0xba}, {0x10,0x18,0x7d,0xa7}, {0x1e,0x11,0x70,0xac}, {0x34,0x2e,0x53,0x9d}, {0x3a,0x27,0x5e,0x96}, {0x28,0x3c,0x49,0x8b}, {0x26,0x35,0x44,0x80}, {0x7c,0x42,0x0f,0xe9}, {0x72,0x4b,0x02,0xe2}, {0x60,0x50,0x15,0xff}, {0x6e,0x59,0x18,0xf4}, {0x44,0x66,0x3b,0xc5}, {0x4a,0x6f,0x36,0xce}, {0x58,0x74,0x21,0xd3}, {0x56,0x7d,0x2c,0xd8}, {0x37,0xa1,0x0c,0x7a}, {0x39,0xa8,0x01,0x71}, {0x2b,0xb3,0x16,0x6c}, {0x25,0xba,0x1b,0x67}, {0x0f,0x85,0x38,0x56}, {0x01,0x8c,0x35,0x5d}, {0x13,0x97,0x22,0x40}, {0x1d,0x9e,0x2f,0x4b}, {0x47,0xe9,0x64,0x22}, {0x49,0xe0,0x69,0x29}, {0x5b,0xfb,0x7e,0x34}, {0x55,0xf2,0x73,0x3f}, {0x7f,0xcd,0x50,0x0e}, {0x71,0xc4,0x5d,0x05}, {0x63,0xdf,0x4a,0x18}, {0x6d,0xd6,0x47,0x13}, {0xd7,0x31,0xdc,0xca}, {0xd9,0x38,0xd1,0xc1}, {0xcb,0x23,0xc6,0xdc}, {0xc5,0x2a,0xcb,0xd7}, {0xef,0x15,0xe8,0xe6}, {0xe1,0x1c,0xe5,0xed}, {0xf3,0x07,0xf2,0xf0}, {0xfd,0x0e,0xff,0xfb}, {0xa7,0x79,0xb4,0x92}, {0xa9,0x70,0xb9,0x99}, {0xbb,0x6b,0xae,0x84}, {0xb5,0x62,0xa3,0x8f}, {0x9f,0x5d,0x80,0xbe}, {0x91,0x54,0x8d,0xb5}, {0x83,0x4f,0x9a,0xa8}, {0x8d,0x46,0x97,0xa3} }; word8 U2[256][4] = { {0x00,0x00,0x00,0x00}, {0x0b,0x0e,0x09,0x0d}, {0x16,0x1c,0x12,0x1a}, {0x1d,0x12,0x1b,0x17}, {0x2c,0x38,0x24,0x34}, {0x27,0x36,0x2d,0x39}, {0x3a,0x24,0x36,0x2e}, {0x31,0x2a,0x3f,0x23}, {0x58,0x70,0x48,0x68}, {0x53,0x7e,0x41,0x65}, {0x4e,0x6c,0x5a,0x72}, {0x45,0x62,0x53,0x7f}, {0x74,0x48,0x6c,0x5c}, {0x7f,0x46,0x65,0x51}, {0x62,0x54,0x7e,0x46}, {0x69,0x5a,0x77,0x4b}, {0xb0,0xe0,0x90,0xd0}, {0xbb,0xee,0x99,0xdd}, {0xa6,0xfc,0x82,0xca}, {0xad,0xf2,0x8b,0xc7}, {0x9c,0xd8,0xb4,0xe4}, {0x97,0xd6,0xbd,0xe9}, {0x8a,0xc4,0xa6,0xfe}, {0x81,0xca,0xaf,0xf3}, {0xe8,0x90,0xd8,0xb8}, {0xe3,0x9e,0xd1,0xb5}, {0xfe,0x8c,0xca,0xa2}, {0xf5,0x82,0xc3,0xaf}, {0xc4,0xa8,0xfc,0x8c}, {0xcf,0xa6,0xf5,0x81}, {0xd2,0xb4,0xee,0x96}, {0xd9,0xba,0xe7,0x9b}, {0x7b,0xdb,0x3b,0xbb}, {0x70,0xd5,0x32,0xb6}, {0x6d,0xc7,0x29,0xa1}, {0x66,0xc9,0x20,0xac}, {0x57,0xe3,0x1f,0x8f}, {0x5c,0xed,0x16,0x82}, {0x41,0xff,0x0d,0x95}, {0x4a,0xf1,0x04,0x98}, {0x23,0xab,0x73,0xd3}, {0x28,0xa5,0x7a,0xde}, {0x35,0xb7,0x61,0xc9}, {0x3e,0xb9,0x68,0xc4}, {0x0f,0x93,0x57,0xe7}, {0x04,0x9d,0x5e,0xea}, {0x19,0x8f,0x45,0xfd}, {0x12,0x81,0x4c,0xf0}, {0xcb,0x3b,0xab,0x6b}, {0xc0,0x35,0xa2,0x66}, {0xdd,0x27,0xb9,0x71}, {0xd6,0x29,0xb0,0x7c}, {0xe7,0x03,0x8f,0x5f}, {0xec,0x0d,0x86,0x52}, {0xf1,0x1f,0x9d,0x45}, {0xfa,0x11,0x94,0x48}, {0x93,0x4b,0xe3,0x03}, {0x98,0x45,0xea,0x0e}, {0x85,0x57,0xf1,0x19}, {0x8e,0x59,0xf8,0x14}, {0xbf,0x73,0xc7,0x37}, {0xb4,0x7d,0xce,0x3a}, {0xa9,0x6f,0xd5,0x2d}, {0xa2,0x61,0xdc,0x20}, {0xf6,0xad,0x76,0x6d}, {0xfd,0xa3,0x7f,0x60}, {0xe0,0xb1,0x64,0x77}, {0xeb,0xbf,0x6d,0x7a}, {0xda,0x95,0x52,0x59}, {0xd1,0x9b,0x5b,0x54}, {0xcc,0x89,0x40,0x43}, {0xc7,0x87,0x49,0x4e}, {0xae,0xdd,0x3e,0x05}, {0xa5,0xd3,0x37,0x08}, {0xb8,0xc1,0x2c,0x1f}, {0xb3,0xcf,0x25,0x12}, {0x82,0xe5,0x1a,0x31}, {0x89,0xeb,0x13,0x3c}, {0x94,0xf9,0x08,0x2b}, {0x9f,0xf7,0x01,0x26}, {0x46,0x4d,0xe6,0xbd}, {0x4d,0x43,0xef,0xb0}, {0x50,0x51,0xf4,0xa7}, {0x5b,0x5f,0xfd,0xaa}, {0x6a,0x75,0xc2,0x89}, {0x61,0x7b,0xcb,0x84}, {0x7c,0x69,0xd0,0x93}, {0x77,0x67,0xd9,0x9e}, {0x1e,0x3d,0xae,0xd5}, {0x15,0x33,0xa7,0xd8}, {0x08,0x21,0xbc,0xcf}, {0x03,0x2f,0xb5,0xc2}, {0x32,0x05,0x8a,0xe1}, {0x39,0x0b,0x83,0xec}, {0x24,0x19,0x98,0xfb}, {0x2f,0x17,0x91,0xf6}, {0x8d,0x76,0x4d,0xd6}, {0x86,0x78,0x44,0xdb}, {0x9b,0x6a,0x5f,0xcc}, {0x90,0x64,0x56,0xc1}, {0xa1,0x4e,0x69,0xe2}, {0xaa,0x40,0x60,0xef}, {0xb7,0x52,0x7b,0xf8}, {0xbc,0x5c,0x72,0xf5}, {0xd5,0x06,0x05,0xbe}, {0xde,0x08,0x0c,0xb3}, {0xc3,0x1a,0x17,0xa4}, {0xc8,0x14,0x1e,0xa9}, {0xf9,0x3e,0x21,0x8a}, {0xf2,0x30,0x28,0x87}, {0xef,0x22,0x33,0x90}, {0xe4,0x2c,0x3a,0x9d}, {0x3d,0x96,0xdd,0x06}, {0x36,0x98,0xd4,0x0b}, {0x2b,0x8a,0xcf,0x1c}, {0x20,0x84,0xc6,0x11}, {0x11,0xae,0xf9,0x32}, {0x1a,0xa0,0xf0,0x3f}, {0x07,0xb2,0xeb,0x28}, {0x0c,0xbc,0xe2,0x25}, {0x65,0xe6,0x95,0x6e}, {0x6e,0xe8,0x9c,0x63}, {0x73,0xfa,0x87,0x74}, {0x78,0xf4,0x8e,0x79}, {0x49,0xde,0xb1,0x5a}, {0x42,0xd0,0xb8,0x57}, {0x5f,0xc2,0xa3,0x40}, {0x54,0xcc,0xaa,0x4d}, {0xf7,0x41,0xec,0xda}, {0xfc,0x4f,0xe5,0xd7}, {0xe1,0x5d,0xfe,0xc0}, {0xea,0x53,0xf7,0xcd}, {0xdb,0x79,0xc8,0xee}, {0xd0,0x77,0xc1,0xe3}, {0xcd,0x65,0xda,0xf4}, {0xc6,0x6b,0xd3,0xf9}, {0xaf,0x31,0xa4,0xb2}, {0xa4,0x3f,0xad,0xbf}, {0xb9,0x2d,0xb6,0xa8}, {0xb2,0x23,0xbf,0xa5}, {0x83,0x09,0x80,0x86}, {0x88,0x07,0x89,0x8b}, {0x95,0x15,0x92,0x9c}, {0x9e,0x1b,0x9b,0x91}, {0x47,0xa1,0x7c,0x0a}, {0x4c,0xaf,0x75,0x07}, {0x51,0xbd,0x6e,0x10}, {0x5a,0xb3,0x67,0x1d}, {0x6b,0x99,0x58,0x3e}, {0x60,0x97,0x51,0x33}, {0x7d,0x85,0x4a,0x24}, {0x76,0x8b,0x43,0x29}, {0x1f,0xd1,0x34,0x62}, {0x14,0xdf,0x3d,0x6f}, {0x09,0xcd,0x26,0x78}, {0x02,0xc3,0x2f,0x75}, {0x33,0xe9,0x10,0x56}, {0x38,0xe7,0x19,0x5b}, {0x25,0xf5,0x02,0x4c}, {0x2e,0xfb,0x0b,0x41}, {0x8c,0x9a,0xd7,0x61}, {0x87,0x94,0xde,0x6c}, {0x9a,0x86,0xc5,0x7b}, {0x91,0x88,0xcc,0x76}, {0xa0,0xa2,0xf3,0x55}, {0xab,0xac,0xfa,0x58}, {0xb6,0xbe,0xe1,0x4f}, {0xbd,0xb0,0xe8,0x42}, {0xd4,0xea,0x9f,0x09}, {0xdf,0xe4,0x96,0x04}, {0xc2,0xf6,0x8d,0x13}, {0xc9,0xf8,0x84,0x1e}, {0xf8,0xd2,0xbb,0x3d}, {0xf3,0xdc,0xb2,0x30}, {0xee,0xce,0xa9,0x27}, {0xe5,0xc0,0xa0,0x2a}, {0x3c,0x7a,0x47,0xb1}, {0x37,0x74,0x4e,0xbc}, {0x2a,0x66,0x55,0xab}, {0x21,0x68,0x5c,0xa6}, {0x10,0x42,0x63,0x85}, {0x1b,0x4c,0x6a,0x88}, {0x06,0x5e,0x71,0x9f}, {0x0d,0x50,0x78,0x92}, {0x64,0x0a,0x0f,0xd9}, {0x6f,0x04,0x06,0xd4}, {0x72,0x16,0x1d,0xc3}, {0x79,0x18,0x14,0xce}, {0x48,0x32,0x2b,0xed}, {0x43,0x3c,0x22,0xe0}, {0x5e,0x2e,0x39,0xf7}, {0x55,0x20,0x30,0xfa}, {0x01,0xec,0x9a,0xb7}, {0x0a,0xe2,0x93,0xba}, {0x17,0xf0,0x88,0xad}, {0x1c,0xfe,0x81,0xa0}, {0x2d,0xd4,0xbe,0x83}, {0x26,0xda,0xb7,0x8e}, {0x3b,0xc8,0xac,0x99}, {0x30,0xc6,0xa5,0x94}, {0x59,0x9c,0xd2,0xdf}, {0x52,0x92,0xdb,0xd2}, {0x4f,0x80,0xc0,0xc5}, {0x44,0x8e,0xc9,0xc8}, {0x75,0xa4,0xf6,0xeb}, {0x7e,0xaa,0xff,0xe6}, {0x63,0xb8,0xe4,0xf1}, {0x68,0xb6,0xed,0xfc}, {0xb1,0x0c,0x0a,0x67}, {0xba,0x02,0x03,0x6a}, {0xa7,0x10,0x18,0x7d}, {0xac,0x1e,0x11,0x70}, {0x9d,0x34,0x2e,0x53}, {0x96,0x3a,0x27,0x5e}, {0x8b,0x28,0x3c,0x49}, {0x80,0x26,0x35,0x44}, {0xe9,0x7c,0x42,0x0f}, {0xe2,0x72,0x4b,0x02}, {0xff,0x60,0x50,0x15}, {0xf4,0x6e,0x59,0x18}, {0xc5,0x44,0x66,0x3b}, {0xce,0x4a,0x6f,0x36}, {0xd3,0x58,0x74,0x21}, {0xd8,0x56,0x7d,0x2c}, {0x7a,0x37,0xa1,0x0c}, {0x71,0x39,0xa8,0x01}, {0x6c,0x2b,0xb3,0x16}, {0x67,0x25,0xba,0x1b}, {0x56,0x0f,0x85,0x38}, {0x5d,0x01,0x8c,0x35}, {0x40,0x13,0x97,0x22}, {0x4b,0x1d,0x9e,0x2f}, {0x22,0x47,0xe9,0x64}, {0x29,0x49,0xe0,0x69}, {0x34,0x5b,0xfb,0x7e}, {0x3f,0x55,0xf2,0x73}, {0x0e,0x7f,0xcd,0x50}, {0x05,0x71,0xc4,0x5d}, {0x18,0x63,0xdf,0x4a}, {0x13,0x6d,0xd6,0x47}, {0xca,0xd7,0x31,0xdc}, {0xc1,0xd9,0x38,0xd1}, {0xdc,0xcb,0x23,0xc6}, {0xd7,0xc5,0x2a,0xcb}, {0xe6,0xef,0x15,0xe8}, {0xed,0xe1,0x1c,0xe5}, {0xf0,0xf3,0x07,0xf2}, {0xfb,0xfd,0x0e,0xff}, {0x92,0xa7,0x79,0xb4}, {0x99,0xa9,0x70,0xb9}, {0x84,0xbb,0x6b,0xae}, {0x8f,0xb5,0x62,0xa3}, {0xbe,0x9f,0x5d,0x80}, {0xb5,0x91,0x54,0x8d}, {0xa8,0x83,0x4f,0x9a}, {0xa3,0x8d,0x46,0x97} }; word8 U3[256][4] = { {0x00,0x00,0x00,0x00}, {0x0d,0x0b,0x0e,0x09}, {0x1a,0x16,0x1c,0x12}, {0x17,0x1d,0x12,0x1b}, {0x34,0x2c,0x38,0x24}, {0x39,0x27,0x36,0x2d}, {0x2e,0x3a,0x24,0x36}, {0x23,0x31,0x2a,0x3f}, {0x68,0x58,0x70,0x48}, {0x65,0x53,0x7e,0x41}, {0x72,0x4e,0x6c,0x5a}, {0x7f,0x45,0x62,0x53}, {0x5c,0x74,0x48,0x6c}, {0x51,0x7f,0x46,0x65}, {0x46,0x62,0x54,0x7e}, {0x4b,0x69,0x5a,0x77}, {0xd0,0xb0,0xe0,0x90}, {0xdd,0xbb,0xee,0x99}, {0xca,0xa6,0xfc,0x82}, {0xc7,0xad,0xf2,0x8b}, {0xe4,0x9c,0xd8,0xb4}, {0xe9,0x97,0xd6,0xbd}, {0xfe,0x8a,0xc4,0xa6}, {0xf3,0x81,0xca,0xaf}, {0xb8,0xe8,0x90,0xd8}, {0xb5,0xe3,0x9e,0xd1}, {0xa2,0xfe,0x8c,0xca}, {0xaf,0xf5,0x82,0xc3}, {0x8c,0xc4,0xa8,0xfc}, {0x81,0xcf,0xa6,0xf5}, {0x96,0xd2,0xb4,0xee}, {0x9b,0xd9,0xba,0xe7}, {0xbb,0x7b,0xdb,0x3b}, {0xb6,0x70,0xd5,0x32}, {0xa1,0x6d,0xc7,0x29}, {0xac,0x66,0xc9,0x20}, {0x8f,0x57,0xe3,0x1f}, {0x82,0x5c,0xed,0x16}, {0x95,0x41,0xff,0x0d}, {0x98,0x4a,0xf1,0x04}, {0xd3,0x23,0xab,0x73}, {0xde,0x28,0xa5,0x7a}, {0xc9,0x35,0xb7,0x61}, {0xc4,0x3e,0xb9,0x68}, {0xe7,0x0f,0x93,0x57}, {0xea,0x04,0x9d,0x5e}, {0xfd,0x19,0x8f,0x45}, {0xf0,0x12,0x81,0x4c}, {0x6b,0xcb,0x3b,0xab}, {0x66,0xc0,0x35,0xa2}, {0x71,0xdd,0x27,0xb9}, {0x7c,0xd6,0x29,0xb0}, {0x5f,0xe7,0x03,0x8f}, {0x52,0xec,0x0d,0x86}, {0x45,0xf1,0x1f,0x9d}, {0x48,0xfa,0x11,0x94}, {0x03,0x93,0x4b,0xe3}, {0x0e,0x98,0x45,0xea}, {0x19,0x85,0x57,0xf1}, {0x14,0x8e,0x59,0xf8}, {0x37,0xbf,0x73,0xc7}, {0x3a,0xb4,0x7d,0xce}, {0x2d,0xa9,0x6f,0xd5}, {0x20,0xa2,0x61,0xdc}, {0x6d,0xf6,0xad,0x76}, {0x60,0xfd,0xa3,0x7f}, {0x77,0xe0,0xb1,0x64}, {0x7a,0xeb,0xbf,0x6d}, {0x59,0xda,0x95,0x52}, {0x54,0xd1,0x9b,0x5b}, {0x43,0xcc,0x89,0x40}, {0x4e,0xc7,0x87,0x49}, {0x05,0xae,0xdd,0x3e}, {0x08,0xa5,0xd3,0x37}, {0x1f,0xb8,0xc1,0x2c}, {0x12,0xb3,0xcf,0x25}, {0x31,0x82,0xe5,0x1a}, {0x3c,0x89,0xeb,0x13}, {0x2b,0x94,0xf9,0x08}, {0x26,0x9f,0xf7,0x01}, {0xbd,0x46,0x4d,0xe6}, {0xb0,0x4d,0x43,0xef}, {0xa7,0x50,0x51,0xf4}, {0xaa,0x5b,0x5f,0xfd}, {0x89,0x6a,0x75,0xc2}, {0x84,0x61,0x7b,0xcb}, {0x93,0x7c,0x69,0xd0}, {0x9e,0x77,0x67,0xd9}, {0xd5,0x1e,0x3d,0xae}, {0xd8,0x15,0x33,0xa7}, {0xcf,0x08,0x21,0xbc}, {0xc2,0x03,0x2f,0xb5}, {0xe1,0x32,0x05,0x8a}, {0xec,0x39,0x0b,0x83}, {0xfb,0x24,0x19,0x98}, {0xf6,0x2f,0x17,0x91}, {0xd6,0x8d,0x76,0x4d}, {0xdb,0x86,0x78,0x44}, {0xcc,0x9b,0x6a,0x5f}, {0xc1,0x90,0x64,0x56}, {0xe2,0xa1,0x4e,0x69}, {0xef,0xaa,0x40,0x60}, {0xf8,0xb7,0x52,0x7b}, {0xf5,0xbc,0x5c,0x72}, {0xbe,0xd5,0x06,0x05}, {0xb3,0xde,0x08,0x0c}, {0xa4,0xc3,0x1a,0x17}, {0xa9,0xc8,0x14,0x1e}, {0x8a,0xf9,0x3e,0x21}, {0x87,0xf2,0x30,0x28}, {0x90,0xef,0x22,0x33}, {0x9d,0xe4,0x2c,0x3a}, {0x06,0x3d,0x96,0xdd}, {0x0b,0x36,0x98,0xd4}, {0x1c,0x2b,0x8a,0xcf}, {0x11,0x20,0x84,0xc6}, {0x32,0x11,0xae,0xf9}, {0x3f,0x1a,0xa0,0xf0}, {0x28,0x07,0xb2,0xeb}, {0x25,0x0c,0xbc,0xe2}, {0x6e,0x65,0xe6,0x95}, {0x63,0x6e,0xe8,0x9c}, {0x74,0x73,0xfa,0x87}, {0x79,0x78,0xf4,0x8e}, {0x5a,0x49,0xde,0xb1}, {0x57,0x42,0xd0,0xb8}, {0x40,0x5f,0xc2,0xa3}, {0x4d,0x54,0xcc,0xaa}, {0xda,0xf7,0x41,0xec}, {0xd7,0xfc,0x4f,0xe5}, {0xc0,0xe1,0x5d,0xfe}, {0xcd,0xea,0x53,0xf7}, {0xee,0xdb,0x79,0xc8}, {0xe3,0xd0,0x77,0xc1}, {0xf4,0xcd,0x65,0xda}, {0xf9,0xc6,0x6b,0xd3}, {0xb2,0xaf,0x31,0xa4}, {0xbf,0xa4,0x3f,0xad}, {0xa8,0xb9,0x2d,0xb6}, {0xa5,0xb2,0x23,0xbf}, {0x86,0x83,0x09,0x80}, {0x8b,0x88,0x07,0x89}, {0x9c,0x95,0x15,0x92}, {0x91,0x9e,0x1b,0x9b}, {0x0a,0x47,0xa1,0x7c}, {0x07,0x4c,0xaf,0x75}, {0x10,0x51,0xbd,0x6e}, {0x1d,0x5a,0xb3,0x67}, {0x3e,0x6b,0x99,0x58}, {0x33,0x60,0x97,0x51}, {0x24,0x7d,0x85,0x4a}, {0x29,0x76,0x8b,0x43}, {0x62,0x1f,0xd1,0x34}, {0x6f,0x14,0xdf,0x3d}, {0x78,0x09,0xcd,0x26}, {0x75,0x02,0xc3,0x2f}, {0x56,0x33,0xe9,0x10}, {0x5b,0x38,0xe7,0x19}, {0x4c,0x25,0xf5,0x02}, {0x41,0x2e,0xfb,0x0b}, {0x61,0x8c,0x9a,0xd7}, {0x6c,0x87,0x94,0xde}, {0x7b,0x9a,0x86,0xc5}, {0x76,0x91,0x88,0xcc}, {0x55,0xa0,0xa2,0xf3}, {0x58,0xab,0xac,0xfa}, {0x4f,0xb6,0xbe,0xe1}, {0x42,0xbd,0xb0,0xe8}, {0x09,0xd4,0xea,0x9f}, {0x04,0xdf,0xe4,0x96}, {0x13,0xc2,0xf6,0x8d}, {0x1e,0xc9,0xf8,0x84}, {0x3d,0xf8,0xd2,0xbb}, {0x30,0xf3,0xdc,0xb2}, {0x27,0xee,0xce,0xa9}, {0x2a,0xe5,0xc0,0xa0}, {0xb1,0x3c,0x7a,0x47}, {0xbc,0x37,0x74,0x4e}, {0xab,0x2a,0x66,0x55}, {0xa6,0x21,0x68,0x5c}, {0x85,0x10,0x42,0x63}, {0x88,0x1b,0x4c,0x6a}, {0x9f,0x06,0x5e,0x71}, {0x92,0x0d,0x50,0x78}, {0xd9,0x64,0x0a,0x0f}, {0xd4,0x6f,0x04,0x06}, {0xc3,0x72,0x16,0x1d}, {0xce,0x79,0x18,0x14}, {0xed,0x48,0x32,0x2b}, {0xe0,0x43,0x3c,0x22}, {0xf7,0x5e,0x2e,0x39}, {0xfa,0x55,0x20,0x30}, {0xb7,0x01,0xec,0x9a}, {0xba,0x0a,0xe2,0x93}, {0xad,0x17,0xf0,0x88}, {0xa0,0x1c,0xfe,0x81}, {0x83,0x2d,0xd4,0xbe}, {0x8e,0x26,0xda,0xb7}, {0x99,0x3b,0xc8,0xac}, {0x94,0x30,0xc6,0xa5}, {0xdf,0x59,0x9c,0xd2}, {0xd2,0x52,0x92,0xdb}, {0xc5,0x4f,0x80,0xc0}, {0xc8,0x44,0x8e,0xc9}, {0xeb,0x75,0xa4,0xf6}, {0xe6,0x7e,0xaa,0xff}, {0xf1,0x63,0xb8,0xe4}, {0xfc,0x68,0xb6,0xed}, {0x67,0xb1,0x0c,0x0a}, {0x6a,0xba,0x02,0x03}, {0x7d,0xa7,0x10,0x18}, {0x70,0xac,0x1e,0x11}, {0x53,0x9d,0x34,0x2e}, {0x5e,0x96,0x3a,0x27}, {0x49,0x8b,0x28,0x3c}, {0x44,0x80,0x26,0x35}, {0x0f,0xe9,0x7c,0x42}, {0x02,0xe2,0x72,0x4b}, {0x15,0xff,0x60,0x50}, {0x18,0xf4,0x6e,0x59}, {0x3b,0xc5,0x44,0x66}, {0x36,0xce,0x4a,0x6f}, {0x21,0xd3,0x58,0x74}, {0x2c,0xd8,0x56,0x7d}, {0x0c,0x7a,0x37,0xa1}, {0x01,0x71,0x39,0xa8}, {0x16,0x6c,0x2b,0xb3}, {0x1b,0x67,0x25,0xba}, {0x38,0x56,0x0f,0x85}, {0x35,0x5d,0x01,0x8c}, {0x22,0x40,0x13,0x97}, {0x2f,0x4b,0x1d,0x9e}, {0x64,0x22,0x47,0xe9}, {0x69,0x29,0x49,0xe0}, {0x7e,0x34,0x5b,0xfb}, {0x73,0x3f,0x55,0xf2}, {0x50,0x0e,0x7f,0xcd}, {0x5d,0x05,0x71,0xc4}, {0x4a,0x18,0x63,0xdf}, {0x47,0x13,0x6d,0xd6}, {0xdc,0xca,0xd7,0x31}, {0xd1,0xc1,0xd9,0x38}, {0xc6,0xdc,0xcb,0x23}, {0xcb,0xd7,0xc5,0x2a}, {0xe8,0xe6,0xef,0x15}, {0xe5,0xed,0xe1,0x1c}, {0xf2,0xf0,0xf3,0x07}, {0xff,0xfb,0xfd,0x0e}, {0xb4,0x92,0xa7,0x79}, {0xb9,0x99,0xa9,0x70}, {0xae,0x84,0xbb,0x6b}, {0xa3,0x8f,0xb5,0x62}, {0x80,0xbe,0x9f,0x5d}, {0x8d,0xb5,0x91,0x54}, {0x9a,0xa8,0x83,0x4f}, {0x97,0xa3,0x8d,0x46} }; word8 U4[256][4] = { {0x00,0x00,0x00,0x00}, {0x09,0x0d,0x0b,0x0e}, {0x12,0x1a,0x16,0x1c}, {0x1b,0x17,0x1d,0x12}, {0x24,0x34,0x2c,0x38}, {0x2d,0x39,0x27,0x36}, {0x36,0x2e,0x3a,0x24}, {0x3f,0x23,0x31,0x2a}, {0x48,0x68,0x58,0x70}, {0x41,0x65,0x53,0x7e}, {0x5a,0x72,0x4e,0x6c}, {0x53,0x7f,0x45,0x62}, {0x6c,0x5c,0x74,0x48}, {0x65,0x51,0x7f,0x46}, {0x7e,0x46,0x62,0x54}, {0x77,0x4b,0x69,0x5a}, {0x90,0xd0,0xb0,0xe0}, {0x99,0xdd,0xbb,0xee}, {0x82,0xca,0xa6,0xfc}, {0x8b,0xc7,0xad,0xf2}, {0xb4,0xe4,0x9c,0xd8}, {0xbd,0xe9,0x97,0xd6}, {0xa6,0xfe,0x8a,0xc4}, {0xaf,0xf3,0x81,0xca}, {0xd8,0xb8,0xe8,0x90}, {0xd1,0xb5,0xe3,0x9e}, {0xca,0xa2,0xfe,0x8c}, {0xc3,0xaf,0xf5,0x82}, {0xfc,0x8c,0xc4,0xa8}, {0xf5,0x81,0xcf,0xa6}, {0xee,0x96,0xd2,0xb4}, {0xe7,0x9b,0xd9,0xba}, {0x3b,0xbb,0x7b,0xdb}, {0x32,0xb6,0x70,0xd5}, {0x29,0xa1,0x6d,0xc7}, {0x20,0xac,0x66,0xc9}, {0x1f,0x8f,0x57,0xe3}, {0x16,0x82,0x5c,0xed}, {0x0d,0x95,0x41,0xff}, {0x04,0x98,0x4a,0xf1}, {0x73,0xd3,0x23,0xab}, {0x7a,0xde,0x28,0xa5}, {0x61,0xc9,0x35,0xb7}, {0x68,0xc4,0x3e,0xb9}, {0x57,0xe7,0x0f,0x93}, {0x5e,0xea,0x04,0x9d}, {0x45,0xfd,0x19,0x8f}, {0x4c,0xf0,0x12,0x81}, {0xab,0x6b,0xcb,0x3b}, {0xa2,0x66,0xc0,0x35}, {0xb9,0x71,0xdd,0x27}, {0xb0,0x7c,0xd6,0x29}, {0x8f,0x5f,0xe7,0x03}, {0x86,0x52,0xec,0x0d}, {0x9d,0x45,0xf1,0x1f}, {0x94,0x48,0xfa,0x11}, {0xe3,0x03,0x93,0x4b}, {0xea,0x0e,0x98,0x45}, {0xf1,0x19,0x85,0x57}, {0xf8,0x14,0x8e,0x59}, {0xc7,0x37,0xbf,0x73}, {0xce,0x3a,0xb4,0x7d}, {0xd5,0x2d,0xa9,0x6f}, {0xdc,0x20,0xa2,0x61}, {0x76,0x6d,0xf6,0xad}, {0x7f,0x60,0xfd,0xa3}, {0x64,0x77,0xe0,0xb1}, {0x6d,0x7a,0xeb,0xbf}, {0x52,0x59,0xda,0x95}, {0x5b,0x54,0xd1,0x9b}, {0x40,0x43,0xcc,0x89}, {0x49,0x4e,0xc7,0x87}, {0x3e,0x05,0xae,0xdd}, {0x37,0x08,0xa5,0xd3}, {0x2c,0x1f,0xb8,0xc1}, {0x25,0x12,0xb3,0xcf}, {0x1a,0x31,0x82,0xe5}, {0x13,0x3c,0x89,0xeb}, {0x08,0x2b,0x94,0xf9}, {0x01,0x26,0x9f,0xf7}, {0xe6,0xbd,0x46,0x4d}, {0xef,0xb0,0x4d,0x43}, {0xf4,0xa7,0x50,0x51}, {0xfd,0xaa,0x5b,0x5f}, {0xc2,0x89,0x6a,0x75}, {0xcb,0x84,0x61,0x7b}, {0xd0,0x93,0x7c,0x69}, {0xd9,0x9e,0x77,0x67}, {0xae,0xd5,0x1e,0x3d}, {0xa7,0xd8,0x15,0x33}, {0xbc,0xcf,0x08,0x21}, {0xb5,0xc2,0x03,0x2f}, {0x8a,0xe1,0x32,0x05}, {0x83,0xec,0x39,0x0b}, {0x98,0xfb,0x24,0x19}, {0x91,0xf6,0x2f,0x17}, {0x4d,0xd6,0x8d,0x76}, {0x44,0xdb,0x86,0x78}, {0x5f,0xcc,0x9b,0x6a}, {0x56,0xc1,0x90,0x64}, {0x69,0xe2,0xa1,0x4e}, {0x60,0xef,0xaa,0x40}, {0x7b,0xf8,0xb7,0x52}, {0x72,0xf5,0xbc,0x5c}, {0x05,0xbe,0xd5,0x06}, {0x0c,0xb3,0xde,0x08}, {0x17,0xa4,0xc3,0x1a}, {0x1e,0xa9,0xc8,0x14}, {0x21,0x8a,0xf9,0x3e}, {0x28,0x87,0xf2,0x30}, {0x33,0x90,0xef,0x22}, {0x3a,0x9d,0xe4,0x2c}, {0xdd,0x06,0x3d,0x96}, {0xd4,0x0b,0x36,0x98}, {0xcf,0x1c,0x2b,0x8a}, {0xc6,0x11,0x20,0x84}, {0xf9,0x32,0x11,0xae}, {0xf0,0x3f,0x1a,0xa0}, {0xeb,0x28,0x07,0xb2}, {0xe2,0x25,0x0c,0xbc}, {0x95,0x6e,0x65,0xe6}, {0x9c,0x63,0x6e,0xe8}, {0x87,0x74,0x73,0xfa}, {0x8e,0x79,0x78,0xf4}, {0xb1,0x5a,0x49,0xde}, {0xb8,0x57,0x42,0xd0}, {0xa3,0x40,0x5f,0xc2}, {0xaa,0x4d,0x54,0xcc}, {0xec,0xda,0xf7,0x41}, {0xe5,0xd7,0xfc,0x4f}, {0xfe,0xc0,0xe1,0x5d}, {0xf7,0xcd,0xea,0x53}, {0xc8,0xee,0xdb,0x79}, {0xc1,0xe3,0xd0,0x77}, {0xda,0xf4,0xcd,0x65}, {0xd3,0xf9,0xc6,0x6b}, {0xa4,0xb2,0xaf,0x31}, {0xad,0xbf,0xa4,0x3f}, {0xb6,0xa8,0xb9,0x2d}, {0xbf,0xa5,0xb2,0x23}, {0x80,0x86,0x83,0x09}, {0x89,0x8b,0x88,0x07}, {0x92,0x9c,0x95,0x15}, {0x9b,0x91,0x9e,0x1b}, {0x7c,0x0a,0x47,0xa1}, {0x75,0x07,0x4c,0xaf}, {0x6e,0x10,0x51,0xbd}, {0x67,0x1d,0x5a,0xb3}, {0x58,0x3e,0x6b,0x99}, {0x51,0x33,0x60,0x97}, {0x4a,0x24,0x7d,0x85}, {0x43,0x29,0x76,0x8b}, {0x34,0x62,0x1f,0xd1}, {0x3d,0x6f,0x14,0xdf}, {0x26,0x78,0x09,0xcd}, {0x2f,0x75,0x02,0xc3}, {0x10,0x56,0x33,0xe9}, {0x19,0x5b,0x38,0xe7}, {0x02,0x4c,0x25,0xf5}, {0x0b,0x41,0x2e,0xfb}, {0xd7,0x61,0x8c,0x9a}, {0xde,0x6c,0x87,0x94}, {0xc5,0x7b,0x9a,0x86}, {0xcc,0x76,0x91,0x88}, {0xf3,0x55,0xa0,0xa2}, {0xfa,0x58,0xab,0xac}, {0xe1,0x4f,0xb6,0xbe}, {0xe8,0x42,0xbd,0xb0}, {0x9f,0x09,0xd4,0xea}, {0x96,0x04,0xdf,0xe4}, {0x8d,0x13,0xc2,0xf6}, {0x84,0x1e,0xc9,0xf8}, {0xbb,0x3d,0xf8,0xd2}, {0xb2,0x30,0xf3,0xdc}, {0xa9,0x27,0xee,0xce}, {0xa0,0x2a,0xe5,0xc0}, {0x47,0xb1,0x3c,0x7a}, {0x4e,0xbc,0x37,0x74}, {0x55,0xab,0x2a,0x66}, {0x5c,0xa6,0x21,0x68}, {0x63,0x85,0x10,0x42}, {0x6a,0x88,0x1b,0x4c}, {0x71,0x9f,0x06,0x5e}, {0x78,0x92,0x0d,0x50}, {0x0f,0xd9,0x64,0x0a}, {0x06,0xd4,0x6f,0x04}, {0x1d,0xc3,0x72,0x16}, {0x14,0xce,0x79,0x18}, {0x2b,0xed,0x48,0x32}, {0x22,0xe0,0x43,0x3c}, {0x39,0xf7,0x5e,0x2e}, {0x30,0xfa,0x55,0x20}, {0x9a,0xb7,0x01,0xec}, {0x93,0xba,0x0a,0xe2}, {0x88,0xad,0x17,0xf0}, {0x81,0xa0,0x1c,0xfe}, {0xbe,0x83,0x2d,0xd4}, {0xb7,0x8e,0x26,0xda}, {0xac,0x99,0x3b,0xc8}, {0xa5,0x94,0x30,0xc6}, {0xd2,0xdf,0x59,0x9c}, {0xdb,0xd2,0x52,0x92}, {0xc0,0xc5,0x4f,0x80}, {0xc9,0xc8,0x44,0x8e}, {0xf6,0xeb,0x75,0xa4}, {0xff,0xe6,0x7e,0xaa}, {0xe4,0xf1,0x63,0xb8}, {0xed,0xfc,0x68,0xb6}, {0x0a,0x67,0xb1,0x0c}, {0x03,0x6a,0xba,0x02}, {0x18,0x7d,0xa7,0x10}, {0x11,0x70,0xac,0x1e}, {0x2e,0x53,0x9d,0x34}, {0x27,0x5e,0x96,0x3a}, {0x3c,0x49,0x8b,0x28}, {0x35,0x44,0x80,0x26}, {0x42,0x0f,0xe9,0x7c}, {0x4b,0x02,0xe2,0x72}, {0x50,0x15,0xff,0x60}, {0x59,0x18,0xf4,0x6e}, {0x66,0x3b,0xc5,0x44}, {0x6f,0x36,0xce,0x4a}, {0x74,0x21,0xd3,0x58}, {0x7d,0x2c,0xd8,0x56}, {0xa1,0x0c,0x7a,0x37}, {0xa8,0x01,0x71,0x39}, {0xb3,0x16,0x6c,0x2b}, {0xba,0x1b,0x67,0x25}, {0x85,0x38,0x56,0x0f}, {0x8c,0x35,0x5d,0x01}, {0x97,0x22,0x40,0x13}, {0x9e,0x2f,0x4b,0x1d}, {0xe9,0x64,0x22,0x47}, {0xe0,0x69,0x29,0x49}, {0xfb,0x7e,0x34,0x5b}, {0xf2,0x73,0x3f,0x55}, {0xcd,0x50,0x0e,0x7f}, {0xc4,0x5d,0x05,0x71}, {0xdf,0x4a,0x18,0x63}, {0xd6,0x47,0x13,0x6d}, {0x31,0xdc,0xca,0xd7}, {0x38,0xd1,0xc1,0xd9}, {0x23,0xc6,0xdc,0xcb}, {0x2a,0xcb,0xd7,0xc5}, {0x15,0xe8,0xe6,0xef}, {0x1c,0xe5,0xed,0xe1}, {0x07,0xf2,0xf0,0xf3}, {0x0e,0xff,0xfb,0xfd}, {0x79,0xb4,0x92,0xa7}, {0x70,0xb9,0x99,0xa9}, {0x6b,0xae,0x84,0xbb}, {0x62,0xa3,0x8f,0xb5}, {0x5d,0x80,0xbe,0x9f}, {0x54,0x8d,0xb5,0x91}, {0x4f,0x9a,0xa8,0x83}, {0x46,0x97,0xa3,0x8d} }; word32 rcon[30] = { 0x01,0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91 }; uclmmbase-1.2.16.0/src/btree.c0000644000175000017500000002345507045607077014744 0ustar enderender/* * FILE: btree.c * PROGRAM: RAT * AUTHOR: O.Hodson * MODIFIED: C.Perkins * * Binary tree implementation - Mostly verbatim from: * * Introduction to Algorithms by Corman, Leisserson, and Rivest, * MIT Press / McGraw Hill, 1990. * */ #include "config_unix.h" #include "config_win32.h" #include "debug.h" #include "memory.h" #include "btree.h" typedef struct s_btree_node { uint32_t key; void *data; struct s_btree_node *parent; struct s_btree_node *left; struct s_btree_node *right; uint32_t magic; } btree_node_t; struct s_btree { btree_node_t *root; uint32_t magic; int count; }; /*****************************************************************************/ /* Debugging functions... */ /*****************************************************************************/ #define BTREE_MAGIC 0x10101010 #define BTREE_NODE_MAGIC 0x01010101 static int btree_count; static void btree_validate_node(btree_node_t *node, btree_node_t *parent) { assert(node->magic == BTREE_NODE_MAGIC); assert(node->parent == parent); btree_count++; if (node->left != NULL) { btree_validate_node(node->left, node); } if (node->right != NULL) { btree_validate_node(node->right, node); } } static void btree_validate(btree_t *t) { assert(t->magic == BTREE_MAGIC); #ifdef DEBUG btree_count = 0; if (t->root != NULL) { btree_validate_node(t->root, NULL); } assert(btree_count == t->count); #endif } /*****************************************************************************/ /* Utility functions */ /*****************************************************************************/ static btree_node_t* btree_min(btree_node_t *x) { if (x == NULL) { return NULL; } while(x->left) { x = x->left; } return x; } static btree_node_t* btree_max(btree_node_t *x) { if (x == NULL) { return NULL; } while(x->right) { x = x->right; } return x; } static btree_node_t* btree_successor(btree_node_t *x) { btree_node_t *y; if (x->right != NULL) { return btree_min(x->right); } y = x->parent; while (y != NULL && x == y->right) { x = y; y = y->parent; } return y; } static btree_node_t* btree_search(btree_node_t *x, uint32_t key) { while (x != NULL && key != x->key) { if (key < x->key) { x = x->left; } else { x = x->right; } } return x; } static void btree_insert_node(btree_t *tree, btree_node_t *z) { btree_node_t *x, *y; btree_validate(tree); y = NULL; x = tree->root; while (x != NULL) { y = x; assert(z->key != x->key); if (z->key < x->key) { x = x->left; } else { x = x->right; } } z->parent = y; if (y == NULL) { tree->root = z; } else if (z->key < y->key) { y->left = z; } else { y->right = z; } tree->count++; btree_validate(tree); } static btree_node_t* btree_delete_node(btree_t *tree, btree_node_t *z) { btree_node_t *x, *y; btree_validate(tree); if (z->left == NULL || z->right == NULL) { y = z; } else { y = btree_successor(z); } if (y->left != NULL) { x = y->left; } else { x = y->right; } if (x != NULL) { x->parent = y->parent; } if (y->parent == NULL) { tree->root = x; } else if (y == y->parent->left) { y->parent->left = x; } else { y->parent->right = x; } z->key = y->key; z->data = y->data; tree->count--; btree_validate(tree); return y; } /*****************************************************************************/ /* Exported functions */ /*****************************************************************************/ int btree_create(btree_t **tree) { btree_t *t = (btree_t*)xmalloc(sizeof(btree_t)); if (t) { t->count = 0; t->magic = BTREE_MAGIC; t->root = NULL; *tree = t; return TRUE; } return FALSE; } int btree_destroy(btree_t **tree) { btree_t *t = *tree; btree_validate(t); if (t->root != NULL) { debug_msg("Tree not empty - cannot destroy\n"); return FALSE; } xfree(t); *tree = NULL; return TRUE; } int btree_find(btree_t *tree, uint32_t key, void **d) { btree_node_t *x; btree_validate(tree); x = btree_search(tree->root, key); if (x != NULL) { *d = x->data; return TRUE; } return FALSE; } int btree_add(btree_t *tree, uint32_t key, void *data) { btree_node_t *x; btree_validate(tree); x = btree_search(tree->root, key); if (x != NULL) { debug_msg("Item already exists - key %ul\n", key); return FALSE; } x = (btree_node_t *)xmalloc(sizeof(btree_node_t)); x->key = key; x->data = data; x->parent = NULL; x->left = NULL; x->right = NULL; x->magic = BTREE_NODE_MAGIC; btree_insert_node(tree, x); return TRUE; } int btree_remove(btree_t *tree, uint32_t key, void **data) { btree_node_t *x; btree_validate(tree); x = btree_search(tree->root, key); if (x == NULL) { debug_msg("Item not on tree - key %ul\n", key); *data = NULL; return FALSE; } /* Note value that gets freed is not necessarily the the same * as node that gets removed from tree since there is an * optimization to avoid pointer updates in tree which means * sometimes we just copy key and data from one node to * another. */ *data = x->data; x = btree_delete_node(tree, x); xfree(x); return TRUE; } int btree_get_min_key(btree_t *tree, uint32_t *key) { btree_node_t *x; btree_validate(tree); if (tree->root == NULL) { return FALSE; } x = btree_min(tree->root); if (x == NULL) { return FALSE; } *key = x->key; return TRUE; } int btree_get_max_key(btree_t *tree, uint32_t *key) { btree_node_t *x; btree_validate(tree); if (tree->root == NULL) { return FALSE; } x = btree_max(tree->root); if (x == NULL) { return FALSE; } *key = x->key; return TRUE; } int btree_get_next_key(btree_t *tree, uint32_t cur_key, uint32_t *next_key) { btree_node_t *x; btree_validate(tree); x = btree_search(tree->root, cur_key); if (x == NULL) { return FALSE; } x = btree_successor(x); if (x == NULL) { return FALSE; } *next_key = x->key; return TRUE; } /*****************************************************************************/ /* Test code */ /*****************************************************************************/ #ifdef TEST_BTREE static int btree_depth(btree_node_t *x) { int l, r; if (x == NULL) { return 0; } l = btree_depth(x->left); r = btree_depth(x->right); if (l > r) { return l + 1; } else { return r + 1; } } #include static void btree_dump_node(btree_node_t *x, int depth, int c, int w) { if (x == NULL) { return; } move(depth * 2, c); printw("%lu", x->key); refresh(); btree_dump_node(x->left, depth + 1, c - w/2, w/2); btree_dump_node(x->right, depth + 1, c + w/2, w/2); return; } static void btree_dump(btree_t *b) { initscr(); btree_dump_node(b->root, 0, 40, 48); refresh(); endwin(); } #include "stdlib.h" int main() { btree_t *b; uint32_t i, *x; uint32_t v[] = {15, 5, 16, 3, 12, 20, 10, 13, 18, 23, 6, 7}; uint32_t nv = sizeof(v) / sizeof(v[0]); btree_create(&b); for(i = 0; i < nv; i++) { x = (uint32_t*)xmalloc(sizeof(uint32_t)); *x = (uint32_t)random(); if (btree_add(b, v[i], (void*)x) != TRUE) { printf("Fail Add %lu %lu\n", v[i], *x); } } printf("depth %d\n", btree_depth(b->root)); btree_dump(b); sleep(3); btree_remove(b, 5, (void*)&x); btree_dump(b); sleep(3); btree_remove(b, 16, (void*)&x); btree_dump(b); sleep(3); btree_remove(b, 13, (void*)&x); btree_dump(b); while (btree_get_root_key(b, &i)) { if (btree_remove(b, i, (void*)&x) == FALSE) { fprintf(stderr, "Failed to remove %lu\n", i); } btree_dump(b); sleep(1); } if (btree_destroy(&b) == FALSE) { printf("Failed to destroy \n"); } return 0; } #endif /* TEST_BTREE*/ uclmmbase-1.2.16.0/src/btree.h0000644000175000017500000000427407017014421014727 0ustar enderender/* * FILE: btree.h * PROGRAM: RAT * AUTHOR: O.Hodson * * Binary tree implementation - Mostly verbatim from: * * Introduction to Algorithms by Corman, Leisserson, and Rivest, * MIT Press / McGraw Hill, 1990. * * Implementation assumes one data element per key is assigned. * * Thanks to Markus Geimeier for pointing out want * btree_get_min_key and not btree_get_root_key for start point for tree * iteration. * */ #ifndef __BTREE_H__ #define __BTREE_H__ typedef struct s_btree btree_t; /* btree_create fills the *tree with a new binary tree. Returns TRUE on */ /* success and FALSE on failure. */ int btree_create (btree_t **tree); /* btree_destroy destroys tree. If tree is not empty it cannot be destroyed */ /* and call returns FALSE. On success returns TRUE. */ int btree_destroy (btree_t **tree); /* btree_add adds data for key to tree. Returns TRUE on success, or FALSE */ /* if key is already on tree. */ int btree_add (btree_t *tree, uint32_t key, void *data); /* btree_remove attempts to remove data from tree. Returns TRUE on success */ /* and points *d at value stored for key. FALSE is returned if key is not */ /* on tree. */ int btree_remove (btree_t *tree, uint32_t key, void **d); /* btree_find locates data for key and make *d point to it. Returns TRUE if */ /* data for key is found, FALSE otherwise. */ int btree_find (btree_t *tree, uint32_t key, void **d); /* btree_get_min_key attempts to return minimum key of tree. Function */ /* intended to help if list of keys is not stored elsewhere. Returns TRUE */ /* and fills key with key if possible, FALSE otherwise */ int btree_get_min_key (btree_t *tree, uint32_t *key); int btree_get_max_key (btree_t *tree, uint32_t *key); /* btree_get_next_key attempts to get the key above cur_key. Returns */ /* TRUE and fills key with key if possible, FALSE otherwise. */ int btree_get_next_key (btree_t *tree, uint32_t cur_key, uint32_t *next_key); #endif /* __BTREE_H__ */ uclmmbase-1.2.16.0/src/cdecl_ext.h0000644000175000017500000000340307057740732015570 0ustar enderender/* * Copyright (C) 1999 WIDE Project. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ #ifndef HAVE_PORTABLE_PROTOTYPE #if defined(__STDC__) || defined(__cplusplus) #define __P(protos) protos /* full-blown ANSI C */ #else #define __P(protos) () /* traditional C preprocessor */ #endif #endif /* !HAVE_PORTABLE_PROTOTYPE */ uclmmbase-1.2.16.0/src/common.dsp0000644000175000017500000004206207734574677015510 0ustar enderender# Microsoft Developer Studio Project File - Name="common" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Static Library" 0x0104 CFG=common - Win32 Release IPv6 XP !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "common.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "common.mak" CFG="common - Win32 Release IPv6 XP" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "common - Win32 Release" (based on "Win32 (x86) Static Library") !MESSAGE "common - Win32 Debug IPv6 Musica" (based on "Win32 (x86) Static Library") !MESSAGE "common - Win32 Debug" (based on "Win32 (x86) Static Library") !MESSAGE "common - Win32 Debug IPv6 Win2000" (based on "Win32 (x86) Static Library") !MESSAGE "common - Win32 Debug IPv6 MSR" (based on "Win32 (x86) Static Library") !MESSAGE "common - Win32 Release IPv6 Win2000" (based on "Win32 (x86) Static Library") !MESSAGE "common - Win32 Release IPv6 XP" (based on "Win32 (x86) Static Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "common - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c # ADD CPP /nologo /W3 /GX /O2 /I "..\tcl-8.0\generic" /I "..\tk-8.0\generic" /I "..\tk-8.0\xlib" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "HAVE_INET_NTOP" /YX /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo /out:"Release\uclmm.lib" !ELSEIF "$(CFG)" == "common - Win32 Debug IPv6 Musica" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "common___Win32_Debug_IPv6_Musica" # PROP BASE Intermediate_Dir "common___Win32_Debug_IPv6_Musica" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug_IPv6_Musica" # PROP Intermediate_Dir "Debug_IPv6_Musica" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /I "\src\tcl-8.0\generic" /I "\src\tk-8.0\generic" /I "\src\tk-8.0\xlib" /I "\DDK\inc" /I "\src\MSR_IPv6_1.3\inc" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "DEBUG" /D "DEBUG_MEM" /D "HAVE_IPv6" /D "BUILD_tcl" /D "BUILD_tk" /FR /YX /FD /GZ /c # ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\tcl-8.0\generic" /I "..\tk-8.0\generic" /I "..\tk-8.0\xlib" /I "..\MUSICA\WINSOCK6" /D "_MBCS" /D "_LIB" /D "DEBUG_MEM" /D "BUILD_tcl" /D "BUILD_tk" /D "DEBUG" /D "WIN32" /D "_DEBUG" /D "HAVE_IPv6" /D "MUSICA_IPV6" /D "_WINNT" /D "_POSIX" /D "NEED_ADDRINFO_H" /D "NEED_IN_EXPERIMENTAL" /D "NEED_IN6_IS_ADDR_V4MAPPED" /FR /YX /FD /GZ /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo /out:"Debug\uclmm.lib" # ADD LIB32 /nologo /out:"Debug_IPv6\uclmm.lib" !ELSEIF "$(CFG)" == "common - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c # ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\tcl-8.0\generic" /I "..\tk-8.0\generic" /I "..\tk-8.0\xlib" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "DEBUG" /D "DEBUG_MEM" /FR /YX /FD /GZ /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo /out:"Debug\uclmm.lib" !ELSEIF "$(CFG)" == "common - Win32 Debug IPv6 Win2000" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "common___Win32_Debug_IPv6_Win2000" # PROP BASE Intermediate_Dir "common___Win32_Debug_IPv6_Win2000" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug_IPv6_Win2000" # PROP Intermediate_Dir "Debug_IPv6_Win2000" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /I "\src\tcl-8.0\generic" /I "\src\tk-8.0\generic" /I "\src\tk-8.0\xlib" /I "\DDK\inc" /I "\src\IPv6Kit\inc" /I "..\tcl-8.0\generic" /I "..\tk-8.0\generic" /I "..\tk-8.0\xlib" /I "..\ipv6kit\inc" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "DEBUG" /D "DEBUG_MEM" /D "HAVE_IPv6" /D "BUILD_tcl" /D "BUILD_tk" /D "NEED_IN6_IS_ADDR_MULTICAST" /D "HAVE_INET_PTON" /D "HAVE_INET_NTOP" /FR /YX /FD /GZ /GZ /c # ADD CPP /nologo /ML /W3 /GX /O2 /I "\src\tcl-8.0\generic" /I "\src\tk-8.0\generic" /I "\src\tk-8.0\xlib" /I "\DDK\inc" /I "\src\IPv6Kit\inc" /I "..\tcl-8.0\generic" /I "..\tk-8.0\generic" /I "..\tk-8.0\xlib" /I "..\ipv6kit\inc" /D "WIN2K_IPV6" /D "WIN32" /D "_NDEBUG" /D "_MBCS" /D "_LIB" /D "NDEBUG" /D "HAVE_IPv6" /D "BUILD_tcl" /D "BUILD_tk" /D "NEED_IN6_IS_ADDR_MULTICAST" /D "NEED_INET_PTON" /D "NEED_INET_NTOP" /YX /FD /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo /out:"Debug_IPv6\uclmm.lib" # ADD LIB32 /nologo /out:"Debug_IPv6\uclmm.lib" !ELSEIF "$(CFG)" == "common - Win32 Debug IPv6 MSR" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "common___Win32_Debug_IPv6_MSR" # PROP BASE Intermediate_Dir "common___Win32_Debug_IPv6_MSR" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug_IPv6_MSR" # PROP Intermediate_Dir "Debug_IPv6_MSR" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /I "\src\tcl-8.0\generic" /I "\src\tk-8.0\generic" /I "\src\tk-8.0\xlib" /I "\DDK\inc" /I "\src\IPv6Kit\inc" /I "..\tcl-8.0\generic" /I "..\tk-8.0\generic" /I "..\tk-8.0\xlib" /I "..\ipv6kit\inc" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "DEBUG" /D "DEBUG_MEM" /D "HAVE_IPv6" /D "BUILD_tcl" /D "BUILD_tk" /D "NEED_IN6_IS_ADDR_MULTICAST" /D "HAVE_INET_PTON" /D "HAVE_INET_NTOP" /FR /YX /FD /GZ /GZ /c # ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "\src\tcl-8.0\generic" /I "\src\tk-8.0\generic" /I "\src\tk-8.0\xlib" /I "\DDK\inc" /I "\src\IPv6Kit\inc" /I "..\tcl-8.0\generic" /I "..\tk-8.0\generic" /I "..\tk-8.0\xlib" /I "d:\ipv6kit\inc" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "DEBUG" /D "DEBUG_MEM" /D "HAVE_IPv6" /D "BUILD_tcl" /D "BUILD_tk" /D "NEED_IN6_IS_ADDR_MULTICAST" /D "HAVE_INET_PTON" /D "HAVE_INET_NTOP" /FR /YX /FD /GZ /GZ /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo /out:"Debug_IPv6\uclmm.lib" # ADD LIB32 /nologo /out:"Debug_IPv6\uclmm.lib" !ELSEIF "$(CFG)" == "common - Win32 Release IPv6 Win2000" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "common___Win32_Release_IPv6_Win2000" # PROP BASE Intermediate_Dir "common___Win32_Release_IPv6_Win2000" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Release_IPv6_Win2000" # PROP Intermediate_Dir "Release_IPv6_Win2000" # PROP Target_Dir "" # ADD BASE CPP /nologo /ML /W3 /GX /O2 /I "\src\tcl-8.0\generic" /I "\src\tk-8.0\generic" /I "\src\tk-8.0\xlib" /I "\DDK\inc" /I "\src\IPv6Kit\inc" /I "..\tcl-8.0\generic" /I "..\tk-8.0\generic" /I "..\tk-8.0\xlib" /I "..\ipv6kit\inc" /D "WIN2K_IPV6" /D "WIN32" /D "_NDEBUG" /D "_MBCS" /D "_LIB" /D "NDEBUG" /D "HAVE_IPv6" /D "BUILD_tcl" /D "BUILD_tk" /D "NEED_IN6_IS_ADDR_MULTICAST" /D "NEED_INET_PTON" /D "NEED_INET_NTOP" /YX /FD /c # ADD CPP /nologo /ML /W3 /GX /O2 /I "\src\tcl-8.0\generic" /I "\src\tk-8.0\generic" /I "\src\tk-8.0\xlib" /I "\DDK\inc" /I "\src\IPv6Kit\inc" /I "..\tcl-8.0\generic" /I "..\tk-8.0\generic" /I "..\tk-8.0\xlib" /I "..\ipv6kit\inc" /D "WIN2K_IPV6" /D "WIN32" /D "_NDEBUG" /D "_MBCS" /D "_LIB" /D "NDEBUG" /D "HAVE_IPv6" /D "BUILD_tcl" /D "BUILD_tk" /D "NEED_IN6_IS_ADDR_MULTICAST" /D "NEED_INET_PTON" /D "NEED_INET_NTOP" /YX /FD /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo /out:"Debug_IPv6\uclmm.lib" # ADD LIB32 /nologo /out:"Release_IPv6\uclmm.lib" !ELSEIF "$(CFG)" == "common - Win32 Release IPv6 XP" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "common___Win32_Release_IPv6_XP" # PROP BASE Intermediate_Dir "common___Win32_Release_IPv6_XP" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Release_IPv6_XP" # PROP Intermediate_Dir "Release_IPv6_XP" # PROP Target_Dir "" # ADD BASE CPP /nologo /ML /W3 /GX /O2 /I "\src\tcl-8.0\generic" /I "\src\tk-8.0\generic" /I "\src\tk-8.0\xlib" /I "\DDK\inc" /I "\src\IPv6Kit\inc" /I "..\tcl-8.0\generic" /I "..\tk-8.0\generic" /I "..\tk-8.0\xlib" /I "..\ipv6kit\inc" /D "WIN2K_IPV6" /D "WIN32" /D "_NDEBUG" /D "_MBCS" /D "_LIB" /D "NDEBUG" /D "HAVE_IPv6" /D "BUILD_tcl" /D "BUILD_tk" /D "NEED_IN6_IS_ADDR_MULTICAST" /D "NEED_INET_PTON" /D "NEED_INET_NTOP" /YX /FD /c # ADD CPP /nologo /ML /W3 /GX /O2 /I "\src\tcl-8.0\generic" /I "\src\tk-8.0\generic" /I "\src\tk-8.0\xlib" /I "..\tcl-8.0\generic" /I "..\tk-8.0\generic" /I "..\tk-8.0\xlib" /I "\Program Files\Microsoft SDK\include" /D "WINXP_IPV6" /D "WIN32" /D "_NDEBUG" /D "_MBCS" /D "_LIB" /D "NDEBUG" /D "HAVE_IPv6" /D "BUILD_tcl" /D "BUILD_tk" /D "NEED_IN6_IS_ADDR_MULTICAST" /D "NEED_INET_PTON" /D "NEED_INET_NTOP" /YX /FD /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo /out:"Release_IPv6\uclmm.lib" # ADD LIB32 /nologo /out:"Release_IPv6\uclmm.lib" !ENDIF # Begin Target # Name "common - Win32 Release" # Name "common - Win32 Debug IPv6 Musica" # Name "common - Win32 Debug" # Name "common - Win32 Debug IPv6 Win2000" # Name "common - Win32 Debug IPv6 MSR" # Name "common - Win32 Release IPv6 Win2000" # Name "common - Win32 Release IPv6 XP" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=.\asarray.c # End Source File # Begin Source File SOURCE=.\base64.c # End Source File # Begin Source File SOURCE=.\btree.c # End Source File # Begin Source File SOURCE=.\crypt_random.c # End Source File # Begin Source File SOURCE=.\debug.c # End Source File # Begin Source File SOURCE=.\drand48.c # End Source File # Begin Source File SOURCE=.\getaddrinfo.c !IF "$(CFG)" == "common - Win32 Release" # PROP Exclude_From_Build 1 !ELSEIF "$(CFG)" == "common - Win32 Debug IPv6 Musica" # ADD CPP /D "INET6" /D "HAVE_GETHOSTBYNAME2" !ELSEIF "$(CFG)" == "common - Win32 Debug" # PROP Exclude_From_Build 1 !ELSEIF "$(CFG)" == "common - Win32 Debug IPv6 Win2000" # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 !ELSEIF "$(CFG)" == "common - Win32 Debug IPv6 MSR" # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 !ELSEIF "$(CFG)" == "common - Win32 Release IPv6 Win2000" # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 !ELSEIF "$(CFG)" == "common - Win32 Release IPv6 XP" # PROP BASE Exclude_From_Build 1 # PROP Exclude_From_Build 1 !ENDIF # End Source File # Begin Source File SOURCE=.\gettimeofday.c !IF "$(CFG)" == "common - Win32 Release" !ELSEIF "$(CFG)" == "common - Win32 Debug IPv6 Musica" # ADD CPP /W4 !ELSEIF "$(CFG)" == "common - Win32 Debug" !ELSEIF "$(CFG)" == "common - Win32 Debug IPv6 Win2000" !ELSEIF "$(CFG)" == "common - Win32 Debug IPv6 MSR" !ELSEIF "$(CFG)" == "common - Win32 Release IPv6 Win2000" !ELSEIF "$(CFG)" == "common - Win32 Release IPv6 XP" !ENDIF # End Source File # Begin Source File SOURCE=.\hmac.c # End Source File # Begin Source File SOURCE=.\inet_ntop.c # End Source File # Begin Source File SOURCE=.\inet_pton.c # End Source File # Begin Source File SOURCE=.\mbus.c # End Source File # Begin Source File SOURCE=.\mbus_addr.c # End Source File # Begin Source File SOURCE=.\mbus_config.c # End Source File # Begin Source File SOURCE=.\mbus_parser.c # End Source File # Begin Source File SOURCE=.\md5.c # End Source File # Begin Source File SOURCE=.\memory.c # End Source File # Begin Source File SOURCE=.\net_udp.c # End Source File # Begin Source File SOURCE=.\ntp.c # End Source File # Begin Source File SOURCE=.\qfDES.c # End Source File # Begin Source File SOURCE=".\rijndael-alg-fst.c" # End Source File # Begin Source File SOURCE=".\rijndael-api-fst.c" # End Source File # Begin Source File SOURCE=.\rtp.c # End Source File # Begin Source File SOURCE=.\sap.c # End Source File # Begin Source File SOURCE=.\sdp.c # End Source File # Begin Source File SOURCE=.\util.c # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File SOURCE=.\base64.h # End Source File # Begin Source File SOURCE=.\btree.h # End Source File # Begin Source File SOURCE=.\config_unix.h # End Source File # Begin Source File SOURCE=.\config_win32.h # End Source File # Begin Source File SOURCE=.\crypt_random.h # End Source File # Begin Source File SOURCE=.\debug.h # End Source File # Begin Source File SOURCE=.\drand48.h # End Source File # Begin Source File SOURCE=.\gettimeofday.h # End Source File # Begin Source File SOURCE=.\hmac.h # End Source File # Begin Source File SOURCE=.\inet_ntop.h # End Source File # Begin Source File SOURCE=.\inet_pton.h # End Source File # Begin Source File SOURCE=.\mbus.h # End Source File # Begin Source File SOURCE=.\mbus_addr.h # End Source File # Begin Source File SOURCE=.\mbus_config.h # End Source File # Begin Source File SOURCE=.\mbus_parser.h # End Source File # Begin Source File SOURCE=.\md5.h # End Source File # Begin Source File SOURCE=.\memory.h # End Source File # Begin Source File SOURCE=.\net_udp.h # End Source File # Begin Source File SOURCE=.\ntp.h # End Source File # Begin Source File SOURCE=.\qfDES.h # End Source File # Begin Source File SOURCE=.\rtp.h # End Source File # Begin Source File SOURCE=.\sap.h # End Source File # Begin Source File SOURCE=.\sdp.h # End Source File # Begin Source File SOURCE=.\util.h # End Source File # Begin Source File SOURCE=.\version.h # End Source File # End Group # Begin Source File SOURCE=..\VERSION !IF "$(CFG)" == "common - Win32 Release" !ELSEIF "$(CFG)" == "common - Win32 Debug IPv6 Musica" !ELSEIF "$(CFG)" == "common - Win32 Debug" # Begin Custom Build InputPath=..\VERSION "version.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy win32\set.txt + ..\VERSION win32\vergen.bat copy win32\vergen.bat + win32\null.txt win32\vergen.bat copy win32\vergen.bat + win32\echo.txt win32\vergen.bat win32\vergen.bat move win32\version.h version.h erase win32\version.h erase win32\vergen.bat # End Custom Build !ELSEIF "$(CFG)" == "common - Win32 Debug IPv6 Win2000" # Begin Custom Build InputPath=..\VERSION "version.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy win32\set.txt + ..\VERSION win32\vergen.bat copy win32\vergen.bat + win32\null.txt win32\vergen.bat copy win32\vergen.bat + win32\echo.txt win32\vergen.bat win32\vergen.bat move win32\version.h version.h erase win32\version.h erase win32\vergen.bat # End Custom Build !ELSEIF "$(CFG)" == "common - Win32 Debug IPv6 MSR" # Begin Custom Build InputPath=..\VERSION "version.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy win32\set.txt + ..\VERSION win32\vergen.bat copy win32\vergen.bat + win32\null.txt win32\vergen.bat copy win32\vergen.bat + win32\echo.txt win32\vergen.bat win32\vergen.bat move win32\version.h version.h erase win32\version.h erase win32\vergen.bat # End Custom Build !ELSEIF "$(CFG)" == "common - Win32 Release IPv6 Win2000" # Begin Custom Build InputPath=..\VERSION "version.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy win32\set.txt + ..\VERSION win32\vergen.bat copy win32\vergen.bat + win32\null.txt win32\vergen.bat copy win32\vergen.bat + win32\echo.txt win32\vergen.bat win32\vergen.bat move win32\version.h version.h erase win32\version.h erase win32\vergen.bat # End Custom Build !ELSEIF "$(CFG)" == "common - Win32 Release IPv6 XP" # Begin Custom Build InputPath=..\VERSION "version.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" copy win32\set.txt + ..\VERSION win32\vergen.bat copy win32\vergen.bat + win32\null.txt win32\vergen.bat copy win32\vergen.bat + win32\echo.txt win32\vergen.bat win32\vergen.bat move win32\version.h version.h erase win32\version.h erase win32\vergen.bat # End Custom Build !ENDIF # End Source File # End Target # End Project uclmmbase-1.2.16.0/src/config.h.in0000644000175000017500000000430707642543245015514 0ustar enderender/* src/config.h.in. Generated automatically from ../configure.in by autoheader. */ /* Define if type char is unsigned and you are not using gcc. */ #ifndef __CHAR_UNSIGNED__ #undef __CHAR_UNSIGNED__ #endif /* Define to empty if the keyword does not work. */ #undef const /* Define if you have that is POSIX.1 compatible. */ #undef HAVE_SYS_WAIT_H /* Define to `unsigned' if doesn't define. */ #undef size_t /* Define if you have the ANSI C header files. */ #undef STDC_HEADERS /* Define if you can safely include both and . */ #undef TIME_WITH_SYS_TIME /* Define if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel and VAX). */ #undef WORDS_BIGENDIAN /* * Define this if you have a /dev/urandom which can supply good random numbers. */ #undef HAVE_DEV_URANDOM /* * Define this if you want IPv6 support. */ #undef HAVE_IPv6 /* * V6 structures that host may or may not be present. */ #undef HAVE_ST_ADDRINFO #undef HAVE_GETIPNODEBYNAME #undef HAVE_SIN6_LEN /* * Define these if your C library is missing some functions... */ #undef NEED_VSNPRINTF #undef NEED_INET_PTON #undef NEED_INET_NTOP /* * If you don't have these types in , #define these to be * the types you do have. */ #undef int8_t #undef int16_t #undef int32_t #undef int64_t #undef uint8_t #undef uint16_t #undef uint32_t /* * Debugging: * DEBUG: general debugging * DEBUG_MEM: debug memory allocation */ #undef DEBUG #undef DEBUG_MEM /* Define if you have the vsnprintf function. */ #undef HAVE_VSNPRINTF /* Define if you have the header file. */ #undef HAVE_INTTYPES_H /* Define if you have the header file. */ #undef HAVE_NETINET6_IN6_H /* Define if you have the header file. */ #undef HAVE_STDINT_H /* Define if you have the header file. */ #undef HAVE_STROPTS_H /* Define if you have the header file. */ #undef HAVE_SYS_FILIO_H /* Define if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define if struct msghdr contains msg_control */ #undef HAVE_MSGHDR_MSGCTRL #ifndef WORDS_BIGENDIAN #define WORDS_SMALLENDIAN #endif uclmmbase-1.2.16.0/src/config_unix.h0000640000175000017500000001146507452155710016144 0ustar enderender/* * config-unix.h * * Unix specific definitions and includes * * $Revision: 1.24 $ * $Date: 2002/04/01 22:14:32 $ * * Copyright (c) 1995-2000 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Science * Department at University College London * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ #ifndef WIN32 #ifndef _CONFIG_UNIX_H #define _CONFIG_UNIX_H #include "uclconf.h" #include #include #if TIME_WITH_SYS_TIME #include #include #else #if HAVE_SYS_TIME_H #include #else #include #endif #endif #include #include #include #include #include #include #include #include #include #include /* abs() */ #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef __APPLE__ #define NEED_DRAND48 #define srand48 srand #define lrand48 rand() * rand #endif #ifdef HAVE_SYS_WAIT_H #include #endif #ifndef WEXITSTATUS #define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) #endif #ifndef WIFEXITED #define WIFEXITED(stat_val) (((stat_val) & 255) == 0) #endif #ifdef HAVE_STDINT_H #include #endif #ifdef HAVE_INTTYPES_H #include #endif #ifdef HAVE_STROPTS_H #include #endif /* HAVE_STROPTS_H */ #ifdef HAVE_SYS_FILIO_H #include #endif /* HAVE_SYS_FILIO_H */ #ifdef HAVE_IPv6 #ifdef HAVE_NETINET6_IN6_H /* Expect IPV6_{JOIN,LEAVE}_GROUP in in6.h, otherwise expect */ /* IPV_{ADD,DROP}_MEMBERSHIP in in.h */ #include #else #include #endif /* HAVE_NETINET_IN6_H */ #ifndef IPV6_ADD_MEMBERSHIP #ifdef IPV6_JOIN_GROUP #define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP #else #error No definition of IPV6_ADD_MEMBERSHIP, please report to mm-tools@cs.ucl.ac.uk. #endif /* IPV6_JOIN_GROUP */ #endif /* IPV6_ADD_MEMBERSHIP */ #ifndef IPV6_DROP_MEMBERSHIP #ifdef IPV6_LEAVE_GROUP #define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP #else #error No definition of IPV6_LEAVE_GROUP, please report to mm-tools@cs.ucl.ac.uk. #endif /* IPV6_LEAVE_GROUP */ #endif /* IPV6_DROP_MEMBERSHIP */ #endif /* HAVE_IPv6 */ #include typedef u_char ttl_t; typedef int fd_t; #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE 1 #endif /* TRUE */ #define USERNAMELEN 8 #ifndef max #define max(a, b) (((a) > (b))? (a): (b)) #endif #ifndef min #define min(a, b) (((a) < (b))? (a): (b)) #endif #ifdef NDEBUG #define assert(x) if ((x) == 0) fprintf(stderr, "%s:%u: failed assertion\n", __FILE__, __LINE__) #else #include #endif #ifdef Solaris #ifdef __cplusplus extern "C" { #endif int gettimeofday(struct timeval *tp, void * ); int gethostname(char *name, int namelen); #ifdef __cplusplus } #endif #endif #ifndef EXIT_SUCCESS #define EXIT_SUCCESS 0 #endif /* EXIT_SUCCESS */ #ifndef EXIT_FAILURE #define EXIT_FAILURE 7 #endif /* EXIT_FAILURE */ #endif /* _CONFIG_UNIX_H_ */ #endif /* WIN32 */ uclmmbase-1.2.16.0/src/config_win32.h0000640000175000017500000001240107734574677016136 0ustar enderender/* * config-win32.h * * Windows specific definitions and includes. * * $Revision: 1.24 $ * $Date: 2003/09/25 14:20:47 $ * * Copyright (c) 1995-2000 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Science * Department at University College London * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ #ifdef WIN32 #ifndef _CONFIG_WIN32_H #define _CONFIG_WIN32_H #include #include #include #include #include #include #include /* abs() */ #include #include #include #include #ifdef HAVE_IPv6 #ifdef MUSICA_IPV6 #include #else #ifdef WINXP_IPV6 #include #else #ifdef WIN2K_IPV6 #include #include #else #include #include #endif #endif #endif #endif #ifndef MUSICA_IPV6 #include #endif #include #include #include #include #include #include #include #include #include typedef int ttl_t; typedef unsigned int fd_t; /* * the definitions below are valid for 32-bit architectures and will have to * be adjusted for 16- or 64-bit architectures */ typedef unsigned __int8 uint8_t; typedef unsigned __int16 uint16_t; typedef unsigned __int32 uint32_t; typedef unsigned __int64 uint64_t; typedef __int8 int8_t; typedef __int16 int16_t; typedef __int32 int32_t; typedef __int64 int64_t; typedef unsigned long in_addr_t; #ifndef TRUE #define FALSE 0 #define TRUE 1 #endif /* TRUE */ #define USERNAMELEN 8 #define WORDS_SMALLENDIAN #define NEED_INET_ATON #define NEED_DRAND48 #define NEED_GETTIMEOFDAY #ifdef NDEBUG #define assert(x) if ((x) == 0) fprintf(stderr, "%s:%u: failed assertion\n", __FILE__, __LINE__) #else #include #endif #include /* For clock_t */ #define inline #define __inline #define AUDIO_MICROPHONE 1 #define AUDIO_LINE_IN 2 #define AUDIO_CD 4 #define AUDIO_SPEAKER 0 #define AUDIO_HEADPHONE 1 #define AUDIO_LINE_OUT 4 #define srand48 srand #define lrand48 rand() * rand #define snprintf _snprintf #define IN_CLASSD(i) (((long)(i) & 0xf0000000) == 0xe0000000) #define IN_MULTICAST(i) IN_CLASSD(i) typedef char *caddr_t; typedef int ssize_t; typedef struct iovec { caddr_t iov_base; ssize_t iov_len; } iovec_t; struct msghdr { caddr_t msg_name; int msg_namelen; struct iovec *msg_iov; int msg_iovlen; caddr_t msg_accrights; int msg_accrightslen; }; #ifndef MAXHOSTNAMELEN #define MAXHOSTNAMELEN 256 #endif #define _SYS_NMLN 9 struct utsname { char sysname[_SYS_NMLN]; char nodename[_SYS_NMLN]; char release[_SYS_NMLN]; char version[_SYS_NMLN]; char machine[_SYS_NMLN]; }; struct timezone { int tz_minuteswest; int tz_dsttime; }; typedef int pid_t; typedef int uid_t; typedef int gid_t; #if defined(__cplusplus) extern "C" { #endif int uname(struct utsname *); int getopt(int, char * const *, const char *); int srandom(int); int random(void); int gethostid(void); int getuid(void); int getgid(void); #define getpid _getpid int nice(int); int usleep(unsigned int); const char * w32_make_version_info(char * rat_verion); #define strcasecmp _stricmp #define strncasecmp _strnicmp int RegGetValue(HKEY *, char *, char*, char*, int); void ShowMessage(int level, char *msg); #define bcopy(from,to,len) memcpy(to,from,len) #if defined(__cplusplus) } #endif #define ECONNREFUSED WSAECONNREFUSED #define ENETUNREACH WSAENETUNREACH #define EHOSTUNREACH WSAEHOSTUNREACH #define EWOULDBLOCK WSAEWOULDBLOCK #ifndef EAFNOSUPPORT #define EAFNOSUPPORT WSAEAFNOSUPPORT #endif #define M_PI 3.14159265358979323846 #endif #endif uclmmbase-1.2.16.0/src/crypt_random.c0000640000175000017500000000543707020211004016306 0ustar enderender/* * Copyright (c) 1993 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Systems * Engineering Group at Lawrence Berkeley Laboratory. * 4. Neither the name of the University nor of the Laboratory may be used * to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ /* * LBL random number generator. * * Written by Steve McCanne & Chris Torek (mccanne@ee.lbl.gov, * torek@ee.lbl.gov), November, 1992. * * This implementation is based on ``Two Fast Implementations of * the "Minimal Standard" Random Number Generator", David G. Carta, * Communications of the ACM, Jan 1990, Vol 33 No 1. */ #include "config_win32.h" #include "config_unix.h" #include "crypt_random.h" static uint32_t randseed = 1; void lbl_srandom(uint32_t seed) { randseed = seed; } uint32_t lbl_random(void) { #ifdef HAVE_DEV_URANDOM int fd, res, l; fd = open("/dev/urandom", O_RDONLY); if (fd == -1) { perror("Cannot open random sequence generator"); abort(); } l = read(fd, &res, sizeof(res)); if (l != sizeof(res)) { perror("Cannot read random data"); abort(); } close(fd); return res; #else register uint32_t x = randseed; register uint32_t hi, lo, t; hi = x / 127773; lo = x % 127773; t = 16807 * lo - 2836 * hi; if (t <= 0) t += 0x7fffffff; randseed = t; return (t); #endif } uclmmbase-1.2.16.0/src/crypt_random.h0000640000175000017500000000425307017014424016323 0ustar enderender/* * Copyright (c) 1993 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Systems * Engineering Group at Lawrence Berkeley Laboratory. * 4. Neither the name of the University nor of the Laboratory may be used * to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ /* * LBL random number generator. * * Written by Steve McCanne & Chris Torek (mccanne@ee.lbl.gov, * torek@ee.lbl.gov), November, 1992. * * This implementation is based on ``Two Fast Implementations of * the "Minimal Standard" Random Number Generator", David G. Carta, * Communications of the ACM, Jan 1990, Vol 33 No 1. */ void lbl_srandom(uint32_t seed); uint32_t lbl_random(void); uclmmbase-1.2.16.0/src/debug.c0000640000175000017500000001421407261724505014712 0ustar enderender/* * FILE: debug.c * PROGRAM: RAT * AUTHORS: Isidor Kouvelas * Colin Perkins * Mark Handley * Orion Hodson * Jerry Isdale * * $Revision: 1.11 $ * $Date: 2001/04/01 22:18:45 $ * * Copyright (c) 1995-2000 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Science * Department at University College London * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ #include "config_unix.h" #include "config_win32.h" #include "debug.h" void _dprintf(const char *format, ...) { #ifdef DEBUG #ifdef WIN32 char msg[65535]; va_list ap; va_start(ap, format); _vsnprintf(msg, 65535, format, ap); va_end(ap); OutputDebugString(msg); #else va_list ap; va_start(ap, format); vfprintf(stderr, format, ap); va_end(ap); #endif /* WIN32 */ #else UNUSED (format); #endif /* DEBUG */ } /** * debug_dump: * @lp: pointer to memory region. * @len: length of memory region in bytes. * * Writes a dump of a memory region to stdout. The dump contains a * hexadecimal and an ascii representation of the memory region. * **/ void debug_dump(void*lp, long len) { char * p; long i, j, start; char Buff[80]; char stuffBuff[10]; char tmpBuf[10]; _dprintf("Dump of %ld=%lx bytes\n",len, len); start = 0L; while (start < len) { /* start line with pointer position key */ p = (char*)lp + start; sprintf(Buff,"%p: ",p); /* display each character as hex value */ for (i=start, j=0; j < 16; p++,i++, j++) { if (i < len) { sprintf(tmpBuf,"%X",((int)(*p) & 0xFF)); if (strlen((char *)tmpBuf) < 2) { stuffBuff[0] = '0'; stuffBuff[1] = tmpBuf[0]; stuffBuff[2] = ' '; stuffBuff[3] = '\0'; } else { stuffBuff[0] = tmpBuf[0]; stuffBuff[1] = tmpBuf[1]; stuffBuff[2] = ' '; stuffBuff[3] = '\0'; } strcat(Buff, stuffBuff); } else strcat(Buff," "); if (j == 7) /* space between groups of 8 */ strcat(Buff," "); } /* fill out incomplete lines */ for(;j<16;j++) { strcat(Buff," "); if (j == 7) strcat(Buff," "); } strcat(Buff," "); /* display each character as character value */ for (i=start,j=0,p=(char*)lp+start; (i < len && j < 16); p++,i++, j++) { if ( ((*p) >= ' ') && ((*p) <= '~') ) /* test displayable */ sprintf(tmpBuf,"%c", *p); else sprintf(tmpBuf,"%c", '.'); strcat(Buff,tmpBuf); if (j == 7) /* space between groups of 8 */ strcat(Buff," "); } _dprintf("%s\n", Buff); start = i; /* next line starting byte */ } } /** * debug_set_core_dir: * @argv0: the application path (usually argv[0] in main()). * * Creates a directory with the application name and makes it the * current working directory. * * This function exists because some unix variants use the name 'core' * for core dump files. When an application uses multiple processes, * this can be problematic if the failure of one process leads to the * failure of another because the dependent process 'core' file will * overwrite the core of the failing process. **/ void debug_set_core_dir(const char *argv0) { #if defined(DEBUG) && !defined(WIN32) struct stat s; char coredir[64]; const char *appname; appname = strrchr(argv0, '/'); if (appname == NULL) { appname = argv0; } else { appname = appname + 1; } /* Should check length of appname, but this is debug code */ /* and developers should know better than to have 64 char */ /* app name. */ sprintf(coredir, "core-%s", appname); mkdir(coredir, S_IRWXU); if (stat(coredir, &s) != 0) { debug_msg("Could not stat %s\n", coredir); return; } if (!S_ISDIR(s.st_mode)) { debug_msg("Not a directory: %s\n", coredir); return; } if (!(s.st_mode & S_IWUSR) || !(s.st_mode & S_IXUSR)) { debug_msg("Cannot write in or change to %s\n", coredir); return; } if (chdir(coredir)) { perror(coredir); } #endif /* DEBUG */ UNUSED(argv0); } uclmmbase-1.2.16.0/src/debug.h0000640000175000017500000000444607337017734014730 0ustar enderender/* * FILE: debug.h * PROGRAM: RAT * AUTHOR: Isidor Kouvelas + Colin Perkins + Mark Handley + Orion Hodson * * $Revision: 1.10 $ * $Date: 2001/08/16 19:32:44 $ * * Copyright (c) 1995-2000 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Science * Department at University College London * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ #ifndef _RAT_DEBUG_H #define _RAT_DEBUG_H #define UNUSED(x) (x=x) #define debug_msg _dprintf("[pid/%d +%d %s] ", getpid(), __LINE__, __FILE__), _dprintf #if defined(__cplusplus) extern "C" { #endif void _dprintf(const char *format, ...); void debug_dump(void*lp, long len); void debug_set_core_dir(const char *argv0); #if defined(__cplusplus) } #endif #endif uclmmbase-1.2.16.0/src/drand48.c0000644000175000017500000000033306757224356015101 0ustar enderender#include "config_unix.h" #include "config_win32.h" #include "drand48.h" #ifdef NEED_DRAND48 double drand48(void) { unsigned int x = (rand() << 16) | rand(); return ((double)x / (double)0xffffffff); } #endif uclmmbase-1.2.16.0/src/drand48.h0000644000175000017500000000006206757226562015106 0ustar enderender #ifdef NEED_DRAND48 double drand48(void); #endif uclmmbase-1.2.16.0/src/getaddrinfo.c0000644000175000017500000006174507060714010016114 0ustar enderender/* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ /* * "#ifdef FAITH" part is local hack for supporting IPv4-v6 translator. * * Issues to be discussed: * - Thread safe-ness must be checked. * - Return values. There are nonstandard return values defined and used * in the source code. This is because RFC2553 is silent about which error * code must be returned for which situation. * Note: * - We use getipnodebyname() just for thread-safeness. There's no intent * to let it do PF_UNSPEC (actually we never pass PF_UNSPEC to * getipnodebyname(). * - The code filters out AFs that are not supported by the kernel, * when globbing NULL hostname (to loopback, or wildcard). Is it the right * thing to do? What is the relationship with post-RFC2553 AI_ADDRCONFIG * in ai_flags? */ #ifndef lint static const char rcsid[] = "@(#) $Header: /cs/research/mice/starship/src/local/CVS_repository/common/src/getaddrinfo.c,v 1.2 2000/03/06 11:35:36 ucaccsp Exp $"; #endif #include "config_unix.h" #include "config_win32.h" #include "debug.h" #include "memory.h" #include "inet_pton.h" #include "inet_ntop.h" #include #ifndef HAVE_PORTABLE_PROTOTYPE #include "cdecl_ext.h" #endif #ifndef HAVE_SOCKADDR_STORAGE #include "sockstorage.h" #endif #ifdef NEED_ADDRINFO_H #include "addrinfo.h" #endif #ifdef NEED_IN6_IS_ADDR_V4MAPPED #define IN6_IS_ADDR_V4MAPPED(a) (((a)->s6_addr32[0] == 0) && \ ((a)->s6_addr32[1] == 0) && \ ((a)->s6_addr32[2] == htonl(0xffff0000)) && \ ((a)->s6_addr32[3] != 0)) #endif #ifdef NEED_IN_EXPERIMENTAL #define IN_EXPERIMENTAL(i) (((i) & 0xe0000000U) == 0xe0000000U) #endif #ifndef IN_LOOPBACKNET #define IN_LOOPBACKNET 127 /* official! */ #endif #if defined(__KAME__) && defined(INET6) # define FAITH #endif #define SUCCESS 0 #define ANY 0 #define YES 1 #define NO 0 #ifdef FAITH static int translate = NO; static struct in6_addr faith_prefix = IN6ADDR_ANY_INIT; #endif static const char in_addrany[] = { 0, 0, 0, 0 }; static const char in6_addrany[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; static const char in_loopback[] = { 127, 0, 0, 1 }; static const char in6_loopback[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; struct sockinet { u_char si_len; u_char si_family; u_short si_port; uint32_t si_scope_id; }; static const struct afd { int a_af; int a_addrlen; int a_socklen; int a_off; const char *a_addrany; const char *a_loopback; int a_scoped; } afdl [] = { #ifdef INET6 {PF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6), offsetof(struct sockaddr_in6, sin6_addr), in6_addrany, in6_loopback, 1}, #endif {PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in), offsetof(struct sockaddr_in, sin_addr), in_addrany, in_loopback, 0}, {0, 0, 0, 0, NULL, NULL, 0}, }; struct explore { int e_af; int e_socktype; int e_protocol; const char *e_protostr; int e_wild; #define WILD_AF(ex) ((ex)->e_wild & 0x01) #define WILD_SOCKTYPE(ex) ((ex)->e_wild & 0x02) #define WILD_PROTOCOL(ex) ((ex)->e_wild & 0x04) }; static const struct explore explore[] = { #if 0 { PF_LOCAL, 0, ANY, ANY, NULL, 0x01 }, #endif #ifdef INET6 { PF_INET6, SOCK_DGRAM, IPPROTO_IPV6, "udp", 0x07 }, { PF_INET6, SOCK_STREAM, IPPROTO_IPV6, "tcp", 0x07 }, { PF_INET6, SOCK_RAW, ANY, NULL, 0x05 }, #endif { PF_INET, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 }, { PF_INET, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 }, { PF_INET, SOCK_RAW, ANY, NULL, 0x05 }, { -1, 0, 0, NULL, 0 }, }; #ifdef INET6 #define PTON_MAX 16 #else #define PTON_MAX 4 #endif static int str_isnumber __P((const char *)); static int explore_fqdn __P((const struct addrinfo *, const char *, const char *, struct addrinfo **)); static int explore_null __P((const struct addrinfo *, const char *, const char *, struct addrinfo **)); static int explore_numeric __P((const struct addrinfo *, const char *, const char *, struct addrinfo **)); static int explore_numeric_scope __P((const struct addrinfo *, const char *, const char *, struct addrinfo **)); static int get_name __P((const char *, const struct afd *, struct addrinfo **, char *, const struct addrinfo *, const char *)); static int get_canonname __P((const struct addrinfo *, struct addrinfo *, const char *)); static struct addrinfo *get_ai __P((const struct addrinfo *, const struct afd *, const char *)); static int get_portmatch __P((const struct addrinfo *, const char *)); static int get_port __P((struct addrinfo *, const char *, int)); static const struct afd *find_afd __P((int)); static char *ai_errlist[] = { "Success", "Address family for hostname not supported", /* EAI_ADDRFAMILY */ "Temporary failure in name resolution", /* EAI_AGAIN */ "Invalid value for ai_flags", /* EAI_BADFLAGS */ "Non-recoverable failure in name resolution", /* EAI_FAIL */ "ai_family not supported", /* EAI_FAMILY */ "Memory allocation failure", /* EAI_MEMORY */ "No address associated with hostname", /* EAI_NODATA */ "hostname nor servname provided, or not known", /* EAI_NONAME */ "servname not supported for ai_socktype", /* EAI_SERVICE */ "ai_socktype not supported", /* EAI_SOCKTYPE */ "System error returned in errno", /* EAI_SYSTEM */ "Invalid value for hints", /* EAI_BADHINTS */ "Resolved protocol is unknown", /* EAI_PROTOCOL */ "Unknown error", /* EAI_MAX */ }; /* XXX macros that make external reference is BAD. */ #define GET_AI(ai, afd, addr) \ do { \ /* external reference: pai, error, and label free */ \ (ai) = get_ai(pai, (afd), (addr)); \ if ((ai) == NULL) { \ error = EAI_MEMORY; \ goto free; \ } \ } while (0) #define GET_PORT(ai, serv) \ do { \ /* external reference: error and label free */ \ error = get_port((ai), (serv), 0); \ if (error != 0) \ goto free; \ } while (0) #define GET_CANONNAME(ai, str) \ do { \ /* external reference: pai, error and label free */ \ error = get_canonname(pai, (ai), (str)); \ if (error != 0) \ goto free; \ } while (0) #define ERR(err) \ do { \ /* external reference: error, and label bad */ \ error = (err); \ goto bad; \ } while (0) #define MATCH_FAMILY(x, y, w) \ ((x) == (y) || ((w) && ((x) == PF_UNSPEC || (y) == PF_UNSPEC))) #define MATCH(x, y, w) \ ((x) == (y) || ((w) && ((x) == ANY || (y) == ANY))) char * gai_strerror(ecode) int ecode; { if (ecode < 0 || ecode > EAI_MAX) ecode = EAI_MAX; return ai_errlist[ecode]; } void freeaddrinfo(ai) struct addrinfo *ai; { struct addrinfo *next; do { next = ai->ai_next; if (ai->ai_canonname) free(ai->ai_canonname); /* no need to free(ai->ai_addr) */ free(ai); } while ((ai = next) != NULL); } static int str_isnumber(p) const char *p; { char *q = (char *)p; while (*q) { if (! isdigit(*q)) return NO; q++; } return YES; } int getaddrinfo(hostname, servname, hints, res) const char *hostname, *servname; const struct addrinfo *hints; struct addrinfo **res; { struct addrinfo sentinel; struct addrinfo *cur; int error = 0; struct addrinfo ai; struct addrinfo ai0; struct addrinfo *pai; const struct afd *afd; const struct explore *ex; #ifdef FAITH static int firsttime = 1; if (firsttime) { /* translator hack */ char *q = getenv("GAI"); if (q && inet_pton(AF_INET6, q, &faith_prefix) == 1) translate = YES; firsttime = 0; } #endif sentinel.ai_next = NULL; cur = &sentinel; pai = &ai; pai->ai_flags = 0; pai->ai_family = PF_UNSPEC; pai->ai_socktype = ANY; pai->ai_protocol = ANY; pai->ai_addrlen = 0; pai->ai_canonname = NULL; pai->ai_addr = NULL; pai->ai_next = NULL; if (hostname == NULL && servname == NULL) return EAI_NONAME; if (hints) { /* error check for hints */ if (hints->ai_addrlen || hints->ai_canonname || hints->ai_addr || hints->ai_next) ERR(EAI_BADHINTS); /* xxx */ if (hints->ai_flags & ~AI_MASK) ERR(EAI_BADFLAGS); switch (hints->ai_family) { case PF_UNSPEC: case PF_INET: #ifdef INET6 case PF_INET6: #endif break; default: ERR(EAI_FAMILY); } memcpy(pai, hints, sizeof(*pai)); /* * if both socktype/protocol are specified, check if they * are meaningful combination. */ if (pai->ai_socktype != ANY && pai->ai_protocol != ANY) { for (ex = explore; ex->e_af >= 0; ex++) { if (pai->ai_family != ex->e_af) continue; if (ex->e_socktype == ANY) continue; if (ex->e_protocol == ANY) continue; if (pai->ai_socktype == ex->e_socktype && pai->ai_protocol != ex->e_protocol) { ERR(EAI_BADHINTS); } } } } /* * check for special cases. (1) numeric servname is disallowed if * socktype/protocol are left unspecified. (2) servname is disallowed * for raw and other inet{,6} sockets. */ if (MATCH_FAMILY(pai->ai_family, PF_INET, 1) #ifdef PF_INET6 || MATCH_FAMILY(pai->ai_family, PF_INET6, 1) #endif ) { ai0 = *pai; if (pai->ai_family == PF_UNSPEC) { #ifdef PF_INET6 pai->ai_family = PF_INET6; #else pai->ai_family = PF_INET; #endif } error = get_portmatch(pai, servname); if (error) ERR(error); *pai = ai0; } ai0 = *pai; /* NULL hostname, or numeric hostname */ for (ex = explore; ex->e_af >= 0; ex++) { *pai = ai0; if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex))) continue; if (!MATCH(pai->ai_socktype, ex->e_socktype, WILD_SOCKTYPE(ex))) continue; if (!MATCH(pai->ai_protocol, ex->e_protocol, WILD_PROTOCOL(ex))) continue; if (pai->ai_family == PF_UNSPEC) pai->ai_family = ex->e_af; if (pai->ai_socktype == ANY && ex->e_socktype != ANY) pai->ai_socktype = ex->e_socktype; if (pai->ai_protocol == ANY && ex->e_protocol != ANY) pai->ai_protocol = ex->e_protocol; if (hostname == NULL) error = explore_null(pai, hostname, servname, &cur->ai_next); else error = explore_numeric_scope(pai, hostname, servname, &cur->ai_next); if (error) goto free; while (cur && cur->ai_next) cur = cur->ai_next; } /* * XXX * If numreic representation of AF1 can be interpreted as FQDN * representation of AF2, we need to think again about the code below. */ if (sentinel.ai_next) goto good; if (pai->ai_flags & AI_NUMERICHOST) ERR(EAI_NONAME); if (hostname == NULL) ERR(EAI_NONAME); /* * hostname as alphabetical name. * we would like to prefer AF_INET6 than AF_INET, so we'll make a * outer loop by AFs. */ for (afd = afdl; afd->a_af; afd++) { *pai = ai0; if (!MATCH_FAMILY(pai->ai_family, afd->a_af, 1)) continue; for (ex = explore; ex->e_af >= 0; ex++) { *pai = ai0; if (pai->ai_family == PF_UNSPEC) pai->ai_family = afd->a_af; if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex))) continue; if (!MATCH(pai->ai_socktype, ex->e_socktype, WILD_SOCKTYPE(ex))) { continue; } if (!MATCH(pai->ai_protocol, ex->e_protocol, WILD_PROTOCOL(ex))) { continue; } if (pai->ai_family == PF_UNSPEC) pai->ai_family = ex->e_af; if (pai->ai_socktype == ANY && ex->e_socktype != ANY) pai->ai_socktype = ex->e_socktype; if (pai->ai_protocol == ANY && ex->e_protocol != ANY) pai->ai_protocol = ex->e_protocol; error = explore_fqdn(pai, hostname, servname, &cur->ai_next); while (cur && cur->ai_next) cur = cur->ai_next; } } /* XXX */ if (sentinel.ai_next) error = 0; if (error) goto free; if (error == 0) { if (sentinel.ai_next) { good: *res = sentinel.ai_next; return SUCCESS; } else error = EAI_FAIL; } free: bad: if (sentinel.ai_next) freeaddrinfo(sentinel.ai_next); *res = NULL; return error; } /* * FQDN hostname, DNS lookup */ static int explore_fqdn(pai, hostname, servname, res) const struct addrinfo *pai; const char *hostname; const char *servname; struct addrinfo **res; { struct hostent *hp; int h_error; int af; char **aplist = NULL, *apbuf = NULL; char *ap; struct addrinfo sentinel, *cur; int i; #ifndef USE_GETIPNODEBY int naddrs; #endif const struct afd *afd; int error; *res = NULL; sentinel.ai_next = NULL; cur = &sentinel; /* * Do not filter unsupported AFs here. We need to honor content of * databases (/etc/hosts, DNS and others). Otherwise we cannot * replace gethostbyname() by getaddrinfo(). */ /* * if the servname does not match socktype/protocol, ignore it. */ if (get_portmatch(pai, servname) != 0) return 0; afd = find_afd(pai->ai_family); /* * post-RFC2553: should look at (pai->ai_flags & AI_ADDRCONFIG) * rather than hardcoding it. we may need to add AI_ADDRCONFIG * handling code by ourselves in case we don't have getipnodebyname(). */ #ifdef USE_GETIPNODEBY hp = getipnodebyname(hostname, pai->ai_family, AI_ADDRCONFIG, &h_error); #else #ifdef HAVE_GETHOSTBYNAME2 hp = gethostbyname2(hostname, pai->ai_family); #else if (pai->ai_family != AF_INET) return 0; hp = gethostbyname(hostname); #ifdef HAVE_H_ERRNO h_error = h_errno; #else h_error = EINVAL; #endif #endif /*HAVE_GETHOSTBYNAME2*/ #endif /*USE_GETIPNODEBY*/ if (hp == NULL) { switch (h_error) { case HOST_NOT_FOUND: case NO_DATA: error = EAI_NODATA; break; case TRY_AGAIN: error = EAI_AGAIN; break; case NO_RECOVERY: case NETDB_INTERNAL: default: error = EAI_FAIL; break; } } else if ((hp->h_name == NULL) || (hp->h_name[0] == 0) || (hp->h_addr_list[0] == NULL)) { #ifdef USE_GETIPNODEBY freehostent(hp); #endif hp = NULL; error = EAI_FAIL; } if (hp == NULL) goto free; #ifdef USE_GETIPNODEBY aplist = hp->h_addr_list; #else /* * hp will be overwritten if we use gethostbyname2(). * always deep copy for simplification. */ for (naddrs = 0; hp->h_addr_list[naddrs] != NULL; naddrs++) ; naddrs++; aplist = (char **)malloc(sizeof(aplist[0]) * naddrs); apbuf = (char *)malloc(hp->h_length * naddrs); if (aplist == NULL || apbuf == NULL) { error = EAI_MEMORY; goto free; } memset(aplist, 0, sizeof(aplist[0]) * naddrs); for (i = 0; i < naddrs; i++) { if (hp->h_addr_list[i] == NULL) { aplist[i] = NULL; continue; } memcpy(&apbuf[i * hp->h_length], hp->h_addr_list[i], hp->h_length); aplist[i] = &apbuf[i * hp->h_length]; } #endif for (i = 0; aplist[i] != NULL; i++) { af = hp->h_addrtype; ap = aplist[i]; #ifdef AF_INET6 if (af == AF_INET6 && IN6_IS_ADDR_V4MAPPED((struct in6_addr *)ap)) { af = AF_INET; ap = ap + sizeof(struct in6_addr) - sizeof(struct in_addr); } #endif if (af != pai->ai_family) continue; if ((pai->ai_flags & AI_CANONNAME) == 0) { GET_AI(cur->ai_next, afd, ap); GET_PORT(cur->ai_next, servname); } else { /* * if AI_CANONNAME and if reverse lookup * fail, return ai anyway to pacify * calling application. * * XXX getaddrinfo() is a name->address * translation function, and it looks * strange that we do addr->name * translation here. */ get_name(ap, afd, &cur->ai_next, ap, pai, servname); } while (cur && cur->ai_next) cur = cur->ai_next; } *res = sentinel.ai_next; return 0; free: #ifdef USE_GETIPNODEBY if (hp) freehostent(hp); #endif if (aplist) free(aplist); if (apbuf) free(apbuf); if (sentinel.ai_next) freeaddrinfo(sentinel.ai_next); return error; } /* * hostname == NULL. * passive socket -> anyaddr (0.0.0.0 or ::) * non-passive socket -> localhost (127.0.0.1 or ::1) */ static int explore_null(pai, hostname, servname, res) const struct addrinfo *pai; const char *hostname; const char *servname; struct addrinfo **res; { int s; const struct afd *afd; struct addrinfo *cur; struct addrinfo sentinel; int error; *res = NULL; sentinel.ai_next = NULL; cur = &sentinel; /* * filter out AFs that are not supported by the kernel * XXX errno? */ s = socket(pai->ai_family, SOCK_DGRAM, 0); if (s < 0) { if (errno != EMFILE) return 0; } else close(s); /* * if the servname does not match socktype/protocol, ignore it. */ if (get_portmatch(pai, servname) != 0) return 0; afd = find_afd(pai->ai_family); if (pai->ai_flags & AI_PASSIVE) { GET_AI(cur->ai_next, afd, afd->a_addrany); /* xxx meaningless? * GET_CANONNAME(cur->ai_next, "anyaddr"); */ GET_PORT(cur->ai_next, servname); } else { GET_AI(cur->ai_next, afd, afd->a_loopback); /* xxx meaningless? * GET_CANONNAME(cur->ai_next, "localhost"); */ GET_PORT(cur->ai_next, servname); } cur = cur->ai_next; *res = sentinel.ai_next; return 0; free: if (sentinel.ai_next) freeaddrinfo(sentinel.ai_next); return error; } /* * numeric hostname */ static int explore_numeric(pai, hostname, servname, res) const struct addrinfo *pai; const char *hostname; const char *servname; struct addrinfo **res; { const struct afd *afd; struct addrinfo *cur; struct addrinfo sentinel; int error; char pton[PTON_MAX]; int flags; *res = NULL; sentinel.ai_next = NULL; cur = &sentinel; /* * if the servname does not match socktype/protocol, ignore it. */ if (get_portmatch(pai, servname) != 0) return 0; afd = find_afd(pai->ai_family); flags = pai->ai_flags; if (inet_pton(afd->a_af, hostname, pton) == 1) { uint32_t v4a; #ifdef INET6 u_char pfx; #endif switch (afd->a_af) { case AF_INET: v4a = (uint32_t)ntohl(((struct in_addr *)pton)->s_addr); if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a)) flags &= ~AI_CANONNAME; v4a >>= IN_CLASSA_NSHIFT; if (v4a == 0 || v4a == IN_LOOPBACKNET) flags &= ~AI_CANONNAME; break; #ifdef INET6 case AF_INET6: pfx = ((struct in6_addr *)pton)->s6_addr[0]; if (pfx == 0 || pfx == 0xfe || pfx == 0xff) flags &= ~AI_CANONNAME; break; #endif } if (pai->ai_family == afd->a_af || pai->ai_family == PF_UNSPEC /*?*/) { if ((flags & AI_CANONNAME) == 0) { GET_AI(cur->ai_next, afd, pton); GET_PORT(cur->ai_next, servname); } else { /* * if AI_CANONNAME and if reverse lookup * fail, return ai anyway to pacify * calling application. * * XXX getaddrinfo() is a name->address * translation function, and it looks * strange that we do addr->name * translation here. */ get_name(pton, afd, &cur->ai_next, pton, pai, servname); } while (cur && cur->ai_next) cur = cur->ai_next; } else ERR(EAI_FAMILY); /*xxx*/ } *res = sentinel.ai_next; return 0; free: bad: if (sentinel.ai_next) freeaddrinfo(sentinel.ai_next); return error; } /* * numeric hostname with scope */ static int explore_numeric_scope(pai, hostname, servname, res) const struct addrinfo *pai; const char *hostname; const char *servname; struct addrinfo **res; { #ifndef SCOPE_DELIMITER return explore_numeric(pai, hostname, servname, res); #else const struct afd *afd; struct addrinfo *cur; int error; char *cp, *hostname2 = NULL; int scope; struct sockaddr_in6 *sin6; /* * if the servname does not match socktype/protocol, ignore it. */ if (get_portmatch(pai, servname) != 0) return 0; afd = find_afd(pai->ai_family); if (!afd->a_scoped) return explore_numeric(pai, hostname, servname, res); cp = strchr(hostname, SCOPE_DELIMITER); if (cp == NULL) return explore_numeric(pai, hostname, servname, res); /* * Handle special case of */ hostname2 = strdup(hostname); if (hostname2 == NULL) return EAI_MEMORY; /* terminate at the delimiter */ hostname2[cp - hostname] = '\0'; cp++; switch (pai->ai_family) { #ifdef INET6 case AF_INET6: scope = if_nametoindex(cp); if (scope == 0) { free(hostname2); return (EAI_NONAME); } break; #endif } error = explore_numeric(pai, hostname2, servname, res); if (error == 0) { for (cur = *res; cur; cur = cur->ai_next) { if (cur->ai_family != AF_INET6) continue; sin6 = (struct sockaddr_in6 *)cur->ai_addr; if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) || IN6_IS_ADDR_MC_LINKLOCAL(&sin6->sin6_addr)) sin6->sin6_scope_id = scope; } } free(hostname2); return error; #endif } static int get_name(addr, afd, res, numaddr, pai, servname) const char *addr; const struct afd *afd; struct addrinfo **res; char *numaddr; const struct addrinfo *pai; const char *servname; { struct hostent *hp = NULL; struct addrinfo *cur = NULL; int error = 0; char *ap = NULL, *cn = NULL; #ifdef USE_GETIPNODEBY int h_error; hp = getipnodebyaddr(addr, afd->a_addrlen, afd->a_af, &h_error); #else hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af); #endif if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) { #ifdef USE_GETIPNODEBY GET_AI(cur, afd, hp->h_addr_list[0]); GET_PORT(cur, servname); GET_CANONNAME(cur, hp->h_name); #else /* hp will be damaged if we use gethostbyaddr() */ if ((ap = (char *)malloc(hp->h_length)) == NULL) { error = EAI_MEMORY; goto free; } memcpy(ap, hp->h_addr_list[0], hp->h_length); if ((cn = strdup(hp->h_name)) == NULL) { error = EAI_MEMORY; goto free; } GET_AI(cur, afd, ap); GET_PORT(cur, servname); GET_CANONNAME(cur, cn); free(ap); ap = NULL; free(cn); cn = NULL; #endif } else { GET_AI(cur, afd, numaddr); GET_PORT(cur, servname); } #ifdef USE_GETIPNODEBY if (hp) freehostent(hp); #endif *res = cur; return SUCCESS; free: if (cur) freeaddrinfo(cur); if (ap) free(ap); if (cn) free(cn); #ifdef USE_GETIPNODEBY if (hp) freehostent(hp); #endif *res = NULL; return error; } static int get_canonname(pai, ai, str) const struct addrinfo *pai; struct addrinfo *ai; const char *str; { if ((pai->ai_flags & AI_CANONNAME) != 0) { ai->ai_canonname = (char *)malloc(strlen(str) + 1); if (ai->ai_canonname == NULL) return EAI_MEMORY; strcpy(ai->ai_canonname, str); } return 0; } static struct addrinfo * get_ai(pai, afd, addr) const struct addrinfo *pai; const struct afd *afd; const char *addr; { char *p; struct addrinfo *ai; ai = (struct addrinfo *)malloc(sizeof(struct addrinfo) + (afd->a_socklen)); if (ai == NULL) return NULL; memcpy(ai, pai, sizeof(struct addrinfo)); ai->ai_addr = (struct sockaddr *)(ai + 1); memset(ai->ai_addr, 0, afd->a_socklen); #ifdef HAVE_SOCKADDR_SA_LEN ai->ai_addr->sa_len = afd->a_socklen; #endif ai->ai_addrlen = afd->a_socklen; ai->ai_addr->sa_family = ai->ai_family = afd->a_af; p = (char *)(ai->ai_addr); memcpy(p + afd->a_off, addr, afd->a_addrlen); return ai; } static int get_portmatch(ai, servname) const struct addrinfo *ai; const char *servname; { /* get_port does not touch first argument. when matchonly == 1. */ return get_port((struct addrinfo *)ai, servname, 1); } static int get_port(ai, servname, matchonly) struct addrinfo *ai; const char *servname; int matchonly; { const char *proto; struct servent *sp; int port; int allownumeric; if (servname == NULL) return 0; switch (ai->ai_family) { case AF_INET: #ifdef AF_INET6 case AF_INET6: #endif break; default: return 0; } switch (ai->ai_socktype) { case SOCK_RAW: return EAI_SERVICE; case SOCK_DGRAM: case SOCK_STREAM: allownumeric = 1; break; case ANY: allownumeric = 0; break; default: return EAI_SOCKTYPE; } if (str_isnumber(servname)) { if (!allownumeric) return EAI_SERVICE; port = htons(atoi(servname)); if (port < 0 || port > 65535) return EAI_SERVICE; } else { switch (ai->ai_socktype) { case SOCK_DGRAM: proto = "udp"; break; case SOCK_STREAM: proto = "tcp"; break; default: proto = NULL; break; } if ((sp = getservbyname(servname, proto)) == NULL) return EAI_SERVICE; port = sp->s_port; } if (!matchonly) { switch (ai->ai_family) { case AF_INET: ((struct sockaddr_in *)ai->ai_addr)->sin_port = port; break; #ifdef INET6 case AF_INET6: ((struct sockaddr_in6 *)ai->ai_addr)->sin6_port = port; break; #endif } } return 0; } static const struct afd * find_afd(af) int af; { const struct afd *afd; if (af == PF_UNSPEC) return NULL; for (afd = afdl; afd->a_af; afd++) { if (afd->a_af == af) return afd; } return NULL; } uclmmbase-1.2.16.0/src/gettimeofday.c0000644000175000017500000000050706757231102016304 0ustar enderender#include "config_unix.h" #include "config_win32.h" #include "gettimeofday.h" #if defined(NEED_GETTIMEOFDAY) && defined(WIN32) int gettimeofday(struct timeval *tp, void *tz) { struct _timeb timebuffer; _ftime( &timebuffer ); tp->tv_sec = timebuffer.time; tp->tv_usec = timebuffer.millitm * 1000; return 0; } #endif uclmmbase-1.2.16.0/src/gettimeofday.h0000644000175000017500000000012107025166427016307 0ustar enderender#ifdef NEED_GETTIMEOFDAY int gettimeofday(struct timeval *tp, void *); #endif uclmmbase-1.2.16.0/src/hmac.c0000640000175000017500000001263707252665774014557 0ustar enderender/* * FILE: hmac.c * AUTHORS: Colin Perkins * * HMAC message authentication (RFC2104) * * Copyright (c) 1998-2000 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Science * Department at University College London * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ #include "config_unix.h" #include "config_win32.h" #include "md5.h" #include "hmac.h" /** * hmac_md5: * @data: pointer to data stream. * @data_len: length of data stream in bytes. * @key: pointer to authentication key. * @key_len: length of authentication key in bytes. * @digest: digest to be filled in. * * Computes MD5 @digest of @data using key @key. * **/ void hmac_md5(unsigned char *data, int data_len, unsigned char *key, int key_len, unsigned char digest[16]) { MD5_CTX context; unsigned char k_ipad[65]; /* inner padding - key XORd with ipad */ unsigned char k_opad[65]; /* outer padding - key XORd with opad */ unsigned char tk[16]; int i; /* If key is longer than 64 bytes reset it to key=MD5(key) */ if (key_len > 64) { MD5_CTX tctx; MD5Init(&tctx); MD5Update(&tctx, key, key_len); MD5Final(tk, &tctx); key = tk; key_len = 16; } /* * The HMAC_MD5 transform looks like: * * MD5(K XOR opad, MD5(K XOR ipad, data)) * * where K is an n byte key * ipad is the byte 0x36 repeated 64 times * opad is the byte 0x5c repeated 64 times * and text is the data being protected */ /* Start out by storing key in pads */ memset(k_ipad, 0, sizeof(k_ipad)); memset(k_opad, 0, sizeof(k_opad)); memcpy(k_ipad, key, key_len); memcpy(k_opad, key, key_len); /* XOR key with ipad and opad values */ for (i=0; i<64; i++) { k_ipad[i] ^= 0x36; k_opad[i] ^= 0x5c; } /* * perform inner MD5 */ MD5Init(&context); /* init context for 1st pass */ MD5Update(&context, k_ipad, 64); /* start with inner pad */ MD5Update(&context, data, data_len); /* then text of datagram */ MD5Final(digest, &context); /* finish up 1st pass */ /* * perform outer MD5 */ MD5Init(&context); /* init context for 2nd pass */ MD5Update(&context, k_opad, 64); /* start with outer pad */ MD5Update(&context, digest, 16); /* then results of 1st hash */ MD5Final(digest, &context); /* finish up 2nd pass */ } /* * Test Vectors (Trailing '\0' of a character string not included in test): * * key = 0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b * key_len = 16 bytes * data = "Hi There" * data_len = 8 bytes * digest = 0x9294727a3638bb1c13f48ef8158bfc9d * * key = "Jefe" * data = "what do ya want for nothing?" * data_len = 28 bytes * digest = 0x750c783e6ab0b503eaa86e310a5db738 * * key = 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA * key_len 16 bytes * data = 0xDDDDDDDDDDDDDDDDDDDD... * ..DDDDDDDDDDDDDDDDDDDD... * ..DDDDDDDDDDDDDDDDDDDD... * ..DDDDDDDDDDDDDDDDDDDD... * ..DDDDDDDDDDDDDDDDDDDD * data_len = 50 bytes * digest = 0x56be34521d144c88dbb8c733f0e8b3f6 */ #ifdef TEST_HMAC int main() { unsigned char *key = "Jefe"; unsigned char *data = "what do ya want for nothing?"; unsigned char digest[16]; int i; hmac_md5(data, 28, key, 4, digest); for (i = 0; i < 16; i++) { printf("%02x", digest[i]); } printf("\n"); return 0; } #endif uclmmbase-1.2.16.0/src/hmac.h0000640000175000017500000000376307034372535014550 0ustar enderender/* * FILE: hmac.h * AUTHORS: Colin Perkins * * HMAC message authentication (RFC2104) * * Copyright (c) 1998-2000 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Science * Department at University College London * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ void hmac_md5(unsigned char *data, int data_len, unsigned char *key, int key_len, unsigned char digest[16]); uclmmbase-1.2.16.0/src/inet_ntop.c0000640000175000017500000001161307021514503015610 0ustar enderender/* This is from the BIND 4.9.4 release, modified to compile by itself */ /* Copyright (c) 1996 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ #ifndef HAVE_INET_NTOP #include "config_unix.h" #include "config_win32.h" #include "inet_ntop.h" #define IN6ADDRSZ 16 #define INT16SZ 2 #ifndef AF_INET6 #define AF_INET6 AF_MAX+1 /* just to let this compile */ #endif /* * WARNING: Don't even consider trying to compile this on a system where * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. */ static const char *inet_ntop4(const u_char *src, char *dst, size_t size); static const char *inet_ntop6(const u_char *src, char *dst, size_t size); /* char * * inet_ntop(af, src, dst, size) * convert a network format address to presentation format. * return: * pointer to presentation format address (`dst'), or NULL (see errno). * author: * Paul Vixie, 1996. */ const char * inet_ntop(af, src, dst, size) int af; const void *src; char *dst; size_t size; { switch (af) { case AF_INET: return (inet_ntop4(src, dst, size)); case AF_INET6: return (inet_ntop6(src, dst, size)); default: errno = EAFNOSUPPORT; return (NULL); } /* NOTREACHED */ } /* const char * * inet_ntop4(src, dst, size) * format an IPv4 address, more or less like inet_ntoa() * return: * `dst' (as a const) * notes: * (1) uses no statics * (2) takes a u_char* not an in_addr as input * author: * Paul Vixie, 1996. */ static const char * inet_ntop4(src, dst, size) const u_char *src; char *dst; size_t size; { static const char fmt[] = "%u.%u.%u.%u"; char tmp[sizeof "255.255.255.255"]; sprintf(tmp, fmt, src[0], src[1], src[2], src[3]); if ((size_t)strlen(tmp) > size) { errno = ENOSPC; return (NULL); } strcpy(dst, tmp); return (dst); } /* const char * * inet_ntop6(src, dst, size) * convert IPv6 binary address into presentation (printable) format * author: * Paul Vixie, 1996. */ static const char * inet_ntop6(src, dst, size) const u_char *src; char *dst; size_t size; { /* * Note that int32_t and int16_t need only be "at least" large enough * to contain a value of the specified size. On some systems, like * Crays, there is no such thing as an integer variable with 16 bits. * Keep this in mind if you think this function should have been coded * to use pointer overlays. All the world's not a VAX. */ char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp; struct { int base, len; } best, cur; uint32_t words[IN6ADDRSZ / INT16SZ]; int i; /* * Preprocess: * Copy the input (bytewise) array into a wordwise array. * Find the longest run of 0x00's in src[] for :: shorthanding. */ memset(words, 0, sizeof words); for (i = 0; i < IN6ADDRSZ; i++) words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); best.base = -1; cur.base = -1; for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { if (words[i] == 0) { if (cur.base == -1) cur.base = i, cur.len = 1; else cur.len++; } else { if (cur.base != -1) { if (best.base == -1 || cur.len > best.len) best = cur; cur.base = -1; } } } if (cur.base != -1) { if (best.base == -1 || cur.len > best.len) best = cur; } if (best.base != -1 && best.len < 2) best.base = -1; /* * Format the result. */ tp = tmp; for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { /* Are we inside the best run of 0x00's? */ if (best.base != -1 && i >= best.base && i < (best.base + best.len)) { if (i == best.base) *tp++ = ':'; continue; } /* Are we following an initial run of 0x00s or any real hex? */ if (i != 0) *tp++ = ':'; /* Is this address an encapsulated IPv4? */ if (i == 6 && best.base == 0 && (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp))) return (NULL); tp += strlen(tp); break; } sprintf(tp, "%x", words[i]); tp += strlen(tp); } /* Was it a trailing run of 0x00's? */ if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) *tp++ = ':'; *tp++ = '\0'; /* * Check for overflow, copy, and we're done. */ if ((size_t) (tp - tmp) > size) { errno = ENOSPC; return (NULL); } strcpy(dst, tmp); return (dst); } #endif uclmmbase-1.2.16.0/src/inet_ntop.h0000640000175000017500000000031407041631647015624 0ustar enderender#ifndef HAVE_INET_NTOP #if defined(__cplusplus) extern "C" { #endif const char *inet_ntop(int af, const void *src, char *dst, size_t size); #if defined(__cplusplus) } #endif #endif /* HAVE_INET_NTOP */ uclmmbase-1.2.16.0/src/inet_pton.c0000640000175000017500000001220207777445071015630 0ustar enderender/* This is from the BIND 4.9.4 release, modified to compile by itself */ /* Copyright (c) 1996 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ #ifndef HAVE_INET_PTON #include "config_unix.h" #include "config_win32.h" #include "inet_pton.h" #define IN6ADDRSZ 16 #define INADDRSZ 4 #define INT16SZ 2 #ifndef AF_INET6 #define AF_INET6 AF_MAX+1 /* just to let this compile */ #endif /* * WARNING: Don't even consider trying to compile this on a system where * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. */ static int inet_pton4(const char *src, u_char *dst); static int inet_pton6(const char *src, u_char *dst); /* int * inet_pton(af, src, dst) * convert from presentation format (which usually means ASCII printable) * to network format (which is usually some kind of binary format). * return: * 1 if the address was valid for the specified address family * 0 if the address wasn't valid (`dst' is untouched in this case) * -1 if some other error occurred (`dst' is untouched in this case, too) * author: * Paul Vixie, 1996. */ int inet_pton(af, src, dst) int af; const char *src; void *dst; { switch (af) { case AF_INET: return (inet_pton4(src, dst)); case AF_INET6: return (inet_pton6(src, dst)); default: errno = EAFNOSUPPORT; return (-1); } /* NOTREACHED */ } /* int * inet_pton4(src, dst) * like inet_aton() but without all the hexadecimal and shorthand. * return: * 1 if `src' is a valid dotted quad, else 0. * notice: * does not touch `dst' unless it's returning 1. * author: * Paul Vixie, 1996. */ static int inet_pton4(src, dst) const char *src; u_char *dst; { static const char digits[] = "0123456789"; int saw_digit, octets, ch; u_char tmp[INADDRSZ], *tp; saw_digit = 0; octets = 0; *(tp = tmp) = 0; while ((ch = *src++) != '\0') { const char *pch; if ((pch = (char *) strchr(digits, ch)) != NULL) { uint32_t new = *tp * 10 + (pch - digits); if (new > 255) return (0); *tp = new; if (! saw_digit) { if (++octets > 4) return (0); saw_digit = 1; } } else if (ch == '.' && saw_digit) { if (octets == 4) return (0); *++tp = 0; saw_digit = 0; } else return (0); } if (octets < 4) return (0); /* bcopy(tmp, dst, INADDRSZ); */ memcpy(dst, tmp, INADDRSZ); return (1); } /* int * inet_pton6(src, dst) * convert presentation level address to network order binary form. * return: * 1 if `src' is a valid [RFC1884 2.2] address, else 0. * notice: * (1) does not touch `dst' unless it's returning 1. * (2) :: in a full address is silently ignored. * credit: * inspired by Mark Andrews. * author: * Paul Vixie, 1996. */ static int inet_pton6(src, dst) const char *src; u_char *dst; { static const char xdigits_l[] = "0123456789abcdef", xdigits_u[] = "0123456789ABCDEF"; u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp; const char *xdigits, *curtok; int ch, saw_xdigit; unsigned val; memset((tp = tmp), 0, IN6ADDRSZ); endp = tp + IN6ADDRSZ; colonp = NULL; /* Leading :: requires some special handling. */ if (*src == ':') if (*++src != ':') return (0); curtok = src; saw_xdigit = 0; val = 0; while ((ch = *src++) != '\0') { const char *pch; if ((pch = (char *) strchr((xdigits = xdigits_l), ch)) == NULL) pch = (char *) strchr((xdigits = xdigits_u), ch); if (pch != NULL) { val <<= 4; val |= (pch - xdigits); if (val > 0xffff) return (0); saw_xdigit = 1; continue; } if (ch == ':') { curtok = src; if (!saw_xdigit) { if (colonp) return (0); colonp = tp; continue; } if (tp + INT16SZ > endp) return (0); *tp++ = (u_char) (val >> 8) & 0xff; *tp++ = (u_char) val & 0xff; saw_xdigit = 0; val = 0; continue; } if (ch == '.' && ((tp + INADDRSZ) <= endp) && inet_pton4(curtok, tp) > 0) { tp += INADDRSZ; saw_xdigit = 0; break; /* '\0' was seen by inet_pton4(). */ } return (0); } if (saw_xdigit) { if (tp + INT16SZ > endp) return (0); *tp++ = (u_char) (val >> 8) & 0xff; *tp++ = (u_char) val & 0xff; } if (colonp != NULL) { /* * Since some memmove()'s erroneously fail to handle * overlapping regions, we'll do the shift by hand. */ const int n = tp - colonp; int i; for (i = 1; i <= n; i++) { endp[- i] = colonp[n - i]; colonp[n - i] = 0; } tp = endp; } if (tp != endp) return (0); /* bcopy(tmp, dst, IN6ADDRSZ); */ memcpy(dst, tmp, IN6ADDRSZ); return (1); } #endif uclmmbase-1.2.16.0/src/inet_pton.h0000640000175000017500000000027007174077456015636 0ustar enderender#ifndef HAVE_INET_PTON #if defined(__cplusplus) extern "C" { #endif int inet_pton(int af, const char *src, void *dst); #if defined(__cplusplus) } #endif #endif /* HAVE_INET_PTON */ uclmmbase-1.2.16.0/src/mbus.c0000640000175000017500000007575607673445567014633 0ustar enderender/* * FILE: mbus.c * AUTHOR: Colin Perkins * MODIFIED: Orion Hodson * Markus Germeier * * Copyright (c) 1997-2000 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Science * Department at University College London * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ #include "config_unix.h" #include "config_win32.h" #include "debug.h" #include "memory.h" #include "net_udp.h" #include "hmac.h" #include "qfDES.h" #include "base64.h" #include "gettimeofday.h" #include "vsnprintf.h" #include "mbus.h" #include "mbus_config.h" #include "mbus_parser.h" #include "mbus_addr.h" #include "asarray.h" #define MBUS_BUF_SIZE 1500 #define MBUS_ACK_BUF_SIZE 1500 #define MBUS_MAX_ADDR 10 #define MBUS_MAX_QLEN 50 /* Number of messages we can queue with mbus_qmsg() */ #define MBUS_MAGIC 0x87654321 #define MBUS_MSG_MAGIC 0x12345678 struct mbus_msg { struct mbus_msg *next; struct timeval send_time; /* Time the message was sent, to trigger a retransmit */ struct timeval comp_time; /* Time the message was composed, the timestamp in the packet header */ char *dest; int reliable; int complete; /* Indicates that we've finished adding cmds to this message */ int seqnum; int retransmit_count; int message_size; int num_cmds; char *cmd_list[MBUS_MAX_QLEN]; char *arg_list[MBUS_MAX_QLEN]; uint32_t idx_list[MBUS_MAX_QLEN]; uint32_t magic; /* For debugging... */ }; struct mbus { socket_udp *s; char *addr; /* Addresses we respond to. */ int max_other_addr; int num_other_addr; char **other_addr; /* Addresses of other entities on the mbus. */ struct timeval **other_hello; /* Time of last mbus.hello we received from other entities */ int seqnum; struct mbus_msg *cmd_queue; /* Queue of messages waiting to be sent */ struct mbus_msg *waiting_ack; /* The last reliable message sent, if we have not yet got the ACK */ char *hashkey; int hashkeylen; char *encrkey; int encrkeylen; struct timeval last_heartbeat; /* Last time we sent a heartbeat message */ struct mbus_config *cfg; void (*cmd_handler)(char *src, char *cmd, char *arg, void *dat); void (*err_handler)(int seqnum, int reason); uint32_t magic; /* For debugging... */ uint32_t index; uint32_t index_sent; }; /* For recording reliable message sequence numbers, so we can ignore duplicates */ static asarray *seq_numbers; static void mbus_validate(struct mbus *m) { #ifdef DEBUG int i; assert(m != 0); assert(m->num_other_addr <= m->max_other_addr); assert(m->num_other_addr >= 0); for (i = 0; i < m->num_other_addr; i++) { assert(m->other_addr[i] != NULL); assert(m->other_hello[i] != NULL); } for (i = m->num_other_addr + 1; i < m->max_other_addr; i++) { assert(m->other_addr[i] == NULL); assert(m->other_hello[i] == NULL); } #endif assert(m->magic == MBUS_MAGIC); xmemchk(); } static void mbus_msg_validate(struct mbus_msg *m) { #ifdef DEBUG int i; assert((m->num_cmds < MBUS_MAX_QLEN) && (m->num_cmds >= 0)); for (i = 0; i < m->num_cmds; i++) { assert(m->cmd_list[i] != NULL); assert(m->arg_list[i] != NULL); if (i > 0) { assert(m->idx_list[i] > m->idx_list[i-1]); } } for (i = m->num_cmds + 1; i < MBUS_MAX_QLEN; i++) { assert(m->cmd_list[i] == NULL); assert(m->arg_list[i] == NULL); } assert(m->dest != NULL); #endif assert(m->magic == MBUS_MSG_MAGIC); } static void store_other_addr(struct mbus *m, char *a) { /* This takes the address a and ensures it is stored in the */ /* m->other_addr field of the mbus structure. The other_addr */ /* field should probably be a hash table, but for now we hope */ /* that there are not too many entities on the mbus, so the */ /* list is small. */ int i; mbus_validate(m); for (i = 0; i < m->num_other_addr; i++) { if (mbus_addr_match(m->other_addr[i], a)) { /* Already in the list... */ gettimeofday(m->other_hello[i],NULL); return; } } if (m->num_other_addr == m->max_other_addr) { /* Expand the list... */ int old_other_addr = m->max_other_addr; m->max_other_addr *= 2; m->other_addr = (char **) xrealloc(m->other_addr, m->max_other_addr * sizeof(char *)); m->other_hello = (struct timeval **) xrealloc(m->other_hello, m->max_other_addr * sizeof(struct timeval *)); for (i = old_other_addr; i < m->max_other_addr; i++) { m->other_addr[i] = NULL; m->other_hello[i] = NULL; } } m->other_hello[m->num_other_addr]=(struct timeval *)xmalloc(sizeof(struct timeval)); gettimeofday(m->other_hello[m->num_other_addr],NULL); m->other_addr[m->num_other_addr++] = xstrdup(a); } static void remove_other_addr(struct mbus *m, char *a) { /* Removes the address a from the m->other_addr field of the */ /* mbus structure. */ int i, j; mbus_validate(m); for (i = 0; i < m->num_other_addr; i++) { if (mbus_addr_match(m->other_addr[i], a)) { xfree(m->other_addr[i]); xfree(m->other_hello[i]); for (j = i+1; j < m->num_other_addr; j++) { m->other_addr[j-1] = m->other_addr[j]; m->other_hello[j-1] = m->other_hello[j]; } m->other_addr[m->num_other_addr - 1] = NULL; m->other_hello[m->num_other_addr - 1] = NULL; m->num_other_addr--; } } } static void remove_inactiv_other_addr(struct mbus *m, struct timeval t, int interval){ /* Remove addresses we haven't heard from for about 5 * interval */ /* Count backwards so it is safe to remove entries */ int i; mbus_validate(m); for (i=m->num_other_addr-1; i>=0; i--){ if ((t.tv_sec-(m->other_hello[i]->tv_sec)) > 5 * interval) { debug_msg("remove dead entity (%s)\n", m->other_addr[i]); remove_other_addr(m, m->other_addr[i]); } } } int mbus_addr_valid(struct mbus *m, char *addr) { int i; mbus_validate(m); for (i = 0; i < m->num_other_addr; i++) { if (mbus_addr_match(m->other_addr[i], addr)) { return TRUE; } } return FALSE; } static int mbus_addr_unique(struct mbus *m, char *addr) { int i, n = 0; mbus_validate(m); for (i = 0; i < m->num_other_addr; i++) { if (mbus_addr_match(m->other_addr[i], addr)) { n++; } } return n==1; } /* The mb_* functions are used to build an mbus message up in the */ /* mb_buffer, and to add authentication and encryption before the */ /* message is sent. */ char mb_cryptbuf[MBUS_BUF_SIZE]; char *mb_buffer; char *mb_bufpos; #define MBUS_AUTH_LEN 16 static void mb_header(int seqnum, struct timeval ts, char reliable, const char *src, const char *dst, int ackseq) { xmemchk(); mb_buffer = (char *) xmalloc(MBUS_BUF_SIZE + 1); memset(mb_buffer, 0, MBUS_BUF_SIZE + 1); memset(mb_buffer, ' ', MBUS_AUTH_LEN); mb_bufpos = mb_buffer + MBUS_AUTH_LEN; /* monster kludge */ if(*dst == '(') sprintf(mb_bufpos, "\nmbus/1.0 %6d %ld%03ld %c (%s) %s ", seqnum, ts.tv_sec,ts.tv_usec/1000, reliable, src, dst); else sprintf(mb_bufpos, "\nmbus/1.0 %6d %ld%03ld %c (%s) (%s) ", seqnum, ts.tv_sec,ts.tv_usec/1000, reliable, src, dst); mb_bufpos += strlen(mb_bufpos); if (ackseq == -1) { sprintf(mb_bufpos, "()\n"); mb_bufpos += 3; } else { sprintf(mb_bufpos, "(%6d)\n", ackseq); mb_bufpos += 9; } } static void mb_add_command(const char *cmnd, const char *args) { int offset = strlen(cmnd) + strlen(args) + 5; assert((mb_bufpos + offset - mb_buffer) < MBUS_BUF_SIZE); sprintf(mb_bufpos, "%s (%s)\n", cmnd, args); mb_bufpos += offset - 1; /* The -1 in offset means we're not NUL terminated - fix in mb_send */ } static void mb_send(struct mbus *m) { char digest[16]; int len; unsigned char initVec[8] = {0,0,0,0,0,0,0,0}; mbus_validate(m); *mb_bufpos = '\0'; assert((mb_bufpos - mb_buffer) < MBUS_BUF_SIZE); assert(strlen(mb_buffer) < MBUS_BUF_SIZE); /* Pad to a multiple of 8 bytes, so the encryption can work... */ if (m->encrkey != NULL) { while (((mb_bufpos - mb_buffer - (MBUS_AUTH_LEN+1)) % 8) != 0) { *(mb_bufpos++) = '\0'; } } len = mb_bufpos - mb_buffer; assert(len < MBUS_BUF_SIZE); assert(strlen(mb_buffer) < MBUS_BUF_SIZE); xmemchk(); if (m->encrkey != NULL) { /* Encrypt... */ memset(mb_cryptbuf, 0, MBUS_BUF_SIZE); memcpy(mb_cryptbuf, mb_buffer + MBUS_AUTH_LEN + 1, len - (MBUS_AUTH_LEN+1)); assert(((len - (MBUS_AUTH_LEN+1)) % 8) == 0); assert(len < MBUS_BUF_SIZE); assert(m->encrkeylen == 8); xmemchk(); qfDES_CBC_e(m->encrkey, mb_cryptbuf, len - (MBUS_AUTH_LEN+1), initVec); xmemchk(); memcpy(mb_buffer + (MBUS_AUTH_LEN+1), mb_cryptbuf, len); } xmemchk(); if (m->hashkey != NULL) { /* Authenticate... */ hmac_md5(mb_buffer + MBUS_AUTH_LEN+1, len - (MBUS_AUTH_LEN+1), m->hashkey, m->hashkeylen, digest); base64encode(digest, 12, mb_buffer, MBUS_AUTH_LEN); } xmemchk(); udp_send(m->s, mb_buffer, len); xfree(mb_buffer); } static void resend(struct mbus *m, struct mbus_msg *curr) { /* Don't need to check for buffer overflows: this was done in mbus_send() when */ /* this message was first transmitted. If it was okay then, it's okay now. */ int i; mbus_validate(m); mb_header(curr->seqnum, curr->comp_time, (char)(curr->reliable?'R':'U'), m->addr, curr->dest, -1); for (i = 0; i < curr->num_cmds; i++) { mb_add_command(curr->cmd_list[i], curr->arg_list[i]); } mb_send(m); curr->retransmit_count++; } void mbus_retransmit(struct mbus *m) { struct mbus_msg *curr = m->waiting_ack; struct timeval time; long diff; mbus_validate(m); if (!mbus_waiting_ack(m)) { return; } mbus_msg_validate(curr); gettimeofday(&time, NULL); /* diff is time in milliseconds that the message has been awaiting an ACK */ diff = ((time.tv_sec * 1000) + (time.tv_usec / 1000)) - ((curr->send_time.tv_sec * 1000) + (curr->send_time.tv_usec / 1000)); if (diff > 10000) { debug_msg("Reliable mbus message failed!\n"); if (m->err_handler == NULL) { abort(); } m->err_handler(curr->seqnum, MBUS_MESSAGE_LOST); /* if we don't delete this failed message, the error handler gets triggered every time we call mbus_retransmit */ while (m->waiting_ack->num_cmds > 0) { m->waiting_ack->num_cmds--; xfree(m->waiting_ack->cmd_list[m->waiting_ack->num_cmds]); xfree(m->waiting_ack->arg_list[m->waiting_ack->num_cmds]); } xfree(m->waiting_ack->dest); xfree(m->waiting_ack); m->waiting_ack = NULL; return; } /* Note: We only send one retransmission each time, to avoid * overflowing the receiver with a burst of requests... */ if ((diff > 750) && (curr->retransmit_count == 2)) { resend(m, curr); return; } if ((diff > 500) && (curr->retransmit_count == 1)) { resend(m, curr); return; } if ((diff > 250) && (curr->retransmit_count == 0)) { resend(m, curr); return; } } void mbus_heartbeat(struct mbus *m, int interval) { struct timeval curr_time; char *a = (char *) xmalloc(3); sprintf(a, "()"); mbus_validate(m); gettimeofday(&curr_time, NULL); if (curr_time.tv_sec - m->last_heartbeat.tv_sec >= interval) { mb_header(++m->seqnum, curr_time, 'U', m->addr, "()", -1); mb_add_command("mbus.hello", ""); mb_send(m); m->last_heartbeat = curr_time; /* Remove dead sources */ remove_inactiv_other_addr(m, curr_time, interval); } xfree(a); } int mbus_waiting_ack(struct mbus *m) { mbus_validate(m); return m->waiting_ack != NULL; } int mbus_sent_all(struct mbus *m) { mbus_validate(m); return (m->cmd_queue == NULL) && (m->waiting_ack == NULL); } struct mbus *mbus_init(void (*cmd_handler)(char *src, char *cmd, char *arg, void *dat), void (*err_handler)(int seqnum, int reason), char *addr) { struct mbus *m; struct mbus_key k; struct mbus_parser *mp; int i; char *net_addr, *tmp; uint16_t net_port; int net_scope; asarray_create (&seq_numbers); m = (struct mbus *) xmalloc(sizeof(struct mbus)); if (m == NULL) { debug_msg("Unable to allocate memory for mbus\n"); return NULL; } m->cfg = mbus_create_config(); mbus_lock_config_file(m->cfg); net_addr = (char *) xmalloc(20); mbus_get_net_addr(m->cfg, net_addr, &net_port, &net_scope); m->s = udp_init(net_addr, net_port, net_port, net_scope); if (m->s == NULL) { debug_msg("Unable to initialize mbus address\n"); xfree(m); return NULL; } m->seqnum = 0; m->cmd_handler = cmd_handler; m->err_handler = err_handler; m->num_other_addr = 0; m->max_other_addr = 10; m->other_addr = (char **) xmalloc(sizeof(char *) * 10); m->other_hello = (struct timeval **) xmalloc(sizeof(struct timeval *) * 10); for (i = 0; i < 10; i++) { m->other_addr[i] = NULL; m->other_hello[i] = NULL; } m->cmd_queue = NULL; m->waiting_ack = NULL; m->magic = MBUS_MAGIC; m->index = 0; m->index_sent = 0; mp = mbus_parse_init(xstrdup(addr)); if (!mbus_parse_lst(mp, &tmp)) { debug_msg("Invalid mbus address\n"); abort(); } m->addr = xstrdup(tmp); mbus_parse_done(mp); assert(m->addr != NULL); gettimeofday(&(m->last_heartbeat), NULL); mbus_get_encrkey(m->cfg, &k); m->encrkey = k.key; m->encrkeylen = k.key_len; mbus_get_hashkey(m->cfg, &k); m->hashkey = k.key; m->hashkeylen = k.key_len; mbus_unlock_config_file(m->cfg); xfree(net_addr); return m; } void mbus_cmd_handler(struct mbus *m, void (*cmd_handler)(char *src, char *cmd, char *arg, void *dat)) { mbus_validate(m); m->cmd_handler = cmd_handler; } static void mbus_flush_msgs(struct mbus_msg **queue) { struct mbus_msg *curr, *next; int i; curr = *queue; while(curr) { next = curr->next; xfree(curr->dest); for(i = 0; i < curr->num_cmds; i++) { xfree(curr->cmd_list[i]); xfree(curr->arg_list[i]); } xfree(curr); curr = next; } *queue = NULL; } void mbus_exit(struct mbus *m) { int i; assert(m != NULL); mbus_validate(m); asarray_destroy(&seq_numbers); mbus_qmsg(m, "()", "mbus.bye", "", FALSE); mbus_send(m); /* FIXME: It should be a fatal error to call mbus_exit() if some messages are still outstanding. */ /* We will need an mbus_flush() call first though, to ensure nothing is waiting. */ mbus_flush_msgs(&m->cmd_queue); mbus_flush_msgs(&m->waiting_ack); if (m->encrkey != NULL) { xfree(m->encrkey); } if (m->hashkey != NULL) { xfree(m->hashkey); } udp_exit(m->s); /* Clean up other_* */ for (i=m->num_other_addr-1; i>=0; i--){ remove_other_addr(m, m->other_addr[i]); } xfree(m->addr); xfree(m->other_addr); xfree(m->other_hello); xfree(m->cfg); xfree(m); } void mbus_send(struct mbus *m) { /* Send one, or more, messages previosly queued with mbus_qmsg(). */ /* Messages for the same destination are batched together. Stops */ /* when a reliable message is sent, until the ACK is received. */ struct mbus_msg *curr = m->cmd_queue; int i; mbus_validate(m); if (m->waiting_ack != NULL) { return; } while (curr != NULL) { mbus_msg_validate(curr); /* It's okay for us to send messages which haven't been marked as complete - */ /* that just means we're sending something which has the potential to have */ /* more data piggybacked. However, if it's not complete it MUST be the last */ /* in the list, or something has been reordered - which is bad. */ if (!curr->complete) { assert(curr->next == NULL); } if (curr->reliable) { if (!mbus_addr_valid(m, curr->dest)) { debug_msg("Trying to send reliably to an unknown address...\n"); if (m->err_handler == NULL) { abort(); } m->err_handler(curr->seqnum, MBUS_DESTINATION_UNKNOWN); } if (!mbus_addr_unique(m, curr->dest)) { debug_msg("Trying to send reliably but address is not unique...\n"); if (m->err_handler == NULL) { abort(); } m->err_handler(curr->seqnum, MBUS_DESTINATION_NOT_UNIQUE); } } /* Create the message... */ mb_header(curr->seqnum, curr->comp_time, (char)(curr->reliable?'R':'U'), m->addr, curr->dest, -1); for (i = 0; i < curr->num_cmds; i++) { assert(m->index_sent == (curr->idx_list[i] - 1)); m->index_sent = curr->idx_list[i]; mb_add_command(curr->cmd_list[i], curr->arg_list[i]); } mb_send(m); m->cmd_queue = curr->next; if (curr->reliable) { /* Reliable message, wait for the ack... */ gettimeofday(&(curr->send_time), NULL); m->waiting_ack = curr; curr->next = NULL; return; } else { while (curr->num_cmds > 0) { curr->num_cmds--; xfree(curr->cmd_list[curr->num_cmds]); curr->cmd_list[curr->num_cmds] = NULL; xfree(curr->arg_list[curr->num_cmds]); curr->arg_list[curr->num_cmds] = NULL; } xfree(curr->dest); xfree(curr); } curr = m->cmd_queue; } } void mbus_qmsg(struct mbus *m, const char *dest, const char *cmnd, const char *args, int reliable) { /* Queue up a message for sending. The message is not */ /* actually sent until mbus_send() is called. */ struct mbus_msg *curr = m->cmd_queue; struct mbus_msg *prev = NULL; int alen = strlen(cmnd) + strlen(args) + 4; int i; mbus_validate(m); while (curr != NULL) { mbus_msg_validate(curr); if (!curr->complete) { /* This message is still open for new commands. It MUST be the last in the */ /* cmd_queue, else commands will be reordered. */ assert(curr->next == NULL); if (mbus_addr_identical(curr->dest, dest) && (curr->num_cmds < MBUS_MAX_QLEN) && ((curr->message_size + alen) < (MBUS_BUF_SIZE - 500))) { curr->num_cmds++; curr->reliable |= reliable; curr->cmd_list[curr->num_cmds-1] = xstrdup(cmnd); curr->arg_list[curr->num_cmds-1] = xstrdup(args); curr->idx_list[curr->num_cmds-1] = ++(m->index); curr->message_size += alen; mbus_msg_validate(curr); return; } else { curr->complete = TRUE; } } prev = curr; curr = curr->next; } /* If we get here, we've not found an open message in the cmd_queue. We */ /* have to create a new message, and add it to the end of the cmd_queue. */ curr = (struct mbus_msg *) xmalloc(sizeof(struct mbus_msg)); curr->magic = MBUS_MSG_MAGIC; curr->next = NULL; curr->dest = xstrdup(dest); curr->retransmit_count = 0; curr->message_size = alen + 60 + strlen(dest) + strlen(m->addr); curr->seqnum = ++m->seqnum; curr->reliable = reliable; curr->complete = FALSE; curr->num_cmds = 1; curr->cmd_list[0] = xstrdup(cmnd); curr->arg_list[0] = xstrdup(args); curr->idx_list[curr->num_cmds-1] = ++(m->index); for (i = 1; i < MBUS_MAX_QLEN; i++) { curr->cmd_list[i] = NULL; curr->arg_list[i] = NULL; } if (prev == NULL) { m->cmd_queue = curr; } else { prev->next = curr; } gettimeofday(&(curr->send_time), NULL); gettimeofday(&(curr->comp_time), NULL); mbus_msg_validate(curr); } void mbus_qmsgf(struct mbus *m, const char *dest, int reliable, const char *cmnd, const char *format, ...) { /* This is a wrapper around mbus_qmsg() which does a printf() style format into */ /* a buffer. Saves the caller from having to a a malloc(), write the args string */ /* and then do a free(), and also saves worring about overflowing the buffer, so */ /* removing a common source of bugs! */ char buffer[MBUS_BUF_SIZE]; va_list ap; mbus_validate(m); va_start(ap, format); #ifdef WIN32 _vsnprintf(buffer, MBUS_BUF_SIZE, format, ap); #else vsnprintf(buffer, MBUS_BUF_SIZE, format, ap); #endif va_end(ap); mbus_qmsg(m, dest, cmnd, buffer, reliable); } int mbus_recv(struct mbus *m, void *data, struct timeval *timeout) { char *auth, *ver, *src, *dst, *ack, *r, *cmd, *param, *npos; char buffer_array[MBUS_BUF_SIZE+1]; char *buffer; int buffer_len, seq, a, rx, authlen, loop_count; struct timeval ts = {0,0}; char ackbuf[MBUS_ACK_BUF_SIZE]; char digest[16]; unsigned char initVec[8] = {0,0,0,0,0,0,0,0}; struct timeval t; struct mbus_parser *mp, *mp2; mbus_validate(m); // debug_msg("receiving\n"); rx = FALSE; loop_count = 0; while (loop_count++ < 10) { buffer = buffer_array; memset(buffer, 0, MBUS_BUF_SIZE); assert(m != NULL); assert(m->s != NULL); udp_fd_zero(); udp_fd_set(m->s); t.tv_sec = timeout->tv_sec; t.tv_usec = timeout->tv_usec; if ((udp_select(&t) > 0) && udp_fd_isset(m->s)) { buffer_len = udp_recv(m->s, buffer, MBUS_BUF_SIZE); if (buffer_len > 0) { rx = TRUE; } else { return rx; } } else { return FALSE; } /* check authentication */ auth = buffer; /* Check that the packet authenticates correctly... */ authlen = 0; if(m->hashkey != NULL){ authlen = MBUS_AUTH_LEN; hmac_md5(buffer + authlen + 1, buffer_len - authlen - 1, m->hashkey, m->hashkeylen, digest); base64encode(digest, 12, ackbuf, 16); if ((strncmp(auth, ackbuf, 16) != 0)) { debug_msg("Failed to authenticate message...\n"); continue; } } buffer += authlen+1; buffer_len -= authlen+1; if (m->encrkey != NULL) { /* Decrypt the message... */ if ((buffer_len % 8) != 0) { debug_msg("Encrypted message not a multiple of 8 bytes in length\n"); continue; } memcpy(mb_cryptbuf, buffer, buffer_len); memset(initVec, 0, 8); qfDES_CBC_d(m->encrkey, mb_cryptbuf, buffer_len, initVec); memcpy(buffer, mb_cryptbuf, buffer_len); } /* Sanity check that this is a vaguely sensible format message... Should prevent */ /* problems if we're fed complete garbage, but won't prevent determined hackers. */ if (strncmp(buffer, "mbus/1.0", 8) != 0) { debug_msg("message doesn't start with preamble\n"); continue; } buffer[buffer_len] = '\0'; assert(strlen(buffer) <= MBUS_BUF_SIZE); mp = mbus_parse_init(buffer); /* remove trailing 0 bytes */ npos = (char *) strchr(buffer,'\0'); if(npos!=NULL) { buffer_len=npos-buffer; } /* Parse the header */ if (!mbus_parse_sym(mp, &ver)) { mbus_parse_done(mp); debug_msg("Parser failed version (1): %s\n",ver); continue; } if (strcmp(ver, "mbus/1.0") != 0) { mbus_parse_done(mp); debug_msg("Parser failed version (2): %s\n",ver); continue; } if (!mbus_parse_int(mp, &seq)) { mbus_parse_done(mp); debug_msg("Parser failed seq\n"); continue; } if (!mbus_parse_ts(mp, &ts)) { mbus_parse_done(mp); debug_msg("Parser failed ts\n"); continue; } if (!mbus_parse_sym(mp, &r)) { mbus_parse_done(mp); debug_msg("Parser failed reliable\n"); continue; } if (!mbus_parse_lst(mp, &src)) { mbus_parse_done(mp); debug_msg("Parser failed src\n"); continue; } if (!mbus_parse_lst(mp, &dst)) { mbus_parse_done(mp); debug_msg("Parser failed dst\n"); continue; } if (!mbus_parse_lst(mp, &ack)) { mbus_parse_done(mp); debug_msg("Parser failed ack\n"); continue; } store_other_addr(m, src); /* Check if the message was addressed to us... */ if (mbus_addr_match(m->addr, dst)) { /* ...if so, process any ACKs received... */ mp2 = mbus_parse_init(ack); while (mbus_parse_int(mp2, &a)) { if (mbus_waiting_ack(m)) { if (m->waiting_ack->seqnum == a) { while (m->waiting_ack->num_cmds > 0) { m->waiting_ack->num_cmds--; xfree(m->waiting_ack->cmd_list[m->waiting_ack->num_cmds]); xfree(m->waiting_ack->arg_list[m->waiting_ack->num_cmds]); } xfree(m->waiting_ack->dest); xfree(m->waiting_ack); m->waiting_ack = NULL; } else { debug_msg("Got ACK %d but wanted %d\n", a, m->waiting_ack->seqnum); } } else { debug_msg("Got ACK %d but wasn't expecting it\n", a); } } mbus_parse_done(mp2); /* ...if an ACK was requested, send one... */ if (strcmp(r, "R") == 0) { char *newsrc = (char *) xmalloc(strlen(src) + 3); char *newseq = (char *) xmalloc(9); char *value; struct timeval t; debug_msg("received reliable msg %d, sending ACK\n", seq); sprintf(newsrc, "(%s)", src); /* Yes, this is a kludge. */ sprintf(newseq, "(%6d)", seq); /* size allocated in mb_header */ gettimeofday(&t, NULL); mb_header(++m->seqnum, t, 'U', m->addr, newsrc, seq); mb_send(m); /* Record sequence number of last reliable message from each source. If the next message we receive has the same source and same sequence number then it is a duplicate and we ignore it. */ if (asarray_lookup (seq_numbers, newsrc, &value)) { if (strcmp (value, newseq) == 0) { debug_msg ("Duplicate reliable message received - ignored\n"); xfree (newseq); xfree (newsrc); continue; } else { asarray_remove(seq_numbers, newsrc); asarray_add (seq_numbers, newsrc, newseq); } } else { asarray_add (seq_numbers, newsrc, newseq); } xfree (newseq); xfree (newsrc); } else if (strcmp(r, "U") == 0) { /* Unreliable message.... not need to do anything */ } else { debug_msg("Message with invalid reliability field \"%s\" ignored\n", r); } /* ...and process the commands contained in the message */ while (mbus_parse_sym(mp, &cmd)) { if (mbus_parse_lst(mp, ¶m)) { char *newsrc = (char *) xmalloc(strlen(src) + 3); sprintf(newsrc, "(%s)", src); /* Yes, this is a kludge. */ /* Finally, we snoop on the message we just passed to the application, */ /* to do housekeeping of our list of known mbus sources... */ if (strcmp(cmd, "mbus.bye") == 0) { remove_other_addr(m, newsrc); } if (strcmp(cmd, "mbus.hello") == 0) { /* Mark this source as activ. We remove dead sources in mbus_heartbeat */ store_other_addr(m, newsrc); } assert(m != NULL); assert(m->cmd_handler != NULL); m->cmd_handler(newsrc, cmd, param, data); xfree(newsrc); } else { debug_msg("Unable to parse mbus command:\n"); debug_msg("cmd = %s\n", cmd); debug_msg("arg = %s\n", param); break; } } } mbus_parse_done(mp); } return rx; } #define RZ_HANDLE_WAITING 1 #define RZ_HANDLE_GO 2 struct mbus_rz { char *peer; char *token; struct mbus *m; void *data; int mode; void (*cmd_handler)(char *src, char *cmd, char *args, void *data); }; static void rz_handler(char *src, char *cmd, char *args, void *data) { struct mbus_rz *r = (struct mbus_rz *) data; struct mbus_parser *mp; if ((r->mode == RZ_HANDLE_WAITING) && (strcmp(cmd, "mbus.waiting") == 0)) { char *t; mp = mbus_parse_init(args); mbus_parse_str(mp, &t); if (strcmp(mbus_decode_str(t), r->token) == 0) { if (r->peer != NULL) xfree(r->peer); r->peer = xstrdup(src); } mbus_parse_done(mp); } else if ((r->mode == RZ_HANDLE_GO) && (strcmp(cmd, "mbus.go") == 0)) { char *t; mp = mbus_parse_init(args); mbus_parse_str(mp, &t); if (strcmp(mbus_decode_str(t), r->token) == 0) { if (r->peer != NULL) xfree(r->peer); r->peer = xstrdup(src); } mbus_parse_done(mp); } else { r->cmd_handler(src, cmd, args, r->data); } } char *mbus_rendezvous_waiting(struct mbus *m, char *addr, char *token, void *data) { /* Loop, sending mbus.waiting(token) to "addr", until we get mbus.go(token) */ /* back from our peer. Any other mbus commands received whilst waiting are */ /* processed in the normal manner, as if mbus_recv() had been called. */ char *token_e, *peer; struct timeval timeout; struct mbus_rz *r; mbus_validate(m); r = (struct mbus_rz *) xmalloc(sizeof(struct mbus_rz)); r->peer = NULL; r->token = token; r->m = m; r->data = data; r->mode = RZ_HANDLE_GO; r->cmd_handler = m->cmd_handler; m->cmd_handler = rz_handler; token_e = mbus_encode_str(token); while (r->peer == NULL) { timeout.tv_sec = 0; timeout.tv_usec = 100000; mbus_heartbeat(m, 1); mbus_qmsgf(m, addr, FALSE, "mbus.waiting", "%s", token_e); mbus_send(m); mbus_recv(m, r, &timeout); mbus_retransmit(m); } m->cmd_handler = r->cmd_handler; peer = r->peer; xfree(r); xfree(token_e); return peer; } char *mbus_rendezvous_go(struct mbus *m, char *token, void *data) { /* Wait until we receive mbus.waiting(token), then send mbus.go(token) back to */ /* the sender of that message. Whilst waiting, other mbus commands are processed */ /* in the normal manner as if mbus_recv() had been called. */ char *token_e, *peer; struct timeval timeout; struct mbus_rz *r; mbus_validate(m); r = (struct mbus_rz *) xmalloc(sizeof(struct mbus_rz)); r->peer = NULL; r->token = token; r->m = m; r->data = data; r->mode = RZ_HANDLE_WAITING; r->cmd_handler = m->cmd_handler; m->cmd_handler = rz_handler; token_e = mbus_encode_str(token); while (r->peer == NULL) { timeout.tv_sec = 0; timeout.tv_usec = 100000; mbus_heartbeat(m, 1); mbus_send(m); mbus_recv(m, r, &timeout); mbus_retransmit(m); } mbus_qmsgf(m, r->peer, TRUE, "mbus.go", "%s", token_e); do { mbus_heartbeat(m, 1); mbus_retransmit(m); mbus_send(m); timeout.tv_sec = 0; timeout.tv_usec = 100000; mbus_recv(m, r, &timeout); } while (!mbus_sent_all(m)); m->cmd_handler = r->cmd_handler; peer = r->peer; xfree(r); xfree(token_e); return peer; } uclmmbase-1.2.16.0/src/mbus.h0000640000175000017500000000621307051621151014565 0ustar enderender/* * FILE: mbus.h * AUTHORS: Colin Perkins * * Copyright (c) 1997-2000 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted, provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Science * Department at University College London * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ #ifndef _MBUS_H #define _MBUS_H /* Error codes... */ #define MBUS_MESSAGE_LOST 1 #define MBUS_DESTINATION_UNKNOWN 2 #define MBUS_DESTINATION_NOT_UNIQUE 3 struct mbus; #if defined(__cplusplus) extern "C" { #endif struct mbus *mbus_init(void (*cmd_handler)(char *src, char *cmd, char *arg, void *dat), void (*err_handler)(int seqnum, int reason), char *addr); void mbus_cmd_handler(struct mbus *m, void (*cmd_handler)(char *src, char *cmd, char *arg, void *dat)); void mbus_exit(struct mbus *m); int mbus_addr_valid(struct mbus *m, char *addr); void mbus_qmsg(struct mbus *m, const char *dest, const char *cmnd, const char *args, int reliable); void mbus_qmsgf(struct mbus *m, const char *dest, int reliable, const char *cmnd, const char *format, ...); void mbus_send(struct mbus *m); int mbus_recv(struct mbus *m, void *data, struct timeval *timeout); void mbus_retransmit(struct mbus *m); void mbus_heartbeat(struct mbus *m, int interval); int mbus_waiting_ack(struct mbus *m); int mbus_sent_all(struct mbus *m); char *mbus_rendezvous_waiting(struct mbus *m, char *addr, char *token, void *data); char *mbus_rendezvous_go(struct mbus *m, char *token, void *data); #if defined(__cplusplus) } #endif #endif uclmmbase-1.2.16.0/src/mbus_addr.c0000640000175000017500000000646507314411165015567 0ustar enderender/* * FILE: mbus_addr.c * AUTHOR: Colin Perkins * * Copyright (c) 2000 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Science * Department at University College London * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ #include "config_unix.h" #include "config_win32.h" #include "debug.h" #include "util.h" #include "mbus_addr.h" int mbus_addr_match(const char *a, const char *b) { /* Compare the addresses "a" and "b". These may optionally be */ /* surrounded by "(" and ")" and may have an arbitrary amount */ /* of white space between components of the addresses. There */ /* is a match if every word of address b is in address a. */ const char *y = NULL; assert(a != NULL); assert(b != NULL); /* Skip leading whitespace and '('... */ while (isspace((unsigned char)*a) || (*a == '(')) a++; while (isspace((unsigned char)*b) || (*b == '(')) b++; while ((*b != '\0') && (*b != ')')) { /* Move b along through the string to the start of the next */ /* word. Move y along from that to the end of the word. */ while (isspace((unsigned char)*b)) b++; for (y = b; ((*y != ' ') && (*y != ')') && (*y != '\0')); y++) { /* do nothing */ } if(y == b) return TRUE; y--; /* Check if the word between b and y is contained in the */ /* string pointed to be a. */ if (!strfind(a, b, y)) { return FALSE; } b = ++y; } return TRUE; } int mbus_addr_identical(const char *a, const char *b) { /* A more restrictive version of mbus_addr_match. Returns TRUE */ /* iff the addresses are identical (except, possibly, for order */ /* of the elements. */ return mbus_addr_match(a, b) && mbus_addr_match(b, a); } uclmmbase-1.2.16.0/src/mbus_addr.h0000640000175000017500000000366307252665775015614 0ustar enderender/* * FILE: mbus_addr.h * AUTHOR: Colin Perkins * * Copyright (c) 2000 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Science * Department at University College London * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ int mbus_addr_match(const char *a, const char *b); int mbus_addr_identical(const char *a, const char *b); uclmmbase-1.2.16.0/src/mbus_config.c0000640000175000017500000005633107226633542016126 0ustar enderender/* * FILE: mbus_config.c * AUTHOR: Colin Perkins * MODIFIED: Orion Hodson * Markus Germeier * * Copyright (c) 1999-2001 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Science * Department at University College London * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ #include "config_unix.h" #include "config_win32.h" #include "debug.h" #include "memory.h" #include "crypt_random.h" #include "base64.h" #include "mbus.h" #include "mbus_config.h" #define MBUS_ENCRYPT_BY_DEFAULT #define MBUS_ENCRKEY_LEN 8 #define MBUS_HASHKEY_LEN 12 #define MBUS_BUF_SIZE 1500 #define MBUS_FILE_NAME ".mbus" #define MBUS_FILE_NAME_LEN 5 struct mbus_config { #ifdef WIN32 HKEY cfgKey; #else fd_t cfgfd; #endif int cfg_locked; }; char *mbus_new_encrkey(void) { char *key; /* The key we are going to return... */ #ifdef MBUS_ENCRYPT_BY_DEFAULT /* Create a new key, for use by the hashing routines. Returns */ /* a key of the form (DES,MTIzMTU2MTg5MTEyMQ==) */ char random_string[MBUS_ENCRKEY_LEN]; char encoded_string[(MBUS_ENCRKEY_LEN*4/3)+4]; int encoded_length; int i, j, k; /* Step 1: generate a random string for the key... */ for (i = 0; i < MBUS_ENCRKEY_LEN; i++) { random_string[i] = ((int32_t)lbl_random() | 0x000ff000) >> 24; } /* Step 2: fill in parity bits to make DES library happy */ for (i = 0; i < MBUS_ENCRKEY_LEN; ++i) { k = random_string[i] & 0xfe; j = k; j ^= j >> 4; j ^= j >> 2; j ^= j >> 1; j = (j & 1) ^ 1; random_string[i] = k | j; } /* Step 3: base64 encode that string... */ memset(encoded_string, 0, (MBUS_ENCRKEY_LEN*4/3)+4); encoded_length = base64encode(random_string, MBUS_ENCRKEY_LEN, encoded_string, (MBUS_ENCRKEY_LEN*4/3)+4); /* Step 4: put it all together to produce the key... */ key = (char *) xmalloc(encoded_length + 18); sprintf(key, "(DES,%s)", encoded_string); #else key = (char *) xmalloc(9); sprintf(key, "(NOENCR)"); #endif return key; } char *mbus_new_hashkey(void) { /* Create a new key, for use by the hashing routines. Returns */ /* a key of the form (HMAC-MD5-96,MTIzMTU2MTg5MTEyMQ==) */ char random_string[MBUS_HASHKEY_LEN]; char encoded_string[(MBUS_HASHKEY_LEN*4/3)+4]; int encoded_length; int i; char *key; /* Step 1: generate a random string for the key... */ for (i = 0; i < MBUS_HASHKEY_LEN; i++) { random_string[i] = ((int32_t)lbl_random() | 0x000ff000) >> 24; } /* Step 2: base64 encode that string... */ memset(encoded_string, 0, (MBUS_HASHKEY_LEN*4/3)+4); encoded_length = base64encode(random_string, MBUS_HASHKEY_LEN, encoded_string, (MBUS_HASHKEY_LEN*4/3)+4); /* Step 3: put it all together to produce the key... */ key = (char *) xmalloc(encoded_length + 26); sprintf(key, "(HMAC-MD5-96,%s)", encoded_string); return key; } static void rewrite_config(struct mbus_config *m) { #ifdef WIN32 char *hashkey = mbus_new_hashkey(); char *encrkey = mbus_new_encrkey(); char *scope = MBUS_DEFAULT_SCOPE_NAME; const uint32_t cver = MBUS_CONFIG_VERSION; const uint32_t port = MBUS_DEFAULT_NET_PORT; char *addr = xstrdup(MBUS_DEFAULT_NET_ADDR); char buffer[MBUS_BUF_SIZE]; LONG status; status = RegSetValueEx(m->cfgKey, "CONFIG_VERSION", 0, REG_DWORD, (const uint8_t *) &cver, sizeof(cver)); if (status != ERROR_SUCCESS) { FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL); debug_msg("Unable to set version: %s\n", buffer); abort(); } status = RegSetValueEx(m->cfgKey, "HASHKEY", 0, REG_SZ, hashkey, strlen(hashkey) + 1); if (status != ERROR_SUCCESS) { FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL); debug_msg("Unable to set hashkey: %s\n", buffer); abort(); } status = RegSetValueEx(m->cfgKey, "ENCRYPTIONKEY", 0, REG_SZ, encrkey, strlen(encrkey) + 1); if (status != ERROR_SUCCESS) { FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL); debug_msg("Unable to set encrkey: %s\n", buffer); abort(); } status = RegSetValueEx(m->cfgKey, "SCOPE", 0, REG_SZ, scope, strlen(scope) + 1); if (status != ERROR_SUCCESS) { FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL); debug_msg("Unable to set scope: %s\n", buffer); abort(); } status = RegSetValueEx(m->cfgKey, "ADDRESS", 0, REG_SZ, addr, strlen(addr) + 1); if (status != ERROR_SUCCESS) { FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL); debug_msg("Unable to set address: %s\n", buffer); abort(); } status = RegSetValueEx(m->cfgKey, "PORT", 0, REG_DWORD, (const uint8_t *) &port, sizeof(port)); if (status != ERROR_SUCCESS) { FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL); debug_msg("Unable to set port: %s\n", buffer); abort(); } xfree(addr); #else char *hashkey = mbus_new_hashkey(); char *encrkey = mbus_new_encrkey(); char buf[1024]; if (lseek(m->cfgfd, 0, SEEK_SET) == -1) { perror("Can't seek to start of config file"); abort(); } sprintf(buf, "[MBUS]\nCONFIG_VERSION=%d\nHASHKEY=%s\nENCRYPTIONKEY=%s\nSCOPE=%s\nADDRESS=%s\nPORT=%d\n", MBUS_CONFIG_VERSION, hashkey, encrkey, MBUS_DEFAULT_SCOPE_NAME, MBUS_DEFAULT_NET_ADDR, MBUS_DEFAULT_NET_PORT); write(m->cfgfd, buf, strlen(buf)); free(hashkey); xfree(encrkey); #endif } void mbus_lock_config_file(struct mbus_config *m) { #ifdef WIN32 /* Open the registry and create the mbus entries if they don't exist */ /* already. The default contents of the registry are random encryption */ /* and authentication keys, and node local scope. */ HKEY key = HKEY_CURRENT_USER; LPCTSTR subKey = "Software\\Mbone Applications\\mbus"; DWORD disp; char buffer[MBUS_BUF_SIZE]; LONG status; status = RegCreateKeyEx(key, subKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &(m->cfgKey), &disp); if (status != ERROR_SUCCESS) { FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL); debug_msg("Unable to open registry: %s\n", buffer); abort(); } if (disp == REG_CREATED_NEW_KEY) { rewrite_config(m); debug_msg("Created new registry entry...\n"); } else { debug_msg("Opened existing registry entry...\n"); } #else /* Obtain a valid lock on the mbus configuration file. This function */ /* creates the file, if one does not exist. The default contents of */ /* this file are random authentication and encryption keys, and node */ /* local scope. */ struct flock l; struct stat s; char *buf; char *cfg_file; char *cfg_loc; int cfg_loc_len; cfg_loc = getenv("MBUS"); if (cfg_loc == NULL) { cfg_loc = getenv("HOME"); if (cfg_loc == NULL) { /* The getpwuid() stuff is to determine the users */ /* home directory, into which we write a .mbus */ /* config file. The struct returned by getpwuid() is */ /* statically allocated, so it's not necessary to */ /* free it afterwards. */ struct passwd *p; p = getpwuid(getuid()); if (p == NULL) { perror("Unable to get passwd entry"); abort(); } cfg_loc = p->pw_dir; } } /* Check if config_loc is terminated by mbus config file name. If */ /* it's not add it. This is allows environment variable MBUS to */ /* point to config file of directory of config file. */ cfg_loc_len = strlen(cfg_loc); if (cfg_loc_len < MBUS_FILE_NAME_LEN || strcmp(cfg_loc + cfg_loc_len - MBUS_FILE_NAME_LEN, MBUS_FILE_NAME)){ /* File location does not include config file name. */ cfg_file = (char*)xmalloc(cfg_loc_len + MBUS_FILE_NAME_LEN + 2); sprintf(cfg_file, "%s/%s", cfg_loc, MBUS_FILE_NAME); } else { cfg_file = xstrdup(cfg_loc); } m->cfgfd = open(cfg_file, O_RDWR | O_CREAT, 0600); if (m->cfgfd == -1) { perror("Unable to open mbus configuration file"); abort(); } /* We attempt to get a lock on the config file, blocking until */ /* the lock can be obtained. The only time this should block is */ /* when another instance of this code has a write lock on the */ /* file, because the contents are being updated. */ l.l_type = F_WRLCK; l.l_start = 0; l.l_whence = SEEK_SET; l.l_len = 0; if (fcntl(m->cfgfd, F_SETLKW, &l) == -1) { perror("Unable to lock mbus configuration file"); printf("The most likely reason for this error is that %s\n", cfg_file); printf("is on an NFS filestore, and you have not correctly setup file locking. \n"); printf("Ask your system administrator to ensure that rpc.lockd and/or rpc.statd\n"); printf("are running. \n"); abort(); } xfree(cfg_file); if (fstat(m->cfgfd, &s) != 0) { perror("Unable to stat config file\n"); abort(); } if (s.st_size == 0) { /* Empty file, create with sensible defaults... */ rewrite_config(m); } else { /* Read in the contents of the config file... */ buf = (char *) xmalloc(s.st_size+1); memset(buf, '\0', s.st_size+1); if (read(m->cfgfd, buf, s.st_size) != s.st_size) { perror("Unable to read config file\n"); abort(); } /* Check that the file contains sensible information... */ /* This is rather a pathetic check, but it'll do for now! */ if (strncmp(buf, "[MBUS]", 6) != 0) { debug_msg("Mbus config file has incorrect header\n"); abort(); } xfree(buf); } #endif m->cfg_locked = TRUE; if (mbus_get_version(m) < MBUS_CONFIG_VERSION) { rewrite_config(m); debug_msg("Updated Mbus configuration database.\n"); } if (mbus_get_version(m) > MBUS_CONFIG_VERSION) { debug_msg("Mbus configuration database has later version number than expected.\n"); debug_msg("Continuing, in the hope that the extensions are backwards compatible.\n"); } } void mbus_unlock_config_file(struct mbus_config *m) { #ifdef WIN32 LONG status; char buffer[MBUS_BUF_SIZE]; status = RegCloseKey(m->cfgKey); if (status != ERROR_SUCCESS) { FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL); debug_msg("Unable to close registry: %s\n", buffer); abort(); } debug_msg("Closed registry entry...\n"); #else struct flock l; l.l_type = F_UNLCK; l.l_start = 0; l.l_whence = SEEK_SET; l.l_len = 0; if (fcntl(m->cfgfd, F_SETLKW, &l) == -1) { perror("Unable to unlock mbus configuration file"); abort(); } close(m->cfgfd); m->cfgfd = -1; #endif m->cfg_locked = FALSE; } #ifndef WIN32 static void mbus_get_key(struct mbus_config *m, struct mbus_key *key, const char *id) { struct stat s; char *buf; char *line; char *tmp; int pos; int linepos; assert(m->cfg_locked); if (lseek(m->cfgfd, 0, SEEK_SET) == -1) { perror("Can't seek to start of config file"); abort(); } if (fstat(m->cfgfd, &s) != 0) { perror("Unable to stat config file\n"); abort(); } /* Read in the contents of the config file... */ buf = (char *) xmalloc(s.st_size+1); memset(buf, '\0', s.st_size+1); if (read(m->cfgfd, buf, s.st_size) != s.st_size) { perror("Unable to read config file\n"); abort(); } line = (char *) xmalloc(s.st_size+1); sscanf(buf, "%s", line); if (strcmp(line, "[MBUS]") != 0) { debug_msg("Invalid .mbus file\n"); abort(); } pos = strlen(line) + 1; while (pos < s.st_size) { /* get whole line and filter out spaces */ /* this is good enough for getting keys */ linepos=0; do { while((buf[pos+linepos]==' ')||(buf[pos+linepos]=='\n') ||(buf[pos+linepos]=='\t')) pos++; sscanf(buf+pos+linepos, "%s", line+linepos); linepos = strlen(line); } while((buf[pos+linepos]!='\n') && (s.st_size>(pos+linepos+1))); pos += linepos + 1; if (strncmp(line, id, strlen(id)) == 0) { key->algorithm = (char *) strdup(strtok(line+strlen(id), ",)")); if (strcmp(key->algorithm, "NOENCR") != 0) { key->key = (char *) strtok(NULL , ")"); assert(key->key!=NULL); key->key_len = strlen(key->key); tmp = (char *) xmalloc(key->key_len); key->key_len = base64decode(key->key, key->key_len, tmp, key->key_len); key->key = tmp; } else { key->key = NULL; key->key_len = 0; } xfree(buf); xfree(line); return; } } debug_msg("Unable to read hashkey from config file\n"); xfree(buf); xfree(line); } #endif void mbus_get_encrkey(struct mbus_config *m, struct mbus_key *key) { /* This MUST be called while the config file is locked! */ int i, j, k; #ifdef WIN32 long status; DWORD type; char *buffer; int buflen = MBUS_BUF_SIZE; char *tmp; assert(m->cfg_locked); /* Read the key from the registry... */ buffer = (char *) xmalloc(MBUS_BUF_SIZE); status = RegQueryValueEx(m->cfgKey, "ENCRYPTIONKEY", 0, &type, buffer, &buflen); if (status != ERROR_SUCCESS) { FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL); debug_msg("Unable to get encrkey: %s\n", buffer); abort(); } assert(type == REG_SZ); assert(buflen > 0); /* Parse the key... */ key->algorithm = strdup(strtok(buffer+1, ",)")); if (strcmp(key->algorithm, "NOENCR") != 0) { key->key = (char *) strtok(NULL , ")"); key->key_len = strlen(key->key); tmp = (char *) xmalloc(key->key_len); key->key_len = base64decode(key->key, key->key_len, tmp, key->key_len); key->key = tmp; } else { key->key = NULL; key->key_len = 0; } xfree(buffer); #else mbus_get_key(m, key, "ENCRYPTIONKEY=("); #endif if (strcmp(key->algorithm, "DES") == 0) { assert(key->key != NULL); assert(key->key_len == 8); /* check parity bits */ for (i = 0; i < 8; ++i) { k = key->key[i] & 0xfe; j = k; j ^= j >> 4; j ^= j >> 2; j ^= j >> 1; j = (j & 1) ^ 1; assert((key->key[i] & 0x01) == j); } } } void mbus_get_hashkey(struct mbus_config *m, struct mbus_key *key) { /* This MUST be called while the config file is locked! */ #ifdef WIN32 long status; DWORD type; char *buffer; int buflen = MBUS_BUF_SIZE; char *tmp; assert(m->cfg_locked); /* Read the key from the registry... */ buffer = (char *) xmalloc(MBUS_BUF_SIZE); status = RegQueryValueEx(m->cfgKey, "HASHKEY", 0, &type, buffer, &buflen); if (status != ERROR_SUCCESS) { FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL); debug_msg("Unable to get encrkey: %s\n", buffer); abort(); } assert(type == REG_SZ); assert(buflen > 0); /* Parse the key... */ key->algorithm = strdup(strtok(buffer+1, ",")); key->key = strtok(NULL , ")"); key->key_len = strlen(key->key); /* Decode the key... */ tmp = (char *) xmalloc(key->key_len); key->key_len = base64decode(key->key, key->key_len, tmp, key->key_len); key->key = tmp; xfree(buffer); #else mbus_get_key(m, key, "HASHKEY=("); #endif } void mbus_get_net_addr(struct mbus_config *m, char *net_addr, uint16_t *net_port, int *net_scope) { #ifdef WIN32 long status; DWORD type; char *buffer; int buflen = MBUS_BUF_SIZE; uint32_t port; assert(m->cfg_locked); /* Read the key from the registry... */ buffer = (char *) xmalloc(MBUS_BUF_SIZE); buflen = MBUS_BUF_SIZE; status = RegQueryValueEx(m->cfgKey, "ADDRESS", 0, &type, buffer, &buflen); if (status != ERROR_SUCCESS) { FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL); debug_msg("Unable to get address: %s\n", buffer); strcpy(net_addr, MBUS_DEFAULT_NET_ADDR); } else { assert(type == REG_SZ); assert(buflen > 0); strncpy(net_addr, buffer, buflen); } buflen = sizeof(port); status = RegQueryValueEx(m->cfgKey, "PORT", 0, &type, (uint8_t *) &port, &buflen); if (status != ERROR_SUCCESS) { FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL); debug_msg("Unable to get port: %s\n", buffer); *net_port = MBUS_DEFAULT_NET_PORT; } else { assert(type == REG_DWORD); assert(buflen == 4); *net_port = (uint16_t) port; } buflen = MBUS_BUF_SIZE; status = RegQueryValueEx(m->cfgKey, "SCOPE", 0, &type, buffer, &buflen); if (status != ERROR_SUCCESS) { FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL); debug_msg("Unable to get scope: %s\n", buffer); *net_scope = MBUS_DEFAULT_SCOPE; } else { assert(type == REG_SZ); assert(buflen > 0); if (strncmp(buffer, SCOPE_HOSTLOCAL_NAME, strlen(SCOPE_HOSTLOCAL_NAME)) == 0) { *net_scope = SCOPE_HOSTLOCAL; } else if (strncmp(buffer, SCOPE_LINKLOCAL_NAME, strlen(SCOPE_LINKLOCAL_NAME)) == 0) { *net_scope = SCOPE_LINKLOCAL; } else { debug_msg("Unrecognized scope: %s\n", buffer); *net_scope = MBUS_DEFAULT_SCOPE; } } xfree(buffer); #else struct stat s; char *buf; char *line; int pos; int pos2; int linepos; int scope; char *addr; uint16_t port; assert(m->cfg_locked); addr = (char *)xmalloc(20); memset(addr, 0, 20); port = 0; scope = -1; if (lseek(m->cfgfd, 0, SEEK_SET) == -1) { perror("Can't seek to start of config file"); abort(); } if (fstat(m->cfgfd, &s) != 0) { perror("Unable to stat config file\n"); abort(); } /* Read in the contents of the config file... */ buf = (char *) xmalloc(s.st_size+1); memset(buf, '\0', s.st_size+1); if (read(m->cfgfd, buf, s.st_size) != s.st_size) { perror("Unable to read config file\n"); abort(); } line = (char *) xmalloc(s.st_size+1); sscanf(buf, "%s", line); if (strcmp(line, "[MBUS]") != 0) { debug_msg("Invalid .mbus file\n"); abort(); } pos = strlen(line) + 1; while (pos < s.st_size) { /* get whole line and filter out spaces */ linepos=0; do { while((buf[pos+linepos]==' ')||(buf[pos+linepos]=='\n') ||(buf[pos+linepos]=='\t')) pos++; sscanf(buf+pos+linepos, "%s", line+linepos); linepos = strlen(line); } while((buf[pos+linepos]!='\n') && (s.st_size>(pos+linepos+1))); pos += linepos + 1; if (strncmp(line, "SCOPE", strlen("SCOPE")) == 0) { pos2 = strlen("SCOPE") + 1; if (strncmp(line+pos2, SCOPE_HOSTLOCAL_NAME, strlen(SCOPE_HOSTLOCAL_NAME)) == 0) { scope = SCOPE_HOSTLOCAL; } if (strncmp(line+pos2, SCOPE_LINKLOCAL_NAME, strlen(SCOPE_LINKLOCAL_NAME)) == 0) { scope = SCOPE_LINKLOCAL ; } } if (strncmp(line, "ADDRESS", strlen("ADDRESS")) == 0) { pos2 = strlen("ADDRESS") + 1; strncpy(addr, line+pos2, 16); } if (strncmp(line, "PORT", strlen("PORT")) == 0) { pos2 = strlen("PORT") + 1; port = atoi(line+pos2); } } /* If we did not find all values, fill in the default ones */ *net_port = (port>0)?port:MBUS_DEFAULT_NET_PORT; *net_scope = (scope!=-1)?scope:MBUS_DEFAULT_SCOPE; if (strlen(addr)>0) { strncpy(net_addr, addr, 16); } else { strcpy(net_addr, MBUS_DEFAULT_NET_ADDR); } debug_msg("using Addr:%s Port:%d Scope:%s for MBUS\n", net_addr, *net_port, (*net_scope==0)?SCOPE_HOSTLOCAL_NAME:SCOPE_LINKLOCAL_NAME); xfree(buf); xfree(line); xfree(addr); #endif } int mbus_get_version(struct mbus_config *m) { #ifdef WIN32 long status; DWORD type; uint32_t cver; int verl; char buffer[MBUS_BUF_SIZE]; assert(m->cfg_locked); /* Read the key from the registry... */ verl = sizeof(&cver); status = RegQueryValueEx(m->cfgKey, "CONFIG_VERSION", 0, &type, (uint8_t *) &cver, &verl); if (status != ERROR_SUCCESS) { FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL); debug_msg("Unable to get version: %s\n", buffer); return 0; } assert(type == REG_DWORD); assert(verl == 4); return cver; #else struct stat s; char *buf; char *line; int pos; int pos2; int linepos; int version = 0; assert(m->cfg_locked); if (lseek(m->cfgfd, 0, SEEK_SET) == -1) { perror("Can't seek to start of config file"); abort(); } if (fstat(m->cfgfd, &s) != 0) { perror("Unable to stat config file\n"); abort(); } /* Read in the contents of the config file... */ buf = (char *) xmalloc(s.st_size+1); memset(buf, '\0', s.st_size+1); if (read(m->cfgfd, buf, s.st_size) != s.st_size) { perror("Unable to read config file\n"); abort(); } line = (char *) xmalloc(s.st_size+1); sscanf(buf, "%s", line); if (strcmp(line, "[MBUS]") != 0) { debug_msg("Invalid .mbus file\n"); abort(); } pos = strlen(line) + 1; while (pos < s.st_size) { /* get whole line and filter out spaces */ linepos=0; do { while((buf[pos+linepos]==' ')||(buf[pos+linepos]=='\n') ||(buf[pos+linepos]=='\t')) { pos++; } sscanf(buf+pos+linepos, "%s", line+linepos); linepos = strlen(line); } while((buf[pos+linepos]!='\n') && (s.st_size>(pos+linepos+1))); pos += linepos + 1; if (strncmp(line, "CONFIG_VERSION", strlen("CONFIG_VERSION")) == 0) { pos2 = strlen("CONFIG_VERSION") + 1; version = atoi(line+pos2); } } xfree(buf); xfree(line); return version; #endif } struct mbus_config *mbus_create_config(void) { return (struct mbus_config *) xmalloc(sizeof(struct mbus_config)); } uclmmbase-1.2.16.0/src/mbus_config.h0000640000175000017500000000560607034372536016132 0ustar enderender/* * FILE: mbus_config.h * AUTHORS: Colin Perkins * * Copyright (c) 1999-2000 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Science * Department at University College London * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ #ifndef _MBUS_CONFIG #define _MBUS_CONFIG struct mbus_key { char *algorithm; char *key; int key_len; }; struct mbus_config; #define MBUS_CONFIG_VERSION 1 #define SCOPE_HOSTLOCAL 0 #define SCOPE_HOSTLOCAL_NAME "HOSTLOCAL" #define SCOPE_LINKLOCAL 1 #define SCOPE_LINKLOCAL_NAME "LINKLOCAL" #define MBUS_DEFAULT_NET_ADDR "224.255.222.239" #define MBUS_DEFAULT_NET_PORT 47000 #define MBUS_DEFAULT_SCOPE SCOPE_HOSTLOCAL #define MBUS_DEFAULT_SCOPE_NAME SCOPE_HOSTLOCAL_NAME #if defined(__cplusplus) extern "C" { #endif char *mbus_new_encrkey(void); char *mbus_new_hashkey(void); void mbus_lock_config_file(struct mbus_config *m); void mbus_unlock_config_file(struct mbus_config *m); void mbus_get_encrkey(struct mbus_config *m, struct mbus_key *key); void mbus_get_hashkey(struct mbus_config *m, struct mbus_key *key); void mbus_get_net_addr(struct mbus_config *m, char *net_addr, uint16_t *net_port, int *net_scope); int mbus_get_version(struct mbus_config *m); struct mbus_config *mbus_create_config(void); #if defined(__cplusplus) } #endif #endif uclmmbase-1.2.16.0/src/mbus_parser.h0000640000175000017500000000501607314411165016145 0ustar enderender/* * FILE: mbus_parser.h * AUTHOR: Colin Perkins * * Copyright (c) 2000 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Science * Department at University College London * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ #ifndef _MBUS_PARSER_H #define _MBUS_PARSER_H #if defined(__cplusplus) extern "C" { #endif struct mbus_parser; struct mbus_parser *mbus_parse_init(char *str); void mbus_parse_done(struct mbus_parser *m); int mbus_parse_lst(struct mbus_parser *m, char **l); int mbus_parse_str(struct mbus_parser *m, char **s); int mbus_parse_sym(struct mbus_parser *m, char **s); int mbus_parse_int(struct mbus_parser *m, int *i); int mbus_parse_ts(struct mbus_parser *m, struct timeval *ts); int mbus_parse_flt(struct mbus_parser *m, double *d); char *mbus_decode_str(char *s); char *mbus_encode_str(const char *s); #if defined(__cplusplus) } #endif #endif /* _MBUS_PARSER_H */ uclmmbase-1.2.16.0/src/md5.c0000640000175000017500000002303007252665775014322 0ustar enderender/* * MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm */ /* * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All rights * reserved. * * License to copy and use this software is granted provided that it is * identified as the "RSA Data Security, Inc. MD5 Message-Digest Algorithm" * in all material mentioning or referencing this software or this function. * * License is also granted to make and use derivative works provided that such * works are identified as "derived from the RSA Data Security, Inc. MD5 * Message-Digest Algorithm" in all material mentioning or referencing the * derived work. * * RSA Data Security, Inc. makes no representations concerning either the * merchantability of this software or the suitability of this software for * any particular purpose. It is provided "as is" without express or implied * warranty of any kind. * * These notices must be retained in any copies of any part of this * documentation and/or software. */ #include "config_unix.h" #include "config_win32.h" #include "md5.h" /* * Constants for MD5Transform routine. */ #define S11 7 #define S12 12 #define S13 17 #define S14 22 #define S21 5 #define S22 9 #define S23 14 #define S24 20 #define S31 4 #define S32 11 #define S33 16 #define S34 23 #define S41 6 #define S42 10 #define S43 15 #define S44 21 static unsigned char PADDING[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* * F, G, H and I are basic MD5 functions. */ #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) #define G(x, y, z) (((x) & (z)) | ((y) & (~z))) #define H(x, y, z) ((x) ^ (y) ^ (z)) #define I(x, y, z) ((y) ^ ((x) | (~z))) /* * ROTATE_LEFT rotates x left n bits. */ #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) /* * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. Rotation is * separate from addition to prevent recomputation. */ #define FF(a, b, c, d, x, s, ac) { \ (a) += F ((b), (c), (d)) + (x) + (uint32_t)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define GG(a, b, c, d, x, s, ac) { \ (a) += G ((b), (c), (d)) + (x) + (uint32_t)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define HH(a, b, c, d, x, s, ac) { \ (a) += H ((b), (c), (d)) + (x) + (uint32_t)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define II(a, b, c, d, x, s, ac) { \ (a) += I ((b), (c), (d)) + (x) + (uint32_t)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } /* * Encodes input (uint32_t) into output (unsigned char). Assumes len is a * multiple of 4. */ static void Encode(unsigned char *output, uint32_t * input, unsigned int len) { unsigned int i, j; assert((len % 4) == 0); for (i = 0, j = 0; j < len; i++, j += 4) { output[j] = (unsigned char) (input[i] & 0xff); output[j + 1] = (unsigned char) ((input[i] >> 8) & 0xff); output[j + 2] = (unsigned char) ((input[i] >> 16) & 0xff); output[j + 3] = (unsigned char) ((input[i] >> 24) & 0xff); } } /* * Decodes input (unsigned char) into output (uint32_t). Assumes len is a * multiple of 4. */ static void Decode(uint32_t * output, unsigned char *input, unsigned int len) { unsigned int i, j; for (i = 0, j = 0; j < len; i++, j += 4) output[i] = ((uint32_t) input[j]) | (((uint32_t) input[j + 1]) << 8) | (((uint32_t) input[j + 2]) << 16) | (((uint32_t) input[j + 3]) << 24); } /* * MD5 basic transformation. Transforms state based on block. */ static void MD5Transform(uint32_t state[4], unsigned char block[64]) { uint32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16]; Decode(x, block, 64); /* Round 1 */ FF(a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */ FF(d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */ FF(c, d, a, b, x[2], S13, 0x242070db); /* 3 */ FF(b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */ FF(a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */ FF(d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */ FF(c, d, a, b, x[6], S13, 0xa8304613); /* 7 */ FF(b, c, d, a, x[7], S14, 0xfd469501); /* 8 */ FF(a, b, c, d, x[8], S11, 0x698098d8); /* 9 */ FF(d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */ FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ /* Round 2 */ GG(a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */ GG(d, a, b, c, x[6], S22, 0xc040b340); /* 18 */ GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */ GG(a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */ GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */ GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */ GG(a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */ GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ GG(c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */ GG(b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */ GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ GG(d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */ GG(c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */ GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ /* Round 3 */ HH(a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */ HH(d, a, b, c, x[8], S32, 0x8771f681); /* 34 */ HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ HH(a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */ HH(d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */ HH(c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */ HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ HH(d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */ HH(c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */ HH(b, c, d, a, x[6], S34, 0x4881d05); /* 44 */ HH(a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */ HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ HH(b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */ /* Round 4 */ II(a, b, c, d, x[0], S41, 0xf4292244); /* 49 */ II(d, a, b, c, x[7], S42, 0x432aff97); /* 50 */ II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ II(b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */ II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ II(d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */ II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ II(b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */ II(a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */ II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ II(c, d, a, b, x[6], S43, 0xa3014314); /* 59 */ II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ II(a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */ II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ II(c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */ II(b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */ state[0] += a; state[1] += b; state[2] += c; state[3] += d; /* * Zeroize sensitive information. */ memset((unsigned char *) x, 0, sizeof(x)); } /** * MD5Init: * @context: MD5 context to be initialized. * * Initializes MD5 context for the start of message digest computation. **/ void MD5Init(MD5_CTX * context) { context->count[0] = context->count[1] = 0; /* Load magic initialization constants. */ context->state[0] = 0x67452301; context->state[1] = 0xefcdab89; context->state[2] = 0x98badcfe; context->state[3] = 0x10325476; } /** * MD5Update: * @context: MD5 context to be updated. * @input: pointer to data to be fed into MD5 algorithm. * @inputLen: size of @input data in bytes. * * MD5 block update operation. Continues an MD5 message-digest operation, * processing another message block, and updating the context. **/ void MD5Update(MD5_CTX * context, unsigned char *input, unsigned int inputLen) { unsigned int i, index, partLen; /* Compute number of bytes mod 64 */ index = (unsigned int) ((context->count[0] >> 3) & 0x3F); /* Update number of bits */ if ((context->count[0] += ((uint32_t) inputLen << 3)) < ((uint32_t) inputLen << 3)) { context->count[1]++; } context->count[1] += ((uint32_t) inputLen >> 29); partLen = 64 - index; /* Transform as many times as possible. */ if (inputLen >= partLen) { memcpy((unsigned char *) & context->buffer[index], (unsigned char *) input, partLen); MD5Transform(context->state, context->buffer); for (i = partLen; i + 63 < inputLen; i += 64) { MD5Transform(context->state, &input[i]); } index = 0; } else { i = 0; } /* Buffer remaining input */ if ((inputLen - i) != 0) { memcpy((unsigned char *) & context->buffer[index], (unsigned char *) & input[i], inputLen - i); } } /** * MD5Final: * @digest: 16-byte buffer to write MD5 checksum. * @context: MD5 context to be finalized. * * Ends an MD5 message-digest operation, writing the the message * digest and zeroing the context. The context must be initialized * with MD5Init() before being used for other MD5 checksum calculations. **/ void MD5Final(unsigned char digest[16], MD5_CTX * context) { unsigned char bits[8]; unsigned int index, padLen; /* Save number of bits */ Encode(bits, context->count, 8); /* * Pad out to 56 mod 64. */ index = (unsigned int) ((context->count[0] >> 3) & 0x3f); padLen = (index < 56) ? (56 - index) : (120 - index); MD5Update(context, PADDING, padLen); /* Append length (before padding) */ MD5Update(context, bits, 8); /* Store state in digest */ Encode(digest, context->state, 16); /* * Zeroize sensitive information. */ memset((unsigned char *) context, 0, sizeof(*context)); } uclmmbase-1.2.16.0/src/md5.h0000640000175000017500000000254407252665776014337 0ustar enderender/* MD5.H - header file for MD5C.C */ /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All rights reserved. License to copy and use this software is granted provided that it is identified as the "RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material mentioning or referencing this software or this function. License is also granted to make and use derivative works provided that such works are identified as "derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material mentioning or referencing the derived work. RSA Data Security, Inc. makes no representations concerning either the merchantability of this software or the suitability of this software for any particular purpose. It is provided "as is" without express or implied warranty of any kind. These notices must be retained in any copies of any part of this documentation and/or software. */ #ifdef __cplusplus extern "C" { #endif /* MD5 context. */ typedef struct { uint32_t state[4]; /* state (ABCD) */ uint32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */ unsigned char buffer[64]; /* input buffer */ } MD5_CTX; void MD5Init(MD5_CTX *context); void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputLen); void MD5Final(unsigned char digest[16], MD5_CTX *context); #ifdef __cplusplus } #endif uclmmbase-1.2.16.0/src/memory.c0000640000175000017500000004274607452140265015144 0ustar enderender/* * FILE: memory.c * AUTHORS: Isidor Kouvelas / Colin Perkins / Mark Handley / Orion Hodson * * $Revision: 1.20 $ * $Date: 2002/04/01 20:19:01 $ * * Copyright (c) 1995-2000 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Science * Department at University College London * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ #include "config_unix.h" #include "config_win32.h" #include "debug.h" #include "memory.h" #include "util.h" #ifdef DEBUG_MEM /* Custom memory routines are here, down to #else, defaults follow */ #define MAX_ADDRS 65536 #define MAGIC_MEMORY 0xdeadbeef #define MAGIC_MEMORY_SIZE 4 /* Allocated block format is: * */ typedef struct { uint32_t key; /* Original allocation number */ uint32_t size; /* Size of allocation requested */ uint32_t pad; /* Alignment padding to 8 bytes */ uint32_t magic; /* Magic number */ } chk_header; typedef struct s_alloc_blk { uint32_t key; /* Key in table (ascending) */ chk_header *addr; char *filen; /* file where allocated */ int line; /* line where allocated */ size_t length; /* size of allocation */ int blen; /* size passed to block_alloc (if relevent) */ int est; /* time last touched in order of all allocation and reclaims */ } alloc_blk; /* Table is ordered by key */ static alloc_blk mem_item[MAX_ADDRS]; static int naddr = 0; /* number of allocations */ static int tick = 1; /* xmemchk assumes this is one, do not change without checking why */ static int init = 0; /** * xdoneinit: * @void: * * Marks end of an applications initialization period. For media * applications with real-time data transfer it's sometimes helpful to * distinguish between memory allocated during application * initialization and when application is running. **/ void xdoneinit(void) { init = tick++; } static int chk_header_okay(const chk_header *ch) { const uint8_t *tm; /* tail magic */ assert(ch != NULL); if (ch->key == MAGIC_MEMORY) { fprintf(stderr, "ERROR: freed unit being checked\n"); abort(); } tm = (const uint8_t*)ch; tm += sizeof(chk_header) + ch->size; if (ch->magic != MAGIC_MEMORY) { fprintf(stderr, "ERROR: memory underrun\n"); abort(); return FALSE; } else if (memcmp(tm, &ch->magic, MAGIC_MEMORY_SIZE)) { fprintf(stderr, "ERROR: memory overrun\n"); abort(); return FALSE; } return TRUE; } static int mem_key_cmp(const void *a, const void *b) { const alloc_blk *g, *h; g = (const alloc_blk*)a; h = (const alloc_blk*)b; if (g->key < h->key) { return -1; } else if (g->key > h->key) { return +1; } return 0; } static alloc_blk *mem_item_find(uint32_t key) { void *p; alloc_blk t; t.key = key; p = bsearch((const void*)&t, mem_item, naddr, sizeof(alloc_blk), mem_key_cmp); return (alloc_blk*)p; } /** * xmemchk: * @void: * * Check for bounds overruns in all memory allocated with xmalloc(), * xrealloc(), and xstrdup(). Information on corrupted blocks is * rendered on the standard error stream. This includes where the * block was allocated, the size of the block, and the number of * allocations made since the block was created. **/ void xmemchk(void) { uint32_t last_key; chk_header *ch; int i; if (naddr > MAX_ADDRS) { fprintf(stderr, "ERROR: Too many addresses for xmemchk()!\n"); abort(); } last_key = 0; for (i = 0; i < naddr; i++) { /* Check for table corruption */ if (mem_item[i].key < last_key) { fprintf(stderr, "Memory table keys out of order - fatal error"); abort(); } last_key = mem_item[i].key; if (mem_item[i].addr == NULL) { fprintf(stderr, "Memory table entry reference null block - fatal error"); abort(); } if (mem_item[i].filen == NULL) { fprintf(stderr, "Memory table filename missing - fatal error"); abort(); } if ((size_t) strlen(mem_item[i].filen) != mem_item[i].length) { fprintf(stderr, "Memory table filename length corrupted - fatal error"); abort(); } /* Check memory */ ch = mem_item[i].addr; if (chk_header_okay(ch) == FALSE) { /* Chk header display which side has gone awry */ fprintf(stderr, "Memory check failed!\n"); fprintf(stderr, "addr: %p", mem_item[i].addr); fprintf(stderr, " size: %6d", ch->size); fprintf(stderr, " age: %6d", tick - mem_item[i].est); fprintf(stderr, " file: %s", mem_item[i].filen); fprintf(stderr, " line: %d", mem_item[i].line); fprintf(stderr, "\n"); abort(); } } } static int alloc_blk_cmp_origin(const void *vab1, const void *vab2) { const alloc_blk *ab1, *ab2; int sc; ab1 = (const alloc_blk*)vab1; ab2 = (const alloc_blk*)vab2; if (ab1->filen == NULL || ab2->filen == NULL) { if (ab1->filen == NULL && ab2->filen == NULL) { return 0; } else if (ab1->filen == NULL) { return +1; } else /* (ab2->filen == NULL)*/ { return -1; } } sc = strcmp(ab1->filen, ab2->filen); if (sc == 0) { if (ab1->line > ab2->line) { return +1; } else if (ab1->line == ab2->line) { return 0; } else /* (ab1->line < ab2->line) */{ return -1; } } return sc; } static int alloc_blk_cmp_est(const void *vab1, const void *vab2) { const alloc_blk *ab1, *ab2; ab1 = (const alloc_blk*)vab1; ab2 = (const alloc_blk*)vab2; if (ab1->est > ab2->est) { return +1; } else if (ab1->est == ab2->est) { return 0; } else { return -1; } } /** * xmemdmp: * @void: * * Dumps the address, size, age, and point of allocation in code. * **/ void xmemdmp(void) { int i; block_release_all(); if (naddr > MAX_ADDRS) { printf("ERROR: Too many addresses for xmemdmp()!\n"); abort(); } qsort(mem_item, naddr, sizeof(mem_item[0]), alloc_blk_cmp_est); for (i=0; isize); fflush(stdout); printf(" age: %6d", tick - mem_item[i].est); fflush(stdout); printf(" file: %s", mem_item[i].filen); fflush(stdout); printf(":%d", mem_item[i].line); fflush(stdout); if (mem_item[i].blen != 0) { printf(" \tblen %d", mem_item[i].blen); fflush(stdout); } printf("\n"); } printf("Program initialisation finished at age %6d\n", tick-init); qsort(mem_item, naddr, sizeof(mem_item[0]), mem_key_cmp); } /* Because block_alloc recycles blocks we need to know which code * fragment takes over responsibility for the memory. */ /** * xclaim: * @addr: address * @filen: new filename * @line: new allocation line * * Coerces information in allocation table about allocation file and * line to be @filen and @line. This is used by the evil * block_alloc() and should probably not be used anywhere else ever. **/ void xclaim(void *addr, const char *filen, int line) { alloc_blk *m; chk_header *ch; ch = ((chk_header *)addr) - 1; m = mem_item_find(ch->key); if (chk_header_okay(ch) == FALSE) { fprintf(stderr, "xclaim: memory corrupted\n"); abort(); } if (m == NULL) { fprintf(stderr, "xclaim: block not found\n"); abort(); } free(m->filen); m->filen = strdup(filen); m->length = strlen(filen); m->line = line; m->est = tick++; } /** * xmemdist: * @fp: file pointer * * Dumps information on existing memory allocations to file. **/ void xmemdist(FILE *fp) { int i, last_line=-1, cnt=0, entry=0; char *last_filen = NULL; /* This is painful...I don't actually envisage running beyond this dump :-) * 2 sorts are needed, one into order by file, and then back to key order. */ qsort(mem_item, naddr, sizeof(mem_item[0]), alloc_blk_cmp_origin); fprintf(fp, "# Distribution of memory allocated\n# \n"); for(i = 0; i < naddr; i++) { if (last_filen == NULL || last_line != mem_item[i].line || strcmp(last_filen, mem_item[i].filen)) { if (last_filen != NULL) { fprintf(fp, "% 3d\n", cnt); } cnt = 0; last_filen = mem_item[i].filen; last_line = mem_item[i].line; fprintf(fp, "% 3d %20s % 4d ", entry, last_filen, last_line); entry++; } cnt++; } fprintf(fp, "% 3d\n", cnt); /* Restore order */ qsort(mem_item, naddr, sizeof(mem_item[0]), mem_key_cmp); } /** * xfree: * @p: pointer to block to freed. * * Free block of memory. Semantically equivalent to free(), but * checks for bounds overruns in @p and tidies up state associated * additional functionality. * * Must be used to free memory allocated with xmalloc(), xrealloc(), * and xstrdup(). **/ void xfree(void *p) { alloc_blk *m; chk_header *ch; uint32_t size, delta, magic, idx; if (p == NULL) { printf("ERROR: Attempt to free NULL pointer!\n"); abort(); } ch = ((chk_header*)p) - 1; /* Validate entry */ if (chk_header_okay(ch) == FALSE) { printf("ERROR: Freeing corrupted block\n"); abort(); } /* Locate in table */ m = mem_item_find(ch->key); if (m == NULL) { printf("ERROR: Freeing unallocated or already free'd block\n"); abort(); } /* Trash memory of allocated block, maybe noticed by apps when * deref'ing free'd */ size = ch->size + sizeof(chk_header) + MAGIC_MEMORY_SIZE; magic = MAGIC_MEMORY; p = (uint8_t*)ch; while (size > 0) { delta = min(size, 4); memcpy(p, &magic, delta); (uint8_t*)p += delta; size -= delta; } /* Free memory */ free(ch); free(m->filen); /* Remove from table */ idx = m - mem_item; if (naddr - idx > 0) { memmove(&mem_item[idx], &mem_item[idx + 1], (naddr - idx - 1) * sizeof(alloc_blk)); } naddr--; xmemchk(); } void * _xmalloc(unsigned size, const char *filen, int line) { uint32_t *data; void *p; chk_header *ch; p = (void*) malloc (size + sizeof(chk_header) + MAGIC_MEMORY_SIZE); assert(p != NULL); assert(filen != NULL); /* Fix block header */ ch = (chk_header*)p; ch->key = tick++; ch->size = size; ch->magic = MAGIC_MEMORY; data = (uint32_t*)((chk_header *)p + 1); memset((void*)data, 0xf0, size); /* Fix block tail */ memcpy(((uint8_t*)data) + size, &ch->magic, MAGIC_MEMORY_SIZE); /* Check set up okay */ if (chk_header_okay(ch) == FALSE) { fprintf(stderr, "Implementation Error\n"); abort(); } /* Add table entry */ mem_item[naddr].key = ch->key; mem_item[naddr].addr = p; mem_item[naddr].filen = (char *)strdup(filen); mem_item[naddr].line = line; mem_item[naddr].length = strlen(filen); mem_item[naddr].blen = 0; /* block_alloc'ed len when appropriate */ mem_item[naddr].est = ch->key; /* changes when block_alloc recycles block */ naddr ++; if (naddr >= MAX_ADDRS) { fprintf(stderr, "ERROR: Allocated too much! Table overflow in xmalloc()\n"); fprintf(stderr, " Do you really need to allocate more than %d items?\n", MAX_ADDRS); abort(); } if (chk_header_okay(ch) == FALSE) { fprintf(stderr, "Implementation Error\n"); abort(); } return (uint8_t*)p + sizeof(chk_header); } void * _xrealloc(void *p, unsigned size, const char *filen, int line) { alloc_blk *m; chk_header *ch; uint8_t *t; assert(p != NULL); assert(filen != NULL); ch = ((chk_header*) p) - 1; m = mem_item_find(ch->key); if (m != NULL) { /* Attempt reallocation */ m->addr = realloc((void*)ch, size + sizeof(chk_header) + MAGIC_MEMORY_SIZE); if (m->addr == NULL) { debug_msg("realloc failed\n"); return NULL; } /* update ch/p */ ch = (chk_header*)m->addr; p = (void*)(ch+1); /* Update table */ free(m->filen); m->filen = (char *) strdup(filen); m->line = line; m->length = strlen(filen); m->est = tick++; /* Fix chunk header */ ch->size = size; /* Fix trailer */ t = (uint8_t*)p + size; memcpy(t, &ch->magic, MAGIC_MEMORY_SIZE); /* Check block is okay */ if (chk_header_okay(ch) == FALSE) { fprintf(stderr, "Implementation Error\n"); abort(); } return p; } debug_msg("Trying to xrealloc() memory not which is not allocated\n"); abort(); return 0; } char *_xstrdup(const char *s1, const char *filen, int line) { char *s2; s2 = (char *) _xmalloc(strlen(s1)+1, filen, line); if (s2 != NULL) { strcpy(s2, s1); } return (s2); } #else void xdoneinit (void) { return; } void xmemchk (void) { return; } void xmemdmp (void) { return; } void xclaim (void *p, const char *filen, int line) { UNUSED(p); UNUSED(filen); UNUSED(line); return; } void xmemdist (FILE *f) { UNUSED(f); } void xfree (void *x) { free(x); } void *_xmalloc(unsigned int size, const char *filen, int line) { void *m; m = malloc(size); #ifdef DEBUG /* This is just to check initialization errors in allocated structs */ memset(m, 0xf0, size); #endif UNUSED(filen); UNUSED(line); return m; } void *_xrealloc(void *p, unsigned int size,const char *filen,int line) { UNUSED(filen); UNUSED(line); return realloc(p, size); } char *_xstrdup(const char *s1, const char *filen, int line) { UNUSED(filen); UNUSED(line); return strdup(s1); } #endif /* DEBUG_MEM */ uclmmbase-1.2.16.0/src/memory.h0000640000175000017500000000535607261724507015152 0ustar enderender/* * FILE: memory.h * PROGRAM: RAT * AUTHOR: Isidor Kouvelas + Colin Perkins + Orion Hodson * * $Revision: 1.7 $ * $Date: 2001/04/01 22:18:47 $ * * Copyright (c) 1995-2000 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Science * Department at University College London * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ #ifndef _RAT_MEMORY_H #define _RAT_MEMORY_H #define xmalloc(x) _xmalloc(x,__FILE__,__LINE__) #define xrealloc(p,x) _xrealloc(p, x,__FILE__,__LINE__) #define xstrdup(str) _xstrdup(str,__FILE__,__LINE__) #if defined(__cplusplus) extern "C" { #endif /* Debug Functions */ void xdoneinit(void); void xmemchk(void); void xmemdmp(void); void xclaim(void *addr, const char *filen, int line); void xmemdist(FILE *fp); /* Replacements for regular memory fn's */ void xfree(void *p); void *_xmalloc(unsigned size,const char *filen,int line); void *_xrealloc(void *p,unsigned size,const char *filen,int line); char *_xstrdup(const char *s1, const char *filen, int line); void *_block_alloc(unsigned size, const char *filen, int line); void _block_free(void *p, int size, int line); #if defined(__cplusplus) } #endif #endif uclmmbase-1.2.16.0/src/net_udp.c0000640000175000017500000006215407734574700015275 0ustar enderender/* * FILE: net_udp.c * AUTHOR: Colin Perkins * MODIFIED: Orion Hodson, Piers O'Hanlon, Kristian Hasler * * Copyright (c) 1998-2000 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Science * Department at University College London * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ /* If this machine supports IPv6 the symbol HAVE_IPv6 should */ /* be defined in either config_unix.h or config_win32.h. The */ /* appropriate system header files should also be included */ /* by those files. */ #include "config_unix.h" #include "config_win32.h" #include "debug.h" #include "memory.h" #include "inet_pton.h" #include "inet_ntop.h" #include "vsnprintf.h" #include "net_udp.h" #ifdef NEED_ADDRINFO_H #include "addrinfo.h" #endif #define IPv4 4 #define IPv6 6 #ifdef WIN2K_IPV6 const struct in6_addr in6addr_any = {IN6ADDR_ANY_INIT}; #endif #ifdef WINXP_IPV6 const struct in6_addr in6addr_any = {IN6ADDR_ANY_INIT}; #endif /* This is pretty nasty but it's the simplest way to get round */ /* the Detexis bug that means their MUSICA IPv6 stack uses */ /* IPPROTO_IP instead of IPPROTO_IPV6 in setsockopt calls */ /* We also need to define in6addr_any */ #ifdef MUSICA_IPV6 #define IPPROTO_IPV6 IPPROTO_IP struct in6_addr in6addr_any = {IN6ADDR_ANY_INIT}; /* These DEF's are required as MUSICA's winsock6.h causes a clash with some of the * standard ws2tcpip.h definitions (eg struct in_addr6). * Note: winsock6.h defines AF_INET6 as 24 NOT 23 as in winsock2.h - I have left it * set to the MUSICA value as this is used in some of their function calls. */ //#define AF_INET6 23 #define IP_MULTICAST_LOOP 11 /*set/get IP multicast loopback */ #define IP_MULTICAST_IF 9 /* set/get IP multicast i/f */ #define IP_MULTICAST_TTL 10 /* set/get IP multicast ttl */ #define IP_MULTICAST_LOOP 11 /*set/get IP multicast loopback */ #define IP_ADD_MEMBERSHIP 12 /* add an IP group membership */ #define IP_DROP_MEMBERSHIP 13/* drop an IP group membership */ #define IN6_IS_ADDR_UNSPECIFIED(a) (((a)->s6_addr32[0] == 0) && \ ((a)->s6_addr32[1] == 0) && \ ((a)->s6_addr32[2] == 0) && \ ((a)->s6_addr32[3] == 0)) struct ip_mreq { struct in_addr imr_multiaddr; /* IP multicast address of group */ struct in_addr imr_interface; /* local IP address of interface */ }; #endif #ifndef INADDR_NONE #define INADDR_NONE 0xffffffff #endif struct _socket_udp { int mode; /* IPv4 or IPv6 */ char *addr; uint16_t rx_port; uint16_t tx_port; ttl_t ttl; fd_t fd; struct in_addr addr4; #ifdef HAVE_IPv6 struct in6_addr addr6; #endif /* HAVE_IPv6 */ }; #ifdef WIN32 /* Want to use both Winsock 1 and 2 socket options, but since * IPv6 support requires Winsock 2 we have to add own backwards * compatibility for Winsock 1. */ #define SETSOCKOPT winsock_versions_setsockopt #else #define SETSOCKOPT setsockopt #endif /* WIN32 */ /*****************************************************************************/ /* Support functions... */ /*****************************************************************************/ static void socket_error(const char *msg, ...) { char buffer[255]; uint32_t blen = sizeof(buffer) / sizeof(buffer[0]); va_list ap; #ifdef WIN32 #define WSERR(x) {#x,x} struct wse { char errname[20]; int my_errno; }; struct wse ws_errs[] = { WSERR(WSANOTINITIALISED), WSERR(WSAENETDOWN), WSERR(WSAEACCES), WSERR(WSAEINVAL), WSERR(WSAEINTR), WSERR(WSAEINPROGRESS), WSERR(WSAEFAULT), WSERR(WSAENETRESET), WSERR(WSAENOBUFS), WSERR(WSAENOTCONN), WSERR(WSAENOTSOCK), WSERR(WSAEOPNOTSUPP), WSERR(WSAESHUTDOWN), WSERR(WSAEWOULDBLOCK), WSERR(WSAEMSGSIZE), WSERR(WSAEHOSTUNREACH), WSERR(WSAECONNABORTED), WSERR(WSAECONNRESET), WSERR(WSAEADDRNOTAVAIL), WSERR(WSAEAFNOSUPPORT), WSERR(WSAEDESTADDRREQ), WSERR(WSAENETUNREACH), WSERR(WSAETIMEDOUT), WSERR(0) }; int i, e = WSAGetLastError(); i = 0; while(ws_errs[i].my_errno && ws_errs[i].my_errno != e) { i++; } va_start(ap, msg); _vsnprintf(buffer, blen, msg, ap); va_end(ap); printf("ERROR: %s, (%d - %s)\n", msg, e, ws_errs[i].errname); #else va_start(ap, msg); vsnprintf(buffer, blen, msg, ap); va_end(ap); perror(buffer); #endif } #ifdef WIN32 /* ws2tcpip.h defines these constants with different values from * winsock.h so files that use winsock 2 values but try to use * winsock 1 fail. So what was the motivation in changing the * constants ? */ #define WS1_IP_MULTICAST_IF 2 /* set/get IP multicast interface */ #define WS1_IP_MULTICAST_TTL 3 /* set/get IP multicast timetolive */ #define WS1_IP_MULTICAST_LOOP 4 /* set/get IP multicast loopback */ #define WS1_IP_ADD_MEMBERSHIP 5 /* add an IP group membership */ #define WS1_IP_DROP_MEMBERSHIP 6 /* drop an IP group membership */ /* winsock_versions_setsockopt tries 1 winsock version of option * optname and then winsock 2 version if that failed. * note: setting the TTL never fails, so we have to try both. */ static int winsock_versions_setsockopt(SOCKET s, int level, int optname, const char FAR * optval, int optlen) { int success = -1; switch (optname) { case IP_MULTICAST_IF: success = setsockopt(s, level, WS1_IP_MULTICAST_IF, optval, optlen); break; case IP_MULTICAST_TTL: success = setsockopt(s, level, WS1_IP_MULTICAST_TTL, optval, optlen); success = setsockopt(s, level, optname, optval, optlen); break; case IP_MULTICAST_LOOP: success = setsockopt(s, level, WS1_IP_MULTICAST_LOOP, optval, optlen); break; case IP_ADD_MEMBERSHIP: success = setsockopt(s, level, WS1_IP_ADD_MEMBERSHIP, optval, optlen); break; case IP_DROP_MEMBERSHIP: success = setsockopt(s, level, WS1_IP_DROP_MEMBERSHIP, optval, optlen); break; } if (success != -1) { return success; } return setsockopt(s, level, optname, optval, optlen); } #endif #ifdef NEED_INET_ATON #ifdef NEED_INET_ATON_STATIC static #endif int inet_aton(const char *name, struct in_addr *addr) { addr->s_addr = inet_addr(name); return (addr->s_addr != (in_addr_t) INADDR_NONE); } #endif #ifdef NEED_IN6_IS_ADDR_MULTICAST #define IN6_IS_ADDR_MULTICAST(addr) ((addr)->s6_addr[0] == 0xffU) #endif #if defined(NEED_IN6_IS_ADDR_UNSPECIFIED) && defined(MUSICA_IPV6) #define IN6_IS_ADDR_UNSPECIFIED(addr) IS_UNSPEC_IN6_ADDR(*addr) #endif /*****************************************************************************/ /* IPv4 specific functions... */ /*****************************************************************************/ static int udp_addr_valid4(const char *dst) { struct in_addr addr4; struct hostent *h; if (inet_pton(AF_INET, dst, &addr4)) { return TRUE; } h = gethostbyname(dst); if (h != NULL) { return TRUE; } socket_error("Can't resolve IP address for %s", dst); return FALSE; } static socket_udp *udp_init4(const char *addr, const char *iface, uint16_t rx_port, uint16_t tx_port, int ttl) { int reuse = 1, udpbufsize=1048576; struct sockaddr_in s_in; struct in_addr iface_addr; #ifdef WIN32 int recv_buf_size = 65536; #endif socket_udp *s = (socket_udp *)malloc(sizeof(socket_udp)); s->mode = IPv4; s->addr = NULL; s->rx_port = rx_port; s->tx_port = tx_port; s->ttl = ttl; if (inet_pton(AF_INET, addr, &s->addr4) != 1) { struct hostent *h = gethostbyname(addr); if (h == NULL) { socket_error("Can't resolve IP address for %s", addr); free(s); return NULL; } memcpy(&(s->addr4), h->h_addr_list[0], sizeof(s->addr4)); } if (iface != NULL) { if (inet_pton(AF_INET, iface, &iface_addr) != 1) { debug_msg("Illegal interface specification\n"); free(s); return NULL; } } else { iface_addr.s_addr = 0; } s->fd = socket(AF_INET, SOCK_DGRAM, 0); if (s->fd < 0) { socket_error("socket"); if (SETSOCKOPT(s->fd, SOL_SOCKET, SO_SNDBUF, (char *) &udpbufsize, sizeof(udpbufsize)) != 0) { socket_error("setsockopt SO_SNDBUF"); return NULL; } if (SETSOCKOPT(s->fd, SOL_SOCKET, SO_RCVBUF, (char *) &udpbufsize, sizeof(udpbufsize)) != 0) { socket_error("setsockopt SO_RCVBUF"); return NULL; } return NULL; } if (SETSOCKOPT(s->fd, SOL_SOCKET, SO_REUSEADDR, (char *) &reuse, sizeof(reuse)) != 0) { socket_error("setsockopt SO_REUSEADDR"); return NULL; } #ifdef SO_REUSEPORT if (SETSOCKOPT(s->fd, SOL_SOCKET, SO_REUSEPORT, (char *) &reuse, sizeof(reuse)) != 0) { socket_error("setsockopt SO_REUSEPORT"); return NULL; } #endif s_in.sin_family = AF_INET; s_in.sin_addr.s_addr = INADDR_ANY; s_in.sin_port = htons(rx_port); if (bind(s->fd, (struct sockaddr *) &s_in, sizeof(s_in)) != 0) { socket_error("bind"); return NULL; } if (IN_MULTICAST(ntohl(s->addr4.s_addr))) { char loop = 1; struct ip_mreq imr; imr.imr_multiaddr.s_addr = s->addr4.s_addr; imr.imr_interface.s_addr = iface_addr.s_addr; if (SETSOCKOPT(s->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &imr, sizeof(struct ip_mreq)) != 0) { socket_error("setsockopt IP_ADD_MEMBERSHIP"); return NULL; } #ifndef WIN32 if (SETSOCKOPT(s->fd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop)) != 0) { socket_error("setsockopt IP_MULTICAST_LOOP"); return NULL; } #endif if (SETSOCKOPT(s->fd, IPPROTO_IP, IP_MULTICAST_TTL, (char *) &s->ttl, sizeof(s->ttl)) != 0) { socket_error("setsockopt IP_MULTICAST_TTL"); return NULL; } if (iface_addr.s_addr != 0) { if (SETSOCKOPT(s->fd, IPPROTO_IP, IP_MULTICAST_IF, (char *) &iface_addr, sizeof(iface_addr)) != 0) { socket_error("setsockopt IP_MULTICAST_IF"); return NULL; } } } s->addr = strdup(addr); return s; } static void udp_exit4(socket_udp *s) { if (IN_MULTICAST(ntohl(s->addr4.s_addr))) { struct ip_mreq imr; imr.imr_multiaddr.s_addr = s->addr4.s_addr; imr.imr_interface.s_addr = INADDR_ANY; if (SETSOCKOPT(s->fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char *) &imr, sizeof(struct ip_mreq)) != 0) { socket_error("setsockopt IP_DROP_MEMBERSHIP"); abort(); } debug_msg("Dropped membership of multicast group\n"); } close(s->fd); free(s->addr); free(s); } static inline int udp_send4(socket_udp *s, char *buffer, int buflen) { struct sockaddr_in s_in; assert(s != NULL); assert(s->mode == IPv4); assert(buffer != NULL); assert(buflen > 0); s_in.sin_family = AF_INET; s_in.sin_addr.s_addr = s->addr4.s_addr; s_in.sin_port = htons(s->tx_port); return sendto(s->fd, buffer, buflen, 0, (struct sockaddr *) &s_in, sizeof(s_in)); } #ifndef WIN32 static inline int udp_sendv4(socket_udp *s, struct iovec *vector, int count) { struct msghdr msg; struct sockaddr_in s_in; assert(s != NULL); assert(s->mode == IPv4); s_in.sin_family = AF_INET; s_in.sin_addr.s_addr = s->addr4.s_addr; s_in.sin_port = htons(s->tx_port); msg.msg_name = &s_in; msg.msg_namelen = sizeof(s_in); msg.msg_iov = vector; msg.msg_iovlen = count; #ifdef NDEF /* Solaris does something different here... can we just ignore these fields? [csp] */ msg.msg_control = 0; msg.msg_controllen = 0; msg.msg_flags = 0; #endif return sendmsg(s->fd, &msg, 0); } #endif static const char *udp_host_addr4(void) { static char hname[MAXHOSTNAMELEN]; struct hostent *hent; struct in_addr iaddr; if (gethostname(hname, MAXHOSTNAMELEN) != 0) { debug_msg("Cannot get hostname!"); abort(); } hent = gethostbyname(hname); if (hent == NULL) { socket_error("Can't resolve IP address for %s", hname); return NULL; } assert(hent->h_addrtype == AF_INET); memcpy(&iaddr.s_addr, hent->h_addr, sizeof(iaddr.s_addr)); strncpy(hname, inet_ntoa(iaddr), MAXHOSTNAMELEN); return (const char*)hname; } /*****************************************************************************/ /* IPv6 specific functions... */ /*****************************************************************************/ static int udp_addr_valid6(const char *dst) { #ifdef HAVE_IPv6 struct in6_addr addr6; switch (inet_pton(AF_INET6, dst, &addr6)) { case 1: return TRUE; break; case 0: return FALSE; break; case -1: debug_msg("inet_pton failed\n"); errno = 0; } #endif /* HAVE_IPv6 */ UNUSED(dst); return FALSE; } static socket_udp *udp_init6(const char *addr, const char *iface, uint16_t rx_port, uint16_t tx_port, int ttl) { #ifdef HAVE_IPv6 int reuse = 1; struct sockaddr_in6 s_in; socket_udp *s = (socket_udp *) malloc(sizeof(socket_udp)); s->mode = IPv6; s->addr = NULL; s->rx_port = rx_port; s->tx_port = tx_port; s->ttl = ttl; if (iface != NULL) { debug_msg("Not yet implemented\n"); abort(); } if (inet_pton(AF_INET6, addr, &s->addr6) != 1) { /* We should probably try to do a DNS lookup on the name */ /* here, but I'm trying to get the basics going first... */ debug_msg("IPv6 address conversion failed\n"); free(s); return NULL; } s->fd = socket(AF_INET6, SOCK_DGRAM, 0); if (s->fd < 0) { socket_error("socket"); return NULL; } if (SETSOCKOPT(s->fd, SOL_SOCKET, SO_REUSEADDR, (char *) &reuse, sizeof(reuse)) != 0) { socket_error("setsockopt SO_REUSEADDR"); return NULL; } #ifdef SO_REUSEPORT if (SETSOCKOPT(s->fd, SOL_SOCKET, SO_REUSEPORT, (char *) &reuse, sizeof(reuse)) != 0) { socket_error("setsockopt SO_REUSEPORT"); return NULL; } #endif memset((char *)&s_in, 0, sizeof(s_in)); s_in.sin6_family = AF_INET6; s_in.sin6_port = htons(rx_port); #ifdef HAVE_SIN6_LEN s_in.sin6_len = sizeof(s_in); #endif s_in.sin6_addr = in6addr_any; if (bind(s->fd, (struct sockaddr *) &s_in, sizeof(s_in)) != 0) { socket_error("bind"); return NULL; } if (IN6_IS_ADDR_MULTICAST(&(s->addr6))) { unsigned int loop = 1; struct ipv6_mreq imr; #ifdef MUSICA_IPV6 imr.i6mr_interface = 1; imr.i6mr_multiaddr = s->addr6; #else imr.ipv6mr_multiaddr = s->addr6; imr.ipv6mr_interface = 0; #endif if (SETSOCKOPT(s->fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (char *) &imr, sizeof(imr)) != 0) { socket_error("setsockopt IPV6_ADD_MEMBERSHIP"); return NULL; } if (SETSOCKOPT(s->fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (char *) &loop, sizeof(loop)) != 0) { socket_error("setsockopt IPV6_MULTICAST_LOOP"); return NULL; } if (SETSOCKOPT(s->fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *) &ttl, sizeof(ttl)) != 0) { socket_error("setsockopt IPV6_MULTICAST_HOPS"); return NULL; } } assert(s != NULL); s->addr = strdup(addr); return s; #else UNUSED(addr); UNUSED(iface); UNUSED(rx_port); UNUSED(tx_port); UNUSED(ttl); return NULL; #endif } static void udp_exit6(socket_udp *s) { #ifdef HAVE_IPv6 if (IN6_IS_ADDR_MULTICAST(&(s->addr6))) { struct ipv6_mreq imr; #ifdef MUSICA_IPV6 imr.i6mr_interface = 1; imr.i6mr_multiaddr = s->addr6; #else imr.ipv6mr_multiaddr = s->addr6; imr.ipv6mr_interface = 0; #endif if (SETSOCKOPT(s->fd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, (char *) &imr, sizeof(struct ipv6_mreq)) != 0) { socket_error("setsockopt IPV6_DROP_MEMBERSHIP"); abort(); } } close(s->fd); free(s->addr); free(s); #else UNUSED(s); #endif /* HAVE_IPv6 */ } static int udp_send6(socket_udp *s, char *buffer, int buflen) { #ifdef HAVE_IPv6 struct sockaddr_in6 s_in; assert(s != NULL); assert(s->mode == IPv6); assert(buffer != NULL); assert(buflen > 0); memset((char *)&s_in, 0, sizeof(s_in)); s_in.sin6_family = AF_INET6; s_in.sin6_addr = s->addr6; s_in.sin6_port = htons(s->tx_port); #ifdef HAVE_SIN6_LEN s_in.sin6_len = sizeof(s_in); #endif return sendto(s->fd, buffer, buflen, 0, (struct sockaddr *) &s_in, sizeof(s_in)); #else UNUSED(s); UNUSED(buffer); UNUSED(buflen); return -1; #endif } #ifndef WIN32 static int udp_sendv6(socket_udp *s, struct iovec *vector, int count) { #ifdef HAVE_IPv6 struct msghdr msg; struct sockaddr_in6 s_in; assert(s != NULL); assert(s->mode == IPv6); memset((char *)&s_in, 0, sizeof(s_in)); s_in.sin6_family = AF_INET6; s_in.sin6_addr = s->addr6; s_in.sin6_port = htons(s->tx_port); #ifdef HAVE_SIN6_LEN s_in.sin6_len = sizeof(s_in); #endif msg.msg_name = &s_in; msg.msg_namelen = sizeof(s_in); msg.msg_iov = vector; msg.msg_iovlen = count; #ifdef HAVE_MSGHDR_MSGCTRL msg.msg_control = 0; msg.msg_controllen = 0; msg.msg_flags = 0; #endif return sendmsg(s->fd, &msg, 0); #else UNUSED(s); UNUSED(vector); UNUSED(count); return -1; #endif } #endif static const char *udp_host_addr6(socket_udp *s) { #ifdef HAVE_IPv6 static char hname[MAXHOSTNAMELEN]; int gai_err, newsock; struct addrinfo hints, *ai; struct sockaddr_in6 local, addr6; int len = sizeof(local), result = 0; newsock=socket(AF_INET6, SOCK_DGRAM,0); memset ((char *)&addr6, 0, len); addr6.sin6_family = AF_INET6; #ifdef HAVE_SIN6_LEN addr6.sin6_len = len; #endif bind (newsock, (struct sockaddr *) &addr6, len); addr6.sin6_addr = s->addr6; addr6.sin6_port = htons (s->rx_port); connect (newsock, (struct sockaddr *) &addr6, len); memset ((char *)&local, 0, len); if ((result = getsockname(newsock,(struct sockaddr *)&local, &len)) < 0){ local.sin6_addr = in6addr_any; local.sin6_port = 0; debug_msg("getsockname failed\n"); } close (newsock); if (IN6_IS_ADDR_UNSPECIFIED(&local.sin6_addr) || IN6_IS_ADDR_MULTICAST(&local.sin6_addr)) { if (gethostname(hname, MAXHOSTNAMELEN) != 0) { debug_msg("gethostname failed\n"); abort(); } hints.ai_protocol = 0; hints.ai_flags = 0; hints.ai_family = AF_INET6; hints.ai_socktype = SOCK_DGRAM; hints.ai_addrlen = 0; hints.ai_canonname = NULL; hints.ai_addr = NULL; hints.ai_next = NULL; if ((gai_err = getaddrinfo(hname, NULL, &hints, &ai))) { debug_msg("getaddrinfo: %s: %s\n", hname, gai_strerror(gai_err)); abort(); } if (inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)(ai->ai_addr))->sin6_addr), hname, MAXHOSTNAMELEN) == NULL) { debug_msg("inet_ntop: %s: \n", hname); abort(); } freeaddrinfo(ai); return (const char*)hname; } if (inet_ntop(AF_INET6, &local.sin6_addr, hname, MAXHOSTNAMELEN) == NULL) { debug_msg("inet_ntop: %s: \n", hname); abort(); } return (const char*)hname; #else /* HAVE_IPv6 */ UNUSED(s); return "::"; /* The unspecified address... */ #endif /* HAVE_IPv6 */ } /*****************************************************************************/ /* Generic functions, which call the appropriate protocol specific routines. */ /*****************************************************************************/ /** * udp_addr_valid: * @addr: string representation of IPv4 or IPv6 network address. * * Returns TRUE if @addr is valid, FALSE otherwise. **/ int udp_addr_valid(const char *addr) { return udp_addr_valid4(addr) | udp_addr_valid6(addr); } /** * udp_init: * @addr: character string containing an IPv4 or IPv6 network address. * @rx_port: receive port. * @tx_port: transmit port. * @ttl: time-to-live value for transmitted packets. * * Creates a session for sending and receiving UDP datagrams over IP * networks. * * Returns: a pointer to a valid socket_udp structure on success, NULL otherwise. **/ socket_udp *udp_init(const char *addr, uint16_t rx_port, uint16_t tx_port, int ttl) { return udp_init_if(addr, NULL, rx_port, tx_port, ttl); } /** * udp_init_if: * @addr: character string containing an IPv4 or IPv6 network address. * @iface: character string containing an interface name. * @rx_port: receive port. * @tx_port: transmit port. * @ttl: time-to-live value for transmitted packets. * * Creates a session for sending and receiving UDP datagrams over IP * networks. The session uses @iface as the interface to send and * receive datagrams on. * * Return value: a pointer to a socket_udp structure on success, NULL otherwise. **/ socket_udp *udp_init_if(const char *addr, const char *iface, uint16_t rx_port, uint16_t tx_port, int ttl) { socket_udp *res; if (strchr(addr, ':') == NULL) { res = udp_init4(addr, iface, rx_port, tx_port, ttl); } else { res = udp_init6(addr, iface, rx_port, tx_port, ttl); } return res; } /** * udp_exit: * @s: UDP session to be terminated. * * Closes UDP session. * **/ void udp_exit(socket_udp *s) { switch(s->mode) { case IPv4 : udp_exit4(s); break; case IPv6 : udp_exit6(s); break; default : abort(); } } /** * udp_send: * @s: UDP session. * @buffer: pointer to buffer to be transmitted. * @buflen: length of @buffer. * * Transmits a UDP datagram containing data from @buffer. * * Return value: 0 on success, -1 on failure. **/ int udp_send(socket_udp *s, char *buffer, int buflen) { switch (s->mode) { case IPv4 : return udp_send4(s, buffer, buflen); case IPv6 : return udp_send6(s, buffer, buflen); default : abort(); /* Yuk! */ } return -1; } #ifndef WIN32 int udp_sendv(socket_udp *s, struct iovec *vector, int count) { switch (s->mode) { case IPv4 : return udp_sendv4(s, vector, count); case IPv6 : return udp_sendv6(s, vector, count); default : abort(); /* Yuk! */ } return -1; } #endif /** * udp_recv: * @s: UDP session. * @buffer: buffer to read data into. * @buflen: length of @buffer. * * Reads from datagram queue associated with UDP session. * * Return value: number of bytes read, returns 0 if no data is available. **/ int udp_recv(socket_udp *s, char *buffer, int buflen) { /* Reads data into the buffer, returning the number of bytes read. */ /* If no data is available, this returns the value zero immediately. */ /* Note: since we don't care about the source address of the packet */ /* we receive, this function becomes protocol independent. */ int len; assert(buffer != NULL); assert(buflen > 0); len = recvfrom(s->fd, buffer, buflen, 0, 0, 0); if (len > 0) { return len; } if (errno != ECONNREFUSED) { socket_error("recvfrom"); } return 0; } static fd_set rfd; static fd_t max_fd; /** * udp_fd_zero: * * Clears file descriptor from set associated with UDP sessions (see select(2)). * **/ void udp_fd_zero(void) { FD_ZERO(&rfd); max_fd = 0; } /** * udp_fd_set: * @s: UDP session. * * Adds file descriptor associated of @s to set associated with UDP sessions. **/ void udp_fd_set(socket_udp *s) { FD_SET(s->fd, &rfd); if (s->fd > (fd_t)max_fd) { max_fd = s->fd; } } /** * udp_fd_isset: * @s: UDP session. * * Checks if file descriptor associated with UDP session is ready for * reading. This function should be called after udp_select(). * * Returns: non-zero if set, zero otherwise. **/ int udp_fd_isset(socket_udp *s) { return FD_ISSET(s->fd, &rfd); } /** * udp_select: * @timeout: maximum period to wait for data to arrive. * * Waits for data to arrive for UDP sessions. * * Return value: number of UDP sessions ready for reading. **/ int udp_select(struct timeval *timeout) { return select(max_fd + 1, &rfd, NULL, NULL, timeout); } /** * udp_host_addr: * @s: UDP session. * * Return value: character string containing network address * associated with session @s. **/ const char *udp_host_addr(socket_udp *s) { switch (s->mode) { case IPv4 : return udp_host_addr4(); case IPv6 : return udp_host_addr6(s); default : abort(); } return NULL; } /** * udp_fd: * @s: UDP session. * * This function allows applications to apply their own socketopt()'s * and ioctl()'s to the UDP session. * * Return value: file descriptor of socket used by session @s. **/ int udp_fd(socket_udp *s) { if (s && s->fd > 0) { return s->fd; } return 0; } uclmmbase-1.2.16.0/src/net_udp.h0000640000175000017500000000530307500153640015256 0ustar enderender/* * FILE: net_udp.h * AUTHORS: Colin Perkins * * Copyright (c) 1998-2000 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Science * Department at University College London * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ #ifndef _NET_UDP #define _NET_UDP typedef struct _socket_udp socket_udp; #if defined(__cplusplus) extern "C" { #endif int udp_addr_valid(const char *addr); socket_udp *udp_init(const char *addr, uint16_t rx_port, uint16_t tx_port, int ttl); socket_udp *udp_init_if(const char *addr, const char *iface, uint16_t rx_port, uint16_t tx_port, int ttl); void udp_exit(socket_udp *s); int udp_recv(socket_udp *s, char *buffer, int buflen); int udp_send(socket_udp *s, char *buffer, int buflen); #ifndef WIN32 int udp_sendv(socket_udp *s, struct iovec *vector, int count); #endif const char *udp_host_addr(socket_udp *s); int udp_fd(socket_udp *s); int udp_select(struct timeval *timeout); void udp_fd_zero(void); void udp_fd_set(socket_udp *s); int udp_fd_isset(socket_udp *s); #if defined(__cplusplus) } #endif #endif uclmmbase-1.2.16.0/src/ntp.c0000644000175000017500000000136007046072343014424 0ustar enderender/* * FILE: ntp.h * AUTHOR: O.Hodson * * NTP utility functions to make rtp and rtp round time calculation * a little less painful. * * Copyright (c) 2000 University College London * All rights reserved. * * $Id: ntp.c,v 1.2 2000/02/02 18:18:11 ucaccsp Exp $ */ #include "config_unix.h" #include "config_win32.h" #include "gettimeofday.h" #include "ntp.h" #define SECS_BETWEEN_1900_1970 2208988800u void ntp64_time(uint32_t *ntp_sec, uint32_t *ntp_frac) { struct timeval now; gettimeofday(&now, NULL); /* NB ntp_frac is in units of 1 / (2^32 - 1) secs. */ *ntp_sec = now.tv_sec + SECS_BETWEEN_1900_1970; *ntp_frac = (now.tv_usec << 12) + (now.tv_usec << 8) - ((now.tv_usec * 3650) >> 6); } uclmmbase-1.2.16.0/src/ntp.h0000644000175000017500000000134307061213601014421 0ustar enderender/* * FILE: ntp.h * AUTHOR: O.Hodson * * NTP utility functions to make rtp and rtp round time calculation * a little less painful. * * Copyright (c) 2000 University College London * All rights reserved. * * $Id: ntp.h,v 1.3 2000/03/07 14:51:45 ucacoxh Exp $ */ #ifndef _NTP_H #define _NTP_H #if defined(__cplusplus) extern "C" { #endif #define ntp64_to_ntp32(ntp_sec, ntp_frac) \ ((((ntp_sec) & 0x0000ffff) << 16) | \ (((ntp_frac) & 0xffff0000) >> 16)) #define ntp32_sub(now, then) ((now) > (then)) ? ((now) - (then)) : (((now) - (then)) + 0x7fffffff) void ntp64_time(uint32_t *ntp_sec, uint32_t *ntp_frac); #if defined(__cplusplus) } #endif #endif /* _NTP_H */ uclmmbase-1.2.16.0/src/qfDES.c0000640000175000017500000007102507015101145014553 0ustar enderender/***************************************************************************** Saleem N. Bhatti February 1993 Patch for Intel/Linux courtesy of Mark Handley & George Pavlou Added 2 August 1996, Saleem *****************************************************************************/ #include "config_unix.h" #include "config_win32.h" #include "qfDES.h" #include "crypt_random.h" typedef unsigned long Word; #define B00 0x80000000 #define B01 0x40000000 #define B02 0x20000000 #define B03 0x10000000 #define B04 0x08000000 #define B05 0x04000000 #define B06 0x02000000 #define B07 0x01000000 #define B08 0x00800000 #define B09 0x00400000 #define B10 0x00200000 #define B11 0x00100000 #define B12 0x00080000 #define B13 0x00040000 #define B14 0x00020000 #define B15 0x00010000 #define B16 0x00008000 #define B17 0x00004000 #define B18 0x00002000 #define B19 0x00001000 #define B20 0x00000800 #define B21 0x00000400 #define B22 0x00000200 #define B23 0x00000100 #define B24 0x00000080 #define B25 0x00000040 #define B26 0x00000020 #define B27 0x00000010 #define B28 0x00000008 #define B29 0x00000004 #define B30 0x00000002 #define B31 0x00000001 #define INITIAL_PERMUTATION_AUX(_i0, _i1, _o0, _o1) \ { \ _o0 = _o1 = 0; \ _o0 |= (_i1 & B25) << 25; /* 58 */ \ _o0 |= (_i1 & B17) << 16; /* 50 */ \ _o0 |= (_i1 & B09) << 7; /* 42 */ \ _o0 |= (_i1 & B01) >> 2; /* 34 */ \ _o0 |= (_i0 & B25) << 21; /* 26 */ \ _o0 |= (_i0 & B17) << 12; /* 18 */ \ _o0 |= (_i0 & B09) << 3; /* 10 */ \ _o0 |= (_i0 & B01) >> 6; /* 2 */ \ _o0 |= (_i1 & B27) << 19; /* 60 */ \ _o0 |= (_i1 & B19) << 10; /* 52 */ \ _o0 |= (_i1 & B11) << 1; /* 44 */ \ _o0 |= (_i1 & B03) >> 8; /* 36 */ \ _o0 |= (_i0 & B27) << 15; /* 28 */ \ _o0 |= (_i0 & B19) << 6; /* 20 */ \ _o0 |= (_i0 & B11) >> 3; /* 12 */ \ _o0 |= (_i0 & B03) >> 12; /* 4 */ \ _o0 |= (_i1 & B29) << 13; /* 62 */ \ _o0 |= (_i1 & B21) << 4; /* 54 */ \ _o0 |= (_i1 & B13) >> 5; /* 46 */ \ _o0 |= (_i1 & B05) >> 14; /* 38 */ \ _o0 |= (_i0 & B29) << 9; /* 30 */ \ _o0 |= (_i0 & B21) ; /* 22 */ \ _o0 |= (_i0 & B13) >> 9; /* 14 */ \ _o0 |= (_i0 & B05) >> 18; /* 6 */ \ _o0 |= (_i1 & B31) << 7; /* 64 */ \ _o0 |= (_i1 & B23) >> 2; /* 56 */ \ _o0 |= (_i1 & B15) >> 11; /* 48 */ \ _o0 |= (_i1 & B07) >> 20; /* 40 */ \ _o0 |= (_i0 & B31) << 3; /* 32 */ \ _o0 |= (_i0 & B23) >> 6; /* 24 */ \ _o0 |= (_i0 & B15) >> 15; /* 16 */ \ _o0 |= (_i0 & B07) >> 24; /* 8 */ \ _o1 |= (_i1 & B24) << 24; /* 57 */ \ _o1 |= (_i1 & B16) << 15; /* 49 */ \ _o1 |= (_i1 & B08) << 6; /* 41 */ \ _o1 |= (_i1 & B00) >> 3; /* 33 */ \ _o1 |= (_i0 & B24) << 20; /* 25 */ \ _o1 |= (_i0 & B16) << 11; /* 17 */ \ _o1 |= (_i0 & B08) << 2; /* 9 */ \ _o1 |= (_i0 & B00) >> 7; /* 1 */ \ _o1 |= (_i1 & B26) << 18; /* 59 */ \ _o1 |= (_i1 & B18) << 9; /* 51 */ \ _o1 |= (_i1 & B10) ; /* 43 */ \ _o1 |= (_i1 & B02) >> 9; /* 35 */ \ _o1 |= (_i0 & B26) << 14; /* 27 */ \ _o1 |= (_i0 & B18) << 5; /* 19 */ \ _o1 |= (_i0 & B10) >> 4; /* 11 */ \ _o1 |= (_i0 & B02) >> 13; /* 3 */ \ _o1 |= (_i1 & B28) << 12; /* 61 */ \ _o1 |= (_i1 & B20) << 3; /* 53 */ \ _o1 |= (_i1 & B12) >> 6; /* 45 */ \ _o1 |= (_i1 & B04) >> 15; /* 37 */ \ _o1 |= (_i0 & B28) << 8; /* 29 */ \ _o1 |= (_i0 & B20) >> 1; /* 21 */ \ _o1 |= (_i0 & B12) >> 10; /* 13 */ \ _o1 |= (_i0 & B04) >> 19; /* 5 */ \ _o1 |= (_i1 & B30) << 6; /* 63 */ \ _o1 |= (_i1 & B22) >> 3; /* 55 */ \ _o1 |= (_i1 & B14) >> 12; /* 47 */ \ _o1 |= (_i1 & B06) >> 21; /* 39 */ \ _o1 |= (_i0 & B30) << 2; /* 31 */ \ _o1 |= (_i0 & B22) >> 7; /* 23 */ \ _o1 |= (_i0 & B14) >> 16; /* 15 */ \ _o1 |= (_i0 & B06) >> 25; /* 7 */ \ } #define FINAL_PERMUTATION_AUX(_i0, _i1, _o0, _o1) \ { \ _o0 = _o1 = 0; \ _o0 |= (_i1 & B07) << 7; /* 40 */ \ _o0 |= (_i0 & B07) << 6; /* 8 */ \ _o0 |= (_i1 & B15) << 13; /* 48 */ \ _o0 |= (_i0 & B15) << 12; /* 16 */ \ _o0 |= (_i1 & B23) << 19; /* 56 */ \ _o0 |= (_i0 & B23) << 18; /* 24 */ \ _o0 |= (_i1 & B31) << 25; /* 64 */ \ _o0 |= (_i0 & B31) << 24; /* 32 */ \ _o0 |= (_i1 & B06) >> 2; /* 39 */ \ _o0 |= (_i0 & B06) >> 3; /* 7 */ \ _o0 |= (_i1 & B14) << 4; /* 47 */ \ _o0 |= (_i0 & B14) << 3; /* 15 */ \ _o0 |= (_i1 & B22) << 10; /* 55 */ \ _o0 |= (_i0 & B22) << 9; /* 23 */ \ _o0 |= (_i1 & B30) << 16; /* 63 */ \ _o0 |= (_i0 & B30) << 15; /* 31 */ \ _o0 |= (_i1 & B05) >> 11; /* 38 */ \ _o0 |= (_i0 & B05) >> 12; /* 6 */ \ _o0 |= (_i1 & B13) >> 5; /* 46 */ \ _o0 |= (_i0 & B13) >> 6; /* 14 */ \ _o0 |= (_i1 & B21) << 1; /* 54 */ \ _o0 |= (_i0 & B21) ; /* 22 */ \ _o0 |= (_i1 & B29) << 7; /* 62 */ \ _o0 |= (_i0 & B29) << 6; /* 30 */ \ _o0 |= (_i1 & B04) >> 20; /* 37 */ \ _o0 |= (_i0 & B04) >> 21; /* 5 */ \ _o0 |= (_i1 & B12) >> 14; /* 45 */ \ _o0 |= (_i0 & B12) >> 15; /* 13 */ \ _o0 |= (_i1 & B20) >> 8; /* 53 */ \ _o0 |= (_i0 & B20) >> 9; /* 21 */ \ _o0 |= (_i1 & B28) >> 2; /* 61 */ \ _o0 |= (_i0 & B28) >> 3; /* 29 */ \ _o1 |= (_i1 & B03) << 3; /* 36 */ \ _o1 |= (_i0 & B03) << 2; /* 4 */ \ _o1 |= (_i1 & B11) << 9; /* 44 */ \ _o1 |= (_i0 & B11) << 8; /* 12 */ \ _o1 |= (_i1 & B19) << 15; /* 52 */ \ _o1 |= (_i0 & B19) << 14; /* 20 */ \ _o1 |= (_i1 & B27) << 21; /* 60 */ \ _o1 |= (_i0 & B27) << 20; /* 28 */ \ _o1 |= (_i1 & B02) >> 6; /* 35 */ \ _o1 |= (_i0 & B02) >> 7; /* 3 */ \ _o1 |= (_i1 & B10) ; /* 43 */ \ _o1 |= (_i0 & B10) >> 1; /* 11 */ \ _o1 |= (_i1 & B18) << 6; /* 51 */ \ _o1 |= (_i0 & B18) << 5; /* 19 */ \ _o1 |= (_i1 & B26) << 12; /* 59 */ \ _o1 |= (_i0 & B26) << 11; /* 27 */ \ _o1 |= (_i1 & B01) >> 15; /* 34 */ \ _o1 |= (_i0 & B01) >> 16; /* 2 */ \ _o1 |= (_i1 & B09) >> 9; /* 42 */ \ _o1 |= (_i0 & B09) >> 10; /* 10 */ \ _o1 |= (_i1 & B17) >> 3; /* 50 */ \ _o1 |= (_i0 & B17) >> 4; /* 18 */ \ _o1 |= (_i1 & B25) << 3; /* 58 */ \ _o1 |= (_i0 & B25) << 2; /* 26 */ \ _o1 |= (_i1 & B00) >> 24; /* 33 */ \ _o1 |= (_i0 & B00) >> 25; /* 1 */ \ _o1 |= (_i1 & B08) >> 18; /* 41 */ \ _o1 |= (_i0 & B08) >> 19; /* 9 */ \ _o1 |= (_i1 & B16) >> 12; /* 49 */ \ _o1 |= (_i0 & B16) >> 13; /* 17 */ \ _o1 |= (_i1 & B24) >> 6; /* 57 */ \ _o1 |= (_i0 & B24) >> 7; /* 25 */ \ } /* 64b -> 2x28b */ #define PC1_AUX(_i0, _i1, _o0, _o1) \ { \ _o0 = _o1 = 0; \ _o0 |= (_i1 & B24) << 24; /* 57 */ \ _o0 |= (_i1 & B16) << 15; /* 49 */ \ _o0 |= (_i1 & B08) << 6; /* 41 */ \ _o0 |= (_i1 & B00) >> 3; /* 33 */ \ _o0 |= (_i0 & B24) << 20; /* 25 */ \ _o0 |= (_i0 & B16) << 11; /* 17 */ \ _o0 |= (_i0 & B08) << 2; /* 9 */ \ _o0 |= (_i0 & B00) >> 7; /* 1 */ \ _o0 |= (_i1 & B25) << 17; /* 58 */ \ _o0 |= (_i1 & B17) << 8; /* 50 */ \ _o0 |= (_i1 & B09) >> 1; /* 42 */ \ _o0 |= (_i1 & B01) >> 10; /* 34 */ \ _o0 |= (_i0 & B25) << 13; /* 26 */ \ _o0 |= (_i0 & B17) << 4; /* 18 */ \ _o0 |= (_i0 & B09) >> 5; /* 10 */ \ _o0 |= (_i0 & B01) >> 14; /* 2 */ \ _o0 |= (_i1 & B26) << 10; /* 59 */ \ _o0 |= (_i1 & B18) << 1; /* 51 */ \ _o0 |= (_i1 & B10) >> 8; /* 43 */ \ _o0 |= (_i1 & B02) >> 17; /* 35 */ \ _o0 |= (_i0 & B26) << 6; /* 27 */ \ _o0 |= (_i0 & B18) >> 3; /* 19 */ \ _o0 |= (_i0 & B10) >> 12; /* 11 */ \ _o0 |= (_i0 & B02) >> 21; /* 3 */ \ _o0 |= (_i1 & B27) << 3; /* 60 */ \ _o0 |= (_i1 & B19) >> 6; /* 52 */ \ _o0 |= (_i1 & B11) >> 15; /* 44 */ \ _o0 |= (_i1 & B03) >> 24; /* 36 */ \ _o1 |= (_i1 & B30) << 30; /* 63 */ \ _o1 |= (_i1 & B22) << 21; /* 55 */ \ _o1 |= (_i1 & B14) << 12; /* 47 */ \ _o1 |= (_i1 & B06) << 3; /* 39 */ \ _o1 |= (_i0 & B30) << 26; /* 31 */ \ _o1 |= (_i0 & B22) << 17; /* 23 */ \ _o1 |= (_i0 & B14) << 8; /* 15 */ \ _o1 |= (_i0 & B06) >> 1; /* 7 */ \ _o1 |= (_i1 & B29) << 21; /* 62 */ \ _o1 |= (_i1 & B21) << 12; /* 54 */ \ _o1 |= (_i1 & B13) << 3; /* 46 */ \ _o1 |= (_i1 & B05) >> 6; /* 38 */ \ _o1 |= (_i0 & B29) << 17; /* 30 */ \ _o1 |= (_i0 & B21) << 8; /* 22 */ \ _o1 |= (_i0 & B13) >> 1; /* 14 */ \ _o1 |= (_i0 & B05) >> 10; /* 6 */ \ _o1 |= (_i1 & B28) << 12; /* 61 */ \ _o1 |= (_i1 & B20) << 3; /* 53 */ \ _o1 |= (_i1 & B12) >> 6; /* 45 */ \ _o1 |= (_i1 & B04) >> 15; /* 37 */ \ _o1 |= (_i0 & B28) << 8; /* 29 */ \ _o1 |= (_i0 & B20) >> 1; /* 21 */ \ _o1 |= (_i0 & B12) >> 10; /* 13 */ \ _o1 |= (_i0 & B04) >> 19; /* 5 */ \ _o1 |= (_i0 & B27) << 3; /* 28 */ \ _o1 |= (_i0 & B19) >> 6; /* 20 */ \ _o1 |= (_i0 & B11) >> 15; /* 12 */ \ _o1 |= (_i0 & B03) >> 24; /* 4 */ \ } /* 2x28b -> 8x6b */ #define PC2_AUX(_i0, _i1, _o0, _o1) \ { \ _o0 = _o1 = 0; \ _o0 |= (_i0 & B13) << 11; /* 14 */ \ _o0 |= (_i0 & B16) << 13; /* 17 */ \ _o0 |= (_i0 & B10) << 6; /* 11 */ \ _o0 |= (_i0 & B23) << 18; /* 24 */ \ _o0 |= (_i0 & B00) >> 6; /* 1 */ \ _o0 |= (_i0 & B04) >> 3; /* 5 */ \ _o0 |= (_i0 & B02) >> 8; /* 3 */ \ _o0 |= (_i0 & B27) << 16; /* 28 */ \ _o0 |= (_i0 & B14) << 2; /* 15 */ \ _o0 |= (_i0 & B05) >> 8; /* 6 */ \ _o0 |= (_i0 & B20) << 6; /* 21 */ \ _o0 |= (_i0 & B09) >> 6; /* 10 */ \ _o0 |= (_i0 & B22) << 4; /* 23 */ \ _o0 |= (_i0 & B18) >> 1; /* 19 */ \ _o0 |= (_i0 & B11) >> 9; /* 12 */ \ _o0 |= (_i0 & B03) >> 18; /* 4 */ \ _o0 |= (_i0 & B25) << 3; /* 26 */ \ _o0 |= (_i0 & B07) >> 16; /* 8 */ \ _o0 |= (_i0 & B15) >> 11; /* 16 */ \ _o0 |= (_i0 & B06) >> 21; /* 7 */ \ _o0 |= (_i0 & B26) >> 2; /* 27 */ \ _o0 |= (_i0 & B19) >> 10; /* 20 */ \ _o0 |= (_i0 & B12) >> 18; /* 13 */ \ _o0 |= (_i0 & B01) >> 30; /* 2 */ \ _o1 |= (_i1 & B12) << 10; /* 41 */ \ _o1 |= (_i1 & B23) << 20; /* 52 */ \ _o1 |= (_i1 & B02) >> 2; /* 31 */ \ _o1 |= (_i1 & B08) << 3; /* 37 */ \ _o1 |= (_i1 & B18) << 12; /* 47 */ \ _o1 |= (_i1 & B26) << 19; /* 55 */ \ _o1 |= (_i1 & B01) >> 9; /* 30 */ \ _o1 |= (_i1 & B11) ; /* 40 */ \ _o1 |= (_i1 & B22) << 10; /* 51 */ \ _o1 |= (_i1 & B16) << 3; /* 45 */ \ _o1 |= (_i1 & B04) >> 10; /* 33 */ \ _o1 |= (_i1 & B19) << 4; /* 48 */ \ _o1 |= (_i1 & B15) >> 3; /* 44 */ \ _o1 |= (_i1 & B20) << 1; /* 49 */ \ _o1 |= (_i1 & B10) >> 10; /* 39 */ \ _o1 |= (_i1 & B27) << 6; /* 56 */ \ _o1 |= (_i1 & B05) >> 17; /* 34 */ \ _o1 |= (_i1 & B24) << 1; /* 53 */ \ _o1 |= (_i1 & B17) >> 9; /* 46 */ \ _o1 |= (_i1 & B13) >> 14; /* 42 */ \ _o1 |= (_i1 & B21) >> 7; /* 50 */ \ _o1 |= (_i1 & B07) >> 22; /* 36 */ \ _o1 |= (_i1 & B00) >> 30; /* 29 */ \ _o1 |= (_i1 & B03) >> 28; /* 32 */ \ } static Word s_p0[64] = { /* Combined S-Box1 and permutation P */ 0x00808200, 0x00000000, 0x00008000, 0x00808202, 0x00808002, 0x00008202, 0x00000002, 0x00008000, 0x00000200, 0x00808200, 0x00808202, 0x00000200, 0x00800202, 0x00808002, 0x00800000, 0x00000002, 0x00000202, 0x00800200, 0x00800200, 0x00008200, 0x00008200, 0x00808000, 0x00808000, 0x00800202, 0x00008002, 0x00800002, 0x00800002, 0x00008002, 0x00000000, 0x00000202, 0x00008202, 0x00800000, 0x00008000, 0x00808202, 0x00000002, 0x00808000, 0x00808200, 0x00800000, 0x00800000, 0x00000200, 0x00808002, 0x00008000, 0x00008200, 0x00800002, 0x00000200, 0x00000002, 0x00800202, 0x00008202, 0x00808202, 0x00008002, 0x00808000, 0x00800202, 0x00800002, 0x00000202, 0x00008202, 0x00808200, 0x00000202, 0x00800200, 0x00800200, 0x00000000, 0x00008002, 0x00008200, 0x00000000, 0x00808002 }; static Word s_p1[64] = { /* Combined S-Box2 and permutation P */ 0x40084010, 0x40004000, 0x00004000, 0x00084010, 0x00080000, 0x00000010, 0x40080010, 0x40004010, 0x40000010, 0x40084010, 0x40084000, 0x40000000, 0x40004000, 0x00080000, 0x00000010, 0x40080010, 0x00084000, 0x00080010, 0x40004010, 0x00000000, 0x40000000, 0x00004000, 0x00084010, 0x40080000, 0x00080010, 0x40000010, 0x00000000, 0x00084000, 0x00004010, 0x40084000, 0x40080000, 0x00004010, 0x00000000, 0x00084010, 0x40080010, 0x00080000, 0x40004010, 0x40080000, 0x40084000, 0x00004000, 0x40080000, 0x40004000, 0x00000010, 0x40084010, 0x00084010, 0x00000010, 0x00004000, 0x40000000, 0x00004010, 0x40084000, 0x00080000, 0x40000010, 0x00080010, 0x40004010, 0x40000010, 0x00080010, 0x00084000, 0x00000000, 0x40004000, 0x00004010, 0x40000000, 0x40080010, 0x40084010, 0x00084000 }; static Word s_p2[64] = { /* Combined S-Box3 and permutation P */ 0x00000104, 0x04010100, 0x00000000, 0x04010004, 0x04000100, 0x00000000, 0x00010104, 0x04000100, 0x00010004, 0x04000004, 0x04000004, 0x00010000, 0x04010104, 0x00010004, 0x04010000, 0x00000104, 0x04000000, 0x00000004, 0x04010100, 0x00000100, 0x00010100, 0x04010000, 0x04010004, 0x00010104, 0x04000104, 0x00010100, 0x00010000, 0x04000104, 0x00000004, 0x04010104, 0x00000100, 0x04000000, 0x04010100, 0x04000000, 0x00010004, 0x00000104, 0x00010000, 0x04010100, 0x04000100, 0x00000000, 0x00000100, 0x00010004, 0x04010104, 0x04000100, 0x04000004, 0x00000100, 0x00000000, 0x04010004, 0x04000104, 0x00010000, 0x04000000, 0x04010104, 0x00000004, 0x00010104, 0x00010100, 0x04000004, 0x04010000, 0x04000104, 0x00000104, 0x04010000, 0x00010104, 0x00000004, 0x04010004, 0x00010100 }; static Word s_p3[64] = { /* Combined S-Box4 and permutation P */ 0x80401000, 0x80001040, 0x80001040, 0x00000040, 0x00401040, 0x80400040, 0x80400000, 0x80001000, 0x00000000, 0x00401000, 0x00401000, 0x80401040, 0x80000040, 0x00000000, 0x00400040, 0x80400000, 0x80000000, 0x00001000, 0x00400000, 0x80401000, 0x00000040, 0x00400000, 0x80001000, 0x00001040, 0x80400040, 0x80000000, 0x00001040, 0x00400040, 0x00001000, 0x00401040, 0x80401040, 0x80000040, 0x00400040, 0x80400000, 0x00401000, 0x80401040, 0x80000040, 0x00000000, 0x00000000, 0x00401000, 0x00001040, 0x00400040, 0x80400040, 0x80000000, 0x80401000, 0x80001040, 0x80001040, 0x00000040, 0x80401040, 0x80000040, 0x80000000, 0x00001000, 0x80400000, 0x80001000, 0x00401040, 0x80400040, 0x80001000, 0x00001040, 0x00400000, 0x80401000, 0x00000040, 0x00400000, 0x00001000, 0x00401040 }; static Word s_p4[64] = { /* Combined S-Box5 and permutation P */ 0x00000080, 0x01040080, 0x01040000, 0x21000080, 0x00040000, 0x00000080, 0x20000000, 0x01040000, 0x20040080, 0x00040000, 0x01000080, 0x20040080, 0x21000080, 0x21040000, 0x00040080, 0x20000000, 0x01000000, 0x20040000, 0x20040000, 0x00000000, 0x20000080, 0x21040080, 0x21040080, 0x01000080, 0x21040000, 0x20000080, 0x00000000, 0x21000000, 0x01040080, 0x01000000, 0x21000000, 0x00040080, 0x00040000, 0x21000080, 0x00000080, 0x01000000, 0x20000000, 0x01040000, 0x21000080, 0x20040080, 0x01000080, 0x20000000, 0x21040000, 0x01040080, 0x20040080, 0x00000080, 0x01000000, 0x21040000, 0x21040080, 0x00040080, 0x21000000, 0x21040080, 0x01040000, 0x00000000, 0x20040000, 0x21000000, 0x00040080, 0x01000080, 0x20000080, 0x00040000, 0x00000000, 0x20040000, 0x01040080, 0x20000080 }; static Word s_p5[64] = { /* Combined S-Box6 and permutation P */ 0x10000008, 0x10200000, 0x00002000, 0x10202008, 0x10200000, 0x00000008, 0x10202008, 0x00200000, 0x10002000, 0x00202008, 0x00200000, 0x10000008, 0x00200008, 0x10002000, 0x10000000, 0x00002008, 0x00000000, 0x00200008, 0x10002008, 0x00002000, 0x00202000, 0x10002008, 0x00000008, 0x10200008, 0x10200008, 0x00000000, 0x00202008, 0x10202000, 0x00002008, 0x00202000, 0x10202000, 0x10000000, 0x10002000, 0x00000008, 0x10200008, 0x00202000, 0x10202008, 0x00200000, 0x00002008, 0x10000008, 0x00200000, 0x10002000, 0x10000000, 0x00002008, 0x10000008, 0x10202008, 0x00202000, 0x10200000, 0x00202008, 0x10202000, 0x00000000, 0x10200008, 0x00000008, 0x00002000, 0x10200000, 0x00202008, 0x00002000, 0x00200008, 0x10002008, 0x00000000, 0x10202000, 0x10000000, 0x00200008, 0x10002008 }; static Word s_p6[64] = { /* Combined S-Box7 and permutation P */ 0x00100000, 0x02100001, 0x02000401, 0x00000000, 0x00000400, 0x02000401, 0x00100401, 0x02100400, 0x02100401, 0x00100000, 0x00000000, 0x02000001, 0x00000001, 0x02000000, 0x02100001, 0x00000401, 0x02000400, 0x00100401, 0x00100001, 0x02000400, 0x02000001, 0x02100000, 0x02100400, 0x00100001, 0x02100000, 0x00000400, 0x00000401, 0x02100401, 0x00100400, 0x00000001, 0x02000000, 0x00100400, 0x02000000, 0x00100400, 0x00100000, 0x02000401, 0x02000401, 0x02100001, 0x02100001, 0x00000001, 0x00100001, 0x02000000, 0x02000400, 0x00100000, 0x02100400, 0x00000401, 0x00100401, 0x02100400, 0x00000401, 0x02000001, 0x02100401, 0x02100000, 0x00100400, 0x00000000, 0x00000001, 0x02100401, 0x00000000, 0x00100401, 0x02100000, 0x00000400, 0x02000001, 0x02000400, 0x00000400, 0x00100001 }; static Word s_p7[64] = { /* Combined S-Box8 and permutation P */ 0x08000820, 0x00000800, 0x00020000, 0x08020820, 0x08000000, 0x08000820, 0x00000020, 0x08000000, 0x00020020, 0x08020000, 0x08020820, 0x00020800, 0x08020800, 0x00020820, 0x00000800, 0x00000020, 0x08020000, 0x08000020, 0x08000800, 0x00000820, 0x00020800, 0x00020020, 0x08020020, 0x08020800, 0x00000820, 0x00000000, 0x00000000, 0x08020020, 0x08000020, 0x08000800, 0x00020820, 0x00020000, 0x00020820, 0x00020000, 0x08020800, 0x00000800, 0x00000020, 0x08020020, 0x00000800, 0x00020820, 0x08000800, 0x00000020, 0x08000020, 0x08020000, 0x08020020, 0x08000000, 0x00020000, 0x08000820, 0x00000000, 0x08020820, 0x00020020, 0x08000020, 0x08020000, 0x08000800, 0x08000820, 0x00000000, 0x08020820, 0x00020800, 0x00020800, 0x00000820, 0x00000820, 0x00020020, 0x08000000, 0x08020800 }; #define INITIAL_PERMUTATION(t, regL, regR) \ INITIAL_PERMUTATION_AUX(t[0], t[1], regL, regR) #define FINAL_PERMUTATION(regR, regL, t) \ FINAL_PERMUTATION_AUX(regR, regL, t[0], t[1]) #define PC1(k, regC, regD) \ PC1_AUX(k[0], k[1], regC, regD) #define PC2(regC, regD, k) \ PC2_AUX(regC, regD, k[0], k[1]) unsigned char G_padChar = (char) 0; /* Default pad charcater */ static Word ROTATE_LEFT(Word x) { Word a; a = (x & 0x80000000) >> 27; return (x << 1) | a; } static Word ROTATE_RIGHT(Word x) { Word a; a = x & 0x00000010; return (x >> 1) | (a << 27); } /* ** The S Box transformations and the permutation P are combined in the vectors ** s_p0 - s_p7. Permutation E and the MOD 2 addition with the intermediate key ** are then done "inline" on each round. The intermediate key is already in a ** a 8x6bit form because of the modified permuation PC2 used. */ #if !defined(WORDS_BIGENDIAN) #define DES(t, ik) \ { \ register Word l, r, reg32, round; \ register unsigned char *bb; \ INITIAL_PERMUTATION(t, l, r); \ for(bb = (unsigned char *) ik, round = 0x8000; round; bb += 8, round >>= 1) { \ register Word w = (r << 1) | (r >> 31); \ reg32 = s_p7[( w & 0x3f) ^ bb[4]]; \ reg32 |= s_p6[((w >>= 4) & 0x3f) ^ bb[5]]; \ reg32 |= s_p5[((w >>= 4) & 0x3f) ^ bb[6]]; \ reg32 |= s_p4[((w >>= 4) & 0x3f) ^ bb[7]]; \ reg32 |= s_p3[((w >>= 4) & 0x3f) ^ bb[0]]; \ reg32 |= s_p2[((w >>= 4) & 0x3f) ^ bb[1]]; \ reg32 |= s_p1[((w >> 4) & 0x3f) ^ bb[2]]; \ reg32 |= s_p0[(((r & 0x1) << 5) | ((r & 0xf8000000) >> 27)) ^ bb[3]]; \ reg32 ^= l; \ l = r; \ r = reg32; \ } \ FINAL_PERMUTATION(r, l, t); \ } #define MAKE_LITTLE_ENDIAN(t, s) \ { \ register unsigned int z, l = s/4; \ register Word *tp = (Word *) t; \ for(z = 0; z < l; ++z) tp[z] = htonl(tp[z]); \ } #else /* WORDS_BIGENDIAN */ #define DES(t, ik) \ { \ register Word l, r, reg32, round; \ register unsigned char *bb; \ INITIAL_PERMUTATION(t, l, r); \ for(bb = (unsigned char *) ik, round = 0x8000; round; bb += 8, round >>= 1) { \ register Word w = (r << 1) | (r >> 31); \ reg32 = s_p7[( w & 0x3f) ^ bb[7]]; \ reg32 |= s_p6[((w >>= 4) & 0x3f) ^ bb[6]]; \ reg32 |= s_p5[((w >>= 4) & 0x3f) ^ bb[5]]; \ reg32 |= s_p4[((w >>= 4) & 0x3f) ^ bb[4]]; \ reg32 |= s_p3[((w >>= 4) & 0x3f) ^ bb[3]]; \ reg32 |= s_p2[((w >>= 4) & 0x3f) ^ bb[2]]; \ reg32 |= s_p1[((w >> 4) & 0x3f) ^ bb[1]]; \ reg32 |= s_p0[(((r & 0x1) << 5) | ((r & 0xf8000000) >> 27)) ^ bb[0]]; \ reg32 ^= l; \ l = r; \ r = reg32; \ } \ FINAL_PERMUTATION(r, l, t); \ } #endif /* WORDS_BIGENDIAN */ int qfDES(unsigned char *key, unsigned char *data, unsigned int size, const QFDES_what what, const QFDES_mode mode, unsigned char *initVec) { /* Store some info to optimise for multiple calls ... */ static unsigned char desKey[8], desKeys[128]; static Word *oldKey = (Word *) desKey, *keys = (Word *) desKeys; static QFDES_what oldWhat; static QFDES_mode oldMode; unsigned char b0[8], b1[8]; /* feedback blocks */ Word *newKey = (Word *) key, /* key from user */ *text, /* text to be [en|de]crypted */ *cb = (Word *) b0, /* the chained block in CBC mode */ *cb1 = (Word *) b1; /* a copy for use when decrypting */ #if !defined(WORDS_BIGENDIAN) unsigned int origSize = size; MAKE_LITTLE_ENDIAN(key, 8); MAKE_LITTLE_ENDIAN(data, origSize); #endif /* ** Check new key against old key ** and set up intermediate keys. */ if (newKey[0] != oldKey[0] || newKey[1] != oldKey[1]) { Word c, d; /* C and D registers */ oldKey[0] = newKey[0]; oldKey[1] = newKey[1]; oldWhat = what; oldMode = mode; PC1(newKey, c, d); if ((what == qfDES_encrypt) || (mode == qfDES_cfb) || (mode == qfDES_ofb)) { int z; Word r; Word *k = keys; Word rol[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1}; for(z = 0; z < 16; z++, k += 2) { for (r = 0; r < rol[z]; r++) { c = ROTATE_LEFT(c); d = ROTATE_LEFT(d); } PC2(c, d, k); } } else { int z; Word r; Word *k = keys; Word ror[16] = {0, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1}; for(z = 0; z < 16; z++, k += 2) { r = 0; while (ror[z] > r) { r++; c = ROTATE_RIGHT(c); d = ROTATE_RIGHT(d); } PC2(c, d, k); } } } else if ((what != oldWhat) && ((mode == qfDES_ecb) || (mode == qfDES_cbc))) { /* ** Same key but different direction. ** Reverse intermediate key sequence (ECB and CBC). */ Word *ik1, *ik2, ik3[2]; for(ik1 = keys, ik2 = &(keys[30]); ik1 < ik2; ik1 += 2, ik2 -= 2) { ik3[0] = ik1[0]; ik3[1] = ik1[1]; ik1[0] = ik2[0]; ik1[1] = ik2[1]; ik2[0] = ik3[0]; ik2[1] = ik3[1]; } oldWhat = what; } /* Set up initilaisation vector */ if (mode != qfDES_ecb) { if (initVec) { { cb[0] = ((Word *) initVec)[0]; cb[1] = ((Word *) initVec)[1]; } } else { cb[0] = 0; cb[1] = 0; } #if !defined(WORDS_BIGENDIAN) MAKE_LITTLE_ENDIAN(cb, 8); #endif } /* ** Lots of gotos and code duplication follow (arrgh) but it speeds ** it up a wee bit! ** What would be more useful is looking more carefully at the DES ** permutations to produce more efficient versions of the macros ** of the "auto-generated" versions used in qfDES-aux.c. */ size >>= 3; /* this is always a multpile of 8 */ if (what == qfDES_encrypt) { switch ((int) mode) { case ((int) qfDES_ecb): goto _ECB_; case ((int) qfDES_cbc): goto _CBC_encrypt_; case ((int) qfDES_cfb): goto _CFB_encrypt_; case ((int) qfDES_ofb): goto _OFB_; } } else { switch ((int) mode) { case ((int) qfDES_ecb): goto _ECB_; case ((int) qfDES_cbc): goto _CBC_decrypt_; case ((int) qfDES_cfb): goto _CFB_decrypt_; case ((int) qfDES_ofb): goto _OFB_; } } _ECB_: /* ECB */ for(text = (Word *) data; size; --size, text += 2) { DES(text, keys); } goto _exit_qfDES_; _CBC_encrypt_: /* CBC Encryption */ for(text = (Word *) data; size; --size, text += 2) { /* chaining block */ text[0] ^= cb[0]; text[1] ^= cb[1]; DES(text, keys); /* set up chaining block for next round */ cb[0] = text[0]; cb[1] = text[1]; } goto _initVec_; _CBC_decrypt_: /* CBC Decryption */ for(text = (Word *) data; size; --size, text += 2) { /* set up chaining block */ /* ** The decryption is done in place so I need ** to copy this text block for the next round. */ cb1[0] = text[0]; cb1[1] = text[1]; DES(text, keys); /* chaining block for next round */ text[0] ^= cb[0]; text[1] ^= cb[1]; /* ** Copy back the saved encrypted text - this makes ** CBC decryption slower than CBC encryption. */ cb[0] = cb1[0]; cb[1] = cb1[1]; } goto _initVec_; _CFB_encrypt_: /* CFB Encryption */ for(text = (Word *) data; size; --size, text += 2) { /* use cb as the feedback block */ DES(cb, keys); text[0] ^= cb[0]; text[1] ^= cb[1]; /* set up feedback block for next round */ cb[0] = text[0]; cb[1] = text[1]; } goto _initVec_; _CFB_decrypt_: /* CFB Decryption */ for(text = (Word *) data; size; --size, text += 2) { /* set up feedback block */ /* ** The decryption is done in place so I need ** to copy this text block for the next round. */ cb1[0] = text[0]; cb1[1] = text[1]; /* use cb as the feedback block */ DES(cb, keys); text[0] ^= cb[0]; text[1] ^= cb[1]; /* set up feedback block for next round */ cb[0] = cb1[0]; cb[1] = cb1[1]; } goto _initVec_; _OFB_: /* OFB */ for(text = (Word *) data; size; --size, text += 2) { /* use cb as the feed back block */ DES(cb, keys); text[0] ^= cb[0]; text[1] ^= cb[1]; } _initVec_: /* ** Copy the final chained block back to initVec (CBC, CFB and OFB). ** This allows the [en|de]cryption of large amounts of data in small ** chunks. */ if (initVec) { ((Word *) initVec)[0] = cb[0]; ((Word *) initVec)[1] = cb[1]; #if !defined(WORDS_BIGENDIAN) MAKE_LITTLE_ENDIAN(initVec, 8); #endif } _exit_qfDES_: #if !defined(WORDS_BIGENDIAN) MAKE_LITTLE_ENDIAN(key, 8); MAKE_LITTLE_ENDIAN(data, origSize); #endif return 0; } /* ** This function sets bit 8 of each byte to odd or even parity as requested. ** It is assumed that the right-most bit of each byte is the parity bit. ** Although this is really only used by the two key generation functions below, ** it may be useful to someone. */ void qfDES_setParity(unsigned char *ptr, unsigned int size, const QFDES_parity parity) { unsigned int i, mask, bits; for(i = 0; i < size; ++i, ++ptr) { for(mask = 0x80, bits = 0; mask > 0x01; mask >>= 1) if (((unsigned int) *ptr) & mask) ++bits; *ptr |= bits % 2 == (unsigned int) parity ? 0x00 : 0x01; } } unsigned int qfDES_checkParity(unsigned char *ptr, unsigned int size, const QFDES_parity parity) { unsigned int i, mask, bits, parityBit, parityErrors = 0; for(i = 0; i < size; ++i, ++ptr) { for(mask = 0x80, bits = 0; mask > 0x01; mask >>= 1) if (((unsigned int) *ptr) & mask) ++bits; parityBit = bits % 2 == (unsigned int) parity ? 0 : 1; if ((((unsigned int) *ptr) & 0x1) != parityBit) ++parityErrors; } return parityErrors; } static unsigned char weakKeys[18][8] = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, {0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, {0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe}, {0x1f, 0x1f, 0x1f, 0x1f, 0x0e, 0x0e, 0x0e, 0x0e}, {0xe0, 0xe0, 0xe0, 0xe0, 0xf1, 0xf1, 0xf1, 0xf1}, {0x01, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0xfe}, {0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01}, {0x1f, 0xe0, 0x1f, 0xe0, 0x0e, 0xf1, 0x0e, 0xf1}, {0xe0, 0x1f, 0xe0, 0x1f, 0xf1, 0x0e, 0xf1, 0x0e}, {0x01, 0xe0, 0x01, 0xe0, 0x01, 0xf1, 0x01, 0xf1}, {0xe0, 0x01, 0xe0, 0x01, 0xf1, 0x01, 0xf1, 0x01}, {0x1f, 0xfe, 0x1f, 0xfe, 0x0e, 0xfe, 0x0e, 0xfe}, {0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x0e, 0xfe, 0x0e}, {0x01, 0x1f, 0x01, 0x1f, 0x01, 0x0e, 0x01, 0x0e}, {0x1f, 0x01, 0x1f, 0x01, 0x0e, 0x01, 0x0e, 0x01}, {0xe0, 0xfe, 0xe0, 0xfe, 0xf1, 0xfe, 0xf1, 0xfe}, {0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0xf1, 0xfe, 0xf1}}; /* ** Although this is really only used by the key generation function below, ** it may be handy to someone. */ int qfDES_checkWeakKeys(unsigned char *key) { unsigned char *bp; int i; for(bp = weakKeys[i = 0]; i < 18; bp = weakKeys[++i]) if (memcmp((void *) key, (void *) bp, 8) == 0) return -1; return 0; } /* ** The following function attempts to genreate a random key or IV. ** It relies on the randomness of the of the random(3) function. Although ** it is probably not particularly fast, keys and IV will most probably be ** generated off-line so it does not matter too much. */ unsigned char *qfDES_generate(const QFDES_generate what) { static unsigned char buffer[8]; static int flag = 0; unsigned char *bp; long mask = what == qfDES_key ? 0xfe : 0xff; /* Set up a seed - 42 is the answer ... */ if (!flag) { lbl_srandom((int) (getpid() * 42) ^ (int) time((time_t *) 0)); flag = 1; } do { for(bp = buffer; bp <= &(buffer[7]); *bp++ = (unsigned char) (lbl_random() & mask)); if (what == qfDES_key) qfDES_setParity(buffer, 8, qfDES_odd); } while(what == qfDES_key ? qfDES_checkWeakKeys(buffer) : 0); return buffer; } unsigned char qfDES_setPad(unsigned char pad) { unsigned char b = G_padChar; G_padChar = pad; return b; } uclmmbase-1.2.16.0/src/qfDES.h0000640000175000017500000000474607252011730014571 0ustar enderender/***************************************************************************** Saleem N. Bhatti February 1993 *****************************************************************************/ #if !defined(_qfDES_h_) #define _qfDES_h_ #if defined(__cplusplus) extern "C" { #endif /* what */ typedef enum {qfDES_encrypt, qfDES_decrypt} QFDES_what; /* mode */ typedef enum {qfDES_ecb, qfDES_cbc, qfDES_cfb, qfDES_ofb} QFDES_mode; /* parity */ typedef enum {qfDES_even, qfDES_odd} QFDES_parity; /* key/IV generation */ typedef enum {qfDES_key, qfDES_iv} QFDES_generate; /* This does it all */ int qfDES (unsigned char *key, unsigned char *data, unsigned int size, const QFDES_what what, const QFDES_mode mode, unsigned char *initVec); /* Handy macros */ #define qfDES_ECB_e(_key, _data, _size) qfDES(_key, _data, _size, qfDES_encrypt, qfDES_ecb, (unsigned char *) 0) #define qfDES_ECB_d(_key, _data, _size) qfDES(_key, _data, _size, qfDES_decrypt, qfDES_ecb, (unsigned char *) 0) #define qfDES_CBC_e(_key, _data, _size, _initVec) qfDES(_key, _data, _size, qfDES_encrypt, qfDES_cbc, _initVec) #define qfDES_CBC_d(_key, _data, _size, _initVec) qfDES(_key, _data, _size, qfDES_decrypt, qfDES_cbc, _initVec) #define qfDES_CFB_e(_key, _data, _size, _initVec) qfDES(_key, _data, _size, qfDES_encrypt, qfDES_cfb, _initVec) #define qfDES_CFB_d(_key, _data, _size, _initVec) qfDES(_key, _data, _size, qfDES_decrypt, qfDES_cfb, _initVec) #define qfDES_OFB_e(_key, _data, _size, _initVec) qfDES(_key, _data, _size, qfDES_encrypt, qfDES_ofb, _initVec) #define qfDES_OFB_d(_key, _data, _size, _initVec) qfDES(_key, _data, _size, qfDES_decrypt, qfDES_ofb, _initVec) /* Padded [m|re]alloc() */ unsigned char qfDES_setPad (unsigned char pad); #define qfDES_padSpace() qfDES_setPad((unsigned char) ' ') #define qfDES_padZero() qfDES_setPad((unsigned char) '\0') /* The size of text in a qfDES_malloc()ed block */ #define qfDES_plainTextSize(_ptr, _size) (unsigned int) ((_size) - (unsigned int) (_ptr)[(_size) - 1]) /* Keys */ void qfDES_setParity (unsigned char *ptr, unsigned int size, const QFDES_parity parity); unsigned int qfDES_checkParity (unsigned char *ptr, unsigned int size, const QFDES_parity parity); unsigned char *qfDES_generate (const QFDES_generate what); /* returns a pointer to static memory */ #define qfDES_generateKey() qfDES_generate(qfDES_key) #define qfDES_generateIV() qfDES_generate(qfDES_iv) int qfDES_checkWeakKeys (unsigned char *key); #if defined(__cplusplus) } #endif #endif /* !_qfDES_h_ */ uclmmbase-1.2.16.0/src/rijndael-alg-fst.c0000644000175000017500000003301107272124017016741 0ustar enderender/* * rijndael-alg-fst.c v2.4 April '2000 * * Optimised ANSI C code * * authors: v1.0: Antoon Bosselaers * v2.0: Vincent Rijmen * v2.3: Paulo Barreto * v2.4: Vincent Rijmen * * This code is placed in the public domain. */ #include #include #include "rijndael-alg-fst.h" #include "boxes-fst.dat" int rijndaelKeySched(word8 k[MAXKC][4], word8 W[MAXROUNDS+1][4][4], int ROUNDS) { /* Calculate the necessary round keys * The number of calculations depends on keyBits and blockBits */ int j, r, t, rconpointer = 0; word8 tk[MAXKC][4]; int KC = ROUNDS - 6; for (j = KC-1; j >= 0; j--) { *((word32*)tk[j]) = *((word32*)k[j]); } r = 0; t = 0; /* copy values into round key array */ for (j = 0; (j < KC) && (r < ROUNDS + 1); ) { for (; (j < KC) && (t < 4); j++, t++) { *((word32*)W[r][t]) = *((word32*)tk[j]); } if (t == 4) { r++; t = 0; } } while (r < ROUNDS + 1) { /* while not enough round key material calculated */ /* calculate new values */ tk[0][0] ^= S[tk[KC-1][1]]; tk[0][1] ^= S[tk[KC-1][2]]; tk[0][2] ^= S[tk[KC-1][3]]; tk[0][3] ^= S[tk[KC-1][0]]; tk[0][0] ^= rcon[rconpointer++]; if (KC != 8) { for (j = 1; j < KC; j++) { *((word32*)tk[j]) ^= *((word32*)tk[j-1]); } } else { for (j = 1; j < KC/2; j++) { *((word32*)tk[j]) ^= *((word32*)tk[j-1]); } tk[KC/2][0] ^= S[tk[KC/2 - 1][0]]; tk[KC/2][1] ^= S[tk[KC/2 - 1][1]]; tk[KC/2][2] ^= S[tk[KC/2 - 1][2]]; tk[KC/2][3] ^= S[tk[KC/2 - 1][3]]; for (j = KC/2 + 1; j < KC; j++) { *((word32*)tk[j]) ^= *((word32*)tk[j-1]); } } /* copy values into round key array */ for (j = 0; (j < KC) && (r < ROUNDS + 1); ) { for (; (j < KC) && (t < 4); j++, t++) { *((word32*)W[r][t]) = *((word32*)tk[j]); } if (t == 4) { r++; t = 0; } } } return 0; } int rijndaelKeyEncToDec(word8 W[MAXROUNDS+1][4][4], int ROUNDS) { int r; word8 *w; for (r = 1; r < ROUNDS; r++) { w = W[r][0]; *((word32*)w) = *((word32*)U1[w[0]]) ^ *((word32*)U2[w[1]]) ^ *((word32*)U3[w[2]]) ^ *((word32*)U4[w[3]]); w = W[r][1]; *((word32*)w) = *((word32*)U1[w[0]]) ^ *((word32*)U2[w[1]]) ^ *((word32*)U3[w[2]]) ^ *((word32*)U4[w[3]]); w = W[r][2]; *((word32*)w) = *((word32*)U1[w[0]]) ^ *((word32*)U2[w[1]]) ^ *((word32*)U3[w[2]]) ^ *((word32*)U4[w[3]]); w = W[r][3]; *((word32*)w) = *((word32*)U1[w[0]]) ^ *((word32*)U2[w[1]]) ^ *((word32*)U3[w[2]]) ^ *((word32*)U4[w[3]]); } return 0; } /** * Encrypt a single block. */ int rijndaelEncrypt(word8 a[16], word8 b[16], word8 rk[MAXROUNDS+1][4][4], int ROUNDS) { int r; word8 temp[4][4]; *((word32*)temp[0]) = *((word32*)(a )) ^ *((word32*)rk[0][0]); *((word32*)temp[1]) = *((word32*)(a+ 4)) ^ *((word32*)rk[0][1]); *((word32*)temp[2]) = *((word32*)(a+ 8)) ^ *((word32*)rk[0][2]); *((word32*)temp[3]) = *((word32*)(a+12)) ^ *((word32*)rk[0][3]); *((word32*)(b )) = *((word32*)T1[temp[0][0]]) ^ *((word32*)T2[temp[1][1]]) ^ *((word32*)T3[temp[2][2]]) ^ *((word32*)T4[temp[3][3]]); *((word32*)(b + 4)) = *((word32*)T1[temp[1][0]]) ^ *((word32*)T2[temp[2][1]]) ^ *((word32*)T3[temp[3][2]]) ^ *((word32*)T4[temp[0][3]]); *((word32*)(b + 8)) = *((word32*)T1[temp[2][0]]) ^ *((word32*)T2[temp[3][1]]) ^ *((word32*)T3[temp[0][2]]) ^ *((word32*)T4[temp[1][3]]); *((word32*)(b +12)) = *((word32*)T1[temp[3][0]]) ^ *((word32*)T2[temp[0][1]]) ^ *((word32*)T3[temp[1][2]]) ^ *((word32*)T4[temp[2][3]]); for (r = 1; r < ROUNDS-1; r++) { *((word32*)temp[0]) = *((word32*)(b )) ^ *((word32*)rk[r][0]); *((word32*)temp[1]) = *((word32*)(b+ 4)) ^ *((word32*)rk[r][1]); *((word32*)temp[2]) = *((word32*)(b+ 8)) ^ *((word32*)rk[r][2]); *((word32*)temp[3]) = *((word32*)(b+12)) ^ *((word32*)rk[r][3]); *((word32*)(b )) = *((word32*)T1[temp[0][0]]) ^ *((word32*)T2[temp[1][1]]) ^ *((word32*)T3[temp[2][2]]) ^ *((word32*)T4[temp[3][3]]); *((word32*)(b + 4)) = *((word32*)T1[temp[1][0]]) ^ *((word32*)T2[temp[2][1]]) ^ *((word32*)T3[temp[3][2]]) ^ *((word32*)T4[temp[0][3]]); *((word32*)(b + 8)) = *((word32*)T1[temp[2][0]]) ^ *((word32*)T2[temp[3][1]]) ^ *((word32*)T3[temp[0][2]]) ^ *((word32*)T4[temp[1][3]]); *((word32*)(b +12)) = *((word32*)T1[temp[3][0]]) ^ *((word32*)T2[temp[0][1]]) ^ *((word32*)T3[temp[1][2]]) ^ *((word32*)T4[temp[2][3]]); } /* last round is special */ *((word32*)temp[0]) = *((word32*)(b )) ^ *((word32*)rk[ROUNDS-1][0]); *((word32*)temp[1]) = *((word32*)(b+ 4)) ^ *((word32*)rk[ROUNDS-1][1]); *((word32*)temp[2]) = *((word32*)(b+ 8)) ^ *((word32*)rk[ROUNDS-1][2]); *((word32*)temp[3]) = *((word32*)(b+12)) ^ *((word32*)rk[ROUNDS-1][3]); b[ 0] = T1[temp[0][0]][1]; b[ 1] = T1[temp[1][1]][1]; b[ 2] = T1[temp[2][2]][1]; b[ 3] = T1[temp[3][3]][1]; b[ 4] = T1[temp[1][0]][1]; b[ 5] = T1[temp[2][1]][1]; b[ 6] = T1[temp[3][2]][1]; b[ 7] = T1[temp[0][3]][1]; b[ 8] = T1[temp[2][0]][1]; b[ 9] = T1[temp[3][1]][1]; b[10] = T1[temp[0][2]][1]; b[11] = T1[temp[1][3]][1]; b[12] = T1[temp[3][0]][1]; b[13] = T1[temp[0][1]][1]; b[14] = T1[temp[1][2]][1]; b[15] = T1[temp[2][3]][1]; *((word32*)(b )) ^= *((word32*)rk[ROUNDS][0]); *((word32*)(b+ 4)) ^= *((word32*)rk[ROUNDS][1]); *((word32*)(b+ 8)) ^= *((word32*)rk[ROUNDS][2]); *((word32*)(b+12)) ^= *((word32*)rk[ROUNDS][3]); return 0; } #ifdef INTERMEDIATE_VALUE_KAT /** * Encrypt only a certain number of rounds. * Only used in the Intermediate Value Known Answer Test. */ int rijndaelEncryptRound(word8 a[4][4], word8 rk[MAXROUNDS+1][4][4], int ROUNDS, int rounds) { int r; word8 temp[4][4]; /* make number of rounds sane */ if (rounds > ROUNDS) { rounds = ROUNDS; } *((word32*)a[0]) = *((word32*)a[0]) ^ *((word32*)rk[0][0]); *((word32*)a[1]) = *((word32*)a[1]) ^ *((word32*)rk[0][1]); *((word32*)a[2]) = *((word32*)a[2]) ^ *((word32*)rk[0][2]); *((word32*)a[3]) = *((word32*)a[3]) ^ *((word32*)rk[0][3]); for (r = 1; (r <= rounds) && (r < ROUNDS); r++) { *((word32*)temp[0]) = *((word32*)T1[a[0][0]]) ^ *((word32*)T2[a[1][1]]) ^ *((word32*)T3[a[2][2]]) ^ *((word32*)T4[a[3][3]]); *((word32*)temp[1]) = *((word32*)T1[a[1][0]]) ^ *((word32*)T2[a[2][1]]) ^ *((word32*)T3[a[3][2]]) ^ *((word32*)T4[a[0][3]]); *((word32*)temp[2]) = *((word32*)T1[a[2][0]]) ^ *((word32*)T2[a[3][1]]) ^ *((word32*)T3[a[0][2]]) ^ *((word32*)T4[a[1][3]]); *((word32*)temp[3]) = *((word32*)T1[a[3][0]]) ^ *((word32*)T2[a[0][1]]) ^ *((word32*)T3[a[1][2]]) ^ *((word32*)T4[a[2][3]]); *((word32*)a[0]) = *((word32*)temp[0]) ^ *((word32*)rk[r][0]); *((word32*)a[1]) = *((word32*)temp[1]) ^ *((word32*)rk[r][1]); *((word32*)a[2]) = *((word32*)temp[2]) ^ *((word32*)rk[r][2]); *((word32*)a[3]) = *((word32*)temp[3]) ^ *((word32*)rk[r][3]); } if (rounds == ROUNDS) { /* last round is special */ temp[0][0] = T1[a[0][0]][1]; temp[0][1] = T1[a[1][1]][1]; temp[0][2] = T1[a[2][2]][1]; temp[0][3] = T1[a[3][3]][1]; temp[1][0] = T1[a[1][0]][1]; temp[1][1] = T1[a[2][1]][1]; temp[1][2] = T1[a[3][2]][1]; temp[1][3] = T1[a[0][3]][1]; temp[2][0] = T1[a[2][0]][1]; temp[2][1] = T1[a[3][1]][1]; temp[2][2] = T1[a[0][2]][1]; temp[2][3] = T1[a[1][3]][1]; temp[3][0] = T1[a[3][0]][1]; temp[3][1] = T1[a[0][1]][1]; temp[3][2] = T1[a[1][2]][1]; temp[3][3] = T1[a[2][3]][1]; *((word32*)a[0]) = *((word32*)temp[0]) ^ *((word32*)rk[ROUNDS][0]); *((word32*)a[1]) = *((word32*)temp[1]) ^ *((word32*)rk[ROUNDS][1]); *((word32*)a[2]) = *((word32*)temp[2]) ^ *((word32*)rk[ROUNDS][2]); *((word32*)a[3]) = *((word32*)temp[3]) ^ *((word32*)rk[ROUNDS][3]); } return 0; } #endif /* INTERMEDIATE_VALUE_KAT */ /** * Decrypt a single block. */ int rijndaelDecrypt(word8 a[16], word8 b[16], word8 rk[MAXROUNDS+1][4][4], int ROUNDS) { int r; word8 temp[4][4]; *((word32*)temp[0]) = *((word32*)(a )) ^ *((word32*)rk[ROUNDS][0]); *((word32*)temp[1]) = *((word32*)(a+ 4)) ^ *((word32*)rk[ROUNDS][1]); *((word32*)temp[2]) = *((word32*)(a+ 8)) ^ *((word32*)rk[ROUNDS][2]); *((word32*)temp[3]) = *((word32*)(a+12)) ^ *((word32*)rk[ROUNDS][3]); *((word32*)(b )) = *((word32*)T5[temp[0][0]]) ^ *((word32*)T6[temp[3][1]]) ^ *((word32*)T7[temp[2][2]]) ^ *((word32*)T8[temp[1][3]]); *((word32*)(b+ 4)) = *((word32*)T5[temp[1][0]]) ^ *((word32*)T6[temp[0][1]]) ^ *((word32*)T7[temp[3][2]]) ^ *((word32*)T8[temp[2][3]]); *((word32*)(b+ 8)) = *((word32*)T5[temp[2][0]]) ^ *((word32*)T6[temp[1][1]]) ^ *((word32*)T7[temp[0][2]]) ^ *((word32*)T8[temp[3][3]]); *((word32*)(b+12)) = *((word32*)T5[temp[3][0]]) ^ *((word32*)T6[temp[2][1]]) ^ *((word32*)T7[temp[1][2]]) ^ *((word32*)T8[temp[0][3]]); for (r = ROUNDS-1; r > 1; r--) { *((word32*)temp[0]) = *((word32*)(b )) ^ *((word32*)rk[r][0]); *((word32*)temp[1]) = *((word32*)(b+ 4)) ^ *((word32*)rk[r][1]); *((word32*)temp[2]) = *((word32*)(b+ 8)) ^ *((word32*)rk[r][2]); *((word32*)temp[3]) = *((word32*)(b+12)) ^ *((word32*)rk[r][3]); *((word32*)(b )) = *((word32*)T5[temp[0][0]]) ^ *((word32*)T6[temp[3][1]]) ^ *((word32*)T7[temp[2][2]]) ^ *((word32*)T8[temp[1][3]]); *((word32*)(b+ 4)) = *((word32*)T5[temp[1][0]]) ^ *((word32*)T6[temp[0][1]]) ^ *((word32*)T7[temp[3][2]]) ^ *((word32*)T8[temp[2][3]]); *((word32*)(b+ 8)) = *((word32*)T5[temp[2][0]]) ^ *((word32*)T6[temp[1][1]]) ^ *((word32*)T7[temp[0][2]]) ^ *((word32*)T8[temp[3][3]]); *((word32*)(b+12)) = *((word32*)T5[temp[3][0]]) ^ *((word32*)T6[temp[2][1]]) ^ *((word32*)T7[temp[1][2]]) ^ *((word32*)T8[temp[0][3]]); } /* last round is special */ *((word32*)temp[0]) = *((word32*)(b )) ^ *((word32*)rk[1][0]); *((word32*)temp[1]) = *((word32*)(b+ 4)) ^ *((word32*)rk[1][1]); *((word32*)temp[2]) = *((word32*)(b+ 8)) ^ *((word32*)rk[1][2]); *((word32*)temp[3]) = *((word32*)(b+12)) ^ *((word32*)rk[1][3]); b[ 0] = S5[temp[0][0]]; b[ 1] = S5[temp[3][1]]; b[ 2] = S5[temp[2][2]]; b[ 3] = S5[temp[1][3]]; b[ 4] = S5[temp[1][0]]; b[ 5] = S5[temp[0][1]]; b[ 6] = S5[temp[3][2]]; b[ 7] = S5[temp[2][3]]; b[ 8] = S5[temp[2][0]]; b[ 9] = S5[temp[1][1]]; b[10] = S5[temp[0][2]]; b[11] = S5[temp[3][3]]; b[12] = S5[temp[3][0]]; b[13] = S5[temp[2][1]]; b[14] = S5[temp[1][2]]; b[15] = S5[temp[0][3]]; *((word32*)(b )) ^= *((word32*)rk[0][0]); *((word32*)(b+ 4)) ^= *((word32*)rk[0][1]); *((word32*)(b+ 8)) ^= *((word32*)rk[0][2]); *((word32*)(b+12)) ^= *((word32*)rk[0][3]); return 0; } #ifdef INTERMEDIATE_VALUE_KAT /** * Decrypt only a certain number of rounds. * Only used in the Intermediate Value Known Answer Test. * Operations rearranged such that the intermediate values * of decryption correspond with the intermediate values * of encryption. */ int rijndaelDecryptRound(word8 a[4][4], word8 rk[MAXROUNDS+1][4][4], int ROUNDS, int rounds) { int r, i; word8 temp[4], shift; /* make number of rounds sane */ if (rounds > ROUNDS) { rounds = ROUNDS; } /* first round is special: */ *(word32 *)a[0] ^= *(word32 *)rk[ROUNDS][0]; *(word32 *)a[1] ^= *(word32 *)rk[ROUNDS][1]; *(word32 *)a[2] ^= *(word32 *)rk[ROUNDS][2]; *(word32 *)a[3] ^= *(word32 *)rk[ROUNDS][3]; for (i = 0; i < 4; i++) { a[i][0] = Si[a[i][0]]; a[i][1] = Si[a[i][1]]; a[i][2] = Si[a[i][2]]; a[i][3] = Si[a[i][3]]; } for (i = 1; i < 4; i++) { shift = (4 - i) & 3; temp[0] = a[(0 + shift) & 3][i]; temp[1] = a[(1 + shift) & 3][i]; temp[2] = a[(2 + shift) & 3][i]; temp[3] = a[(3 + shift) & 3][i]; a[0][i] = temp[0]; a[1][i] = temp[1]; a[2][i] = temp[2]; a[3][i] = temp[3]; } /* ROUNDS-1 ordinary rounds */ for (r = ROUNDS-1; r > rounds; r--) { *(word32 *)a[0] ^= *(word32 *)rk[r][0]; *(word32 *)a[1] ^= *(word32 *)rk[r][1]; *(word32 *)a[2] ^= *(word32 *)rk[r][2]; *(word32 *)a[3] ^= *(word32 *)rk[r][3]; *((word32*)a[0]) = *((word32*)U1[a[0][0]]) ^ *((word32*)U2[a[0][1]]) ^ *((word32*)U3[a[0][2]]) ^ *((word32*)U4[a[0][3]]); *((word32*)a[1]) = *((word32*)U1[a[1][0]]) ^ *((word32*)U2[a[1][1]]) ^ *((word32*)U3[a[1][2]]) ^ *((word32*)U4[a[1][3]]); *((word32*)a[2]) = *((word32*)U1[a[2][0]]) ^ *((word32*)U2[a[2][1]]) ^ *((word32*)U3[a[2][2]]) ^ *((word32*)U4[a[2][3]]); *((word32*)a[3]) = *((word32*)U1[a[3][0]]) ^ *((word32*)U2[a[3][1]]) ^ *((word32*)U3[a[3][2]]) ^ *((word32*)U4[a[3][3]]); for (i = 0; i < 4; i++) { a[i][0] = Si[a[i][0]]; a[i][1] = Si[a[i][1]]; a[i][2] = Si[a[i][2]]; a[i][3] = Si[a[i][3]]; } for (i = 1; i < 4; i++) { shift = (4 - i) & 3; temp[0] = a[(0 + shift) & 3][i]; temp[1] = a[(1 + shift) & 3][i]; temp[2] = a[(2 + shift) & 3][i]; temp[3] = a[(3 + shift) & 3][i]; a[0][i] = temp[0]; a[1][i] = temp[1]; a[2][i] = temp[2]; a[3][i] = temp[3]; } } if (rounds == 0) { /* End with the extra key addition */ *(word32 *)a[0] ^= *(word32 *)rk[0][0]; *(word32 *)a[1] ^= *(word32 *)rk[0][1]; *(word32 *)a[2] ^= *(word32 *)rk[0][2]; *(word32 *)a[3] ^= *(word32 *)rk[0][3]; } return 0; } #endif /* INTERMEDIATE_VALUE_KAT */ uclmmbase-1.2.16.0/src/rijndael-alg-fst.h0000644000175000017500000000225707272124020016750 0ustar enderender/* * rijndael-alg-fst.h v2.4 April '2000 * * Optimised ANSI C code * * #define INTERMEDIATE_VALUE_KAT to generate the Intermediate Value Known Answer Test. */ #ifndef __RIJNDAEL_ALG_FST_H #define __RIJNDAEL_ALG_FST_H #define BINARY_KEY_MATERIAL #define MAXKC (256/32) #define MAXROUNDS 14 #ifndef USUAL_TYPES #define USUAL_TYPES typedef unsigned char byte; typedef unsigned char word8; typedef unsigned short word16; typedef unsigned int word32; #endif /* USUAL_TYPES */ int rijndaelKeySched(word8 k[MAXKC][4], word8 rk[MAXROUNDS+1][4][4], int ROUNDS); int rijndaelKeyEncToDec(word8 W[MAXROUNDS+1][4][4], int ROUNDS); int rijndaelEncrypt(word8 a[16], word8 b[16], word8 rk[MAXROUNDS+1][4][4], int ROUNDS); #ifdef INTERMEDIATE_VALUE_KAT int rijndaelEncryptRound(word8 a[4][4], word8 rk[MAXROUNDS+1][4][4], int ROUNDS, int rounds); #endif /* INTERMEDIATE_VALUE_KAT */ int rijndaelDecrypt(word8 a[16], word8 b[16], word8 rk[MAXROUNDS+1][4][4], int ROUNDS); #ifdef INTERMEDIATE_VALUE_KAT int rijndaelDecryptRound(word8 a[4][4], word8 rk[MAXROUNDS+1][4][4], int ROUNDS, int rounds); #endif /* INTERMEDIATE_VALUE_KAT */ #endif /* __RIJNDAEL_ALG_FST_H */ uclmmbase-1.2.16.0/src/rijndael-api-fst.c0000644000175000017500000003326207272124020016751 0ustar enderender/* * rijndael-api-fst.c v2.4 April '2000 * * Optimised ANSI C code * * authors: v1.0: Antoon Bosselaers * v2.0: Vincent Rijmen * v2.1: Vincent Rijmen * v2.2: Vincent Rijmen * v2.3: Paulo Barreto * v2.4: Vincent Rijmen * * This code is placed in the public domain. */ #include #include #include #include "rijndael-alg-fst.h" #include "rijndael-api-fst.h" int makeKey(keyInstance *key, BYTE direction, int keyLen, char *keyMaterial) { word8 k[MAXKC][4]; int i; char *keyMat; if (key == NULL) { return BAD_KEY_INSTANCE; } if ((direction == DIR_ENCRYPT) || (direction == DIR_DECRYPT)) { key->direction = direction; } else { return BAD_KEY_DIR; } if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256)) { key->keyLen = keyLen; } else { return BAD_KEY_MAT; } if (keyMaterial != NULL) { strncpy(key->keyMaterial, keyMaterial, keyLen/4); } key->ROUNDS = keyLen/32 + 6; /* initialize key schedule: */ keyMat = key->keyMaterial; #ifndef BINARY_KEY_MATERIAL for (i = 0; i < key->keyLen/8; i++) { int t, j; t = *keyMat++; if ((t >= '0') && (t <= '9')) j = (t - '0') << 4; else if ((t >= 'a') && (t <= 'f')) j = (t - 'a' + 10) << 4; else if ((t >= 'A') && (t <= 'F')) j = (t - 'A' + 10) << 4; else return BAD_KEY_MAT; t = *keyMat++; if ((t >= '0') && (t <= '9')) j ^= (t - '0'); else if ((t >= 'a') && (t <= 'f')) j ^= (t - 'a' + 10); else if ((t >= 'A') && (t <= 'F')) j ^= (t - 'A' + 10); else return BAD_KEY_MAT; k[i >> 2][i & 3] = (word8)j; } #else for (i = 0; i < key->keyLen/8; i++) { k[i >> 2][i & 3] = (word8)keyMat[i]; } #endif /* ?BINARY_KEY_MATERIAL */ rijndaelKeySched(k, key->keySched, key->ROUNDS); if (direction == DIR_DECRYPT) { rijndaelKeyEncToDec(key->keySched, key->ROUNDS); } return TRUE; } int cipherInit(cipherInstance *cipher, BYTE mode, char *IV) { if ((mode == MODE_ECB) || (mode == MODE_CBC) || (mode == MODE_CFB1)) { cipher->mode = mode; } else { return BAD_CIPHER_MODE; } if (IV != NULL) { #ifndef BINARY_KEY_MATERIAL int i; for (i = 0; i < MAX_IV_SIZE; i++) { int t, j; t = IV[2*i]; if ((t >= '0') && (t <= '9')) j = (t - '0') << 4; else if ((t >= 'a') && (t <= 'f')) j = (t - 'a' + 10) << 4; else if ((t >= 'A') && (t <= 'F')) j = (t - 'A' + 10) << 4; else return BAD_CIPHER_INSTANCE; t = IV[2*i+1]; if ((t >= '0') && (t <= '9')) j ^= (t - '0'); else if ((t >= 'a') && (t <= 'f')) j ^= (t - 'a' + 10); else if ((t >= 'A') && (t <= 'F')) j ^= (t - 'A' + 10); else return BAD_CIPHER_INSTANCE; cipher->IV[i] = (word8)j; } #else memcpy(cipher->IV, IV, MAX_IV_SIZE); #endif /* ?BINARY_KEY_MATERIAL */ } else { memset(cipher->IV, 0, MAX_IV_SIZE); } return TRUE; } int blockEncrypt(cipherInstance *cipher, keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer) { int i, k, numBlocks; word8 block[16], iv[4][4]; if (cipher == NULL || key == NULL || key->direction == DIR_DECRYPT) { return BAD_CIPHER_STATE; } if (input == NULL || inputLen <= 0) { return 0; /* nothing to do */ } numBlocks = inputLen/128; switch (cipher->mode) { case MODE_ECB: for (i = numBlocks; i > 0; i--) { rijndaelEncrypt(input, outBuffer, key->keySched, key->ROUNDS); input += 16; outBuffer += 16; } break; case MODE_CBC: ((word32*)block)[0] = ((word32*)cipher->IV)[0] ^ ((word32*)input)[0]; ((word32*)block)[1] = ((word32*)cipher->IV)[1] ^ ((word32*)input)[1]; ((word32*)block)[2] = ((word32*)cipher->IV)[2] ^ ((word32*)input)[2]; ((word32*)block)[3] = ((word32*)cipher->IV)[3] ^ ((word32*)input)[3]; rijndaelEncrypt(block, outBuffer, key->keySched, key->ROUNDS); input += 16; for (i = numBlocks - 1; i > 0; i--) { ((word32*)block)[0] = ((word32*)outBuffer)[0] ^ ((word32*)input)[0]; ((word32*)block)[1] = ((word32*)outBuffer)[1] ^ ((word32*)input)[1]; ((word32*)block)[2] = ((word32*)outBuffer)[2] ^ ((word32*)input)[2]; ((word32*)block)[3] = ((word32*)outBuffer)[3] ^ ((word32*)input)[3]; outBuffer += 16; rijndaelEncrypt(block, outBuffer, key->keySched, key->ROUNDS); input += 16; } break; case MODE_CFB1: #if STRICT_ALIGN memcpy(iv, cipher->IV, 16); #else /* !STRICT_ALIGN */ *((word32*)iv[0]) = *((word32*)(cipher->IV )); *((word32*)iv[1]) = *((word32*)(cipher->IV+ 4)); *((word32*)iv[2]) = *((word32*)(cipher->IV+ 8)); *((word32*)iv[3]) = *((word32*)(cipher->IV+12)); #endif /* ?STRICT_ALIGN */ for (i = numBlocks; i > 0; i--) { for (k = 0; k < 128; k++) { *((word32*) block ) = *((word32*)iv[0]); *((word32*)(block+ 4)) = *((word32*)iv[1]); *((word32*)(block+ 8)) = *((word32*)iv[2]); *((word32*)(block+12)) = *((word32*)iv[3]); rijndaelEncrypt(block, block, key->keySched, key->ROUNDS); outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7); iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7); iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7); iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7); iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7); iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7); iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7); iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7); iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7); iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7); iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7); iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7); iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7); iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7); iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7); iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7); iv[3][3] = (iv[3][3] << 1) | ((outBuffer[k/8] >> (7-(k&7))) & 1); } } break; default: return BAD_CIPHER_STATE; } return 128*numBlocks; } /** * Encrypt data partitioned in octets, using RFC 2040-like padding. * * @param input data to be encrypted (octet sequence) * @param inputOctets input length in octets (not bits) * @param outBuffer encrypted output data * * @return length in octets (not bits) of the encrypted output buffer. */ int padEncrypt(cipherInstance *cipher, keyInstance *key, BYTE *input, int inputOctets, BYTE *outBuffer) { int i, numBlocks, padLen; word8 block[16], *iv; if (cipher == NULL || key == NULL || key->direction == DIR_DECRYPT) { return BAD_CIPHER_STATE; } if (input == NULL || inputOctets <= 0) { return 0; /* nothing to do */ } numBlocks = inputOctets/16; switch (cipher->mode) { case MODE_ECB: for (i = numBlocks; i > 0; i--) { rijndaelEncrypt(input, outBuffer, key->keySched, key->ROUNDS); input += 16; outBuffer += 16; } padLen = 16 - (inputOctets - 16*numBlocks); assert(padLen > 0 && padLen <= 16); memcpy(block, input, 16 - padLen); memset(block + 16 - padLen, padLen, padLen); rijndaelEncrypt(block, outBuffer, key->keySched, key->ROUNDS); break; case MODE_CBC: iv = cipher->IV; for (i = numBlocks; i > 0; i--) { ((word32*)block)[0] = ((word32*)input)[0] ^ ((word32*)iv)[0]; ((word32*)block)[1] = ((word32*)input)[1] ^ ((word32*)iv)[1]; ((word32*)block)[2] = ((word32*)input)[2] ^ ((word32*)iv)[2]; ((word32*)block)[3] = ((word32*)input)[3] ^ ((word32*)iv)[3]; rijndaelEncrypt(block, outBuffer, key->keySched, key->ROUNDS); iv = outBuffer; input += 16; outBuffer += 16; } padLen = 16 - (inputOctets - 16*numBlocks); assert(padLen > 0 && padLen <= 16); for (i = 0; i < 16 - padLen; i++) { block[i] = input[i] ^ iv[i]; } for (i = 16 - padLen; i < 16; i++) { block[i] = (BYTE)padLen ^ iv[i]; } rijndaelEncrypt(block, outBuffer, key->keySched, key->ROUNDS); break; default: return BAD_CIPHER_STATE; } return 16*(numBlocks + 1); } int blockDecrypt(cipherInstance *cipher, keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer) { int i, k, numBlocks; word8 block[16], iv[4][4]; if (cipher == NULL || key == NULL || (cipher->mode != MODE_CFB1 && key->direction == DIR_ENCRYPT)) { return BAD_CIPHER_STATE; } if (input == NULL || inputLen <= 0) { return 0; /* nothing to do */ } numBlocks = inputLen/128; switch (cipher->mode) { case MODE_ECB: for (i = numBlocks; i > 0; i--) { rijndaelDecrypt(input, outBuffer, key->keySched, key->ROUNDS); input += 16; outBuffer += 16; } break; case MODE_CBC: #if STRICT_ALIGN memcpy(iv, cipher->IV, 16); #else *((word32*)iv[0]) = *((word32*)(cipher->IV )); *((word32*)iv[1]) = *((word32*)(cipher->IV+ 4)); *((word32*)iv[2]) = *((word32*)(cipher->IV+ 8)); *((word32*)iv[3]) = *((word32*)(cipher->IV+12)); #endif for (i = numBlocks; i > 0; i--) { rijndaelDecrypt(input, block, key->keySched, key->ROUNDS); ((word32*)block)[0] ^= *((word32*)iv[0]); ((word32*)block)[1] ^= *((word32*)iv[1]); ((word32*)block)[2] ^= *((word32*)iv[2]); ((word32*)block)[3] ^= *((word32*)iv[3]); #if STRICT_ALIGN memcpy(iv, input, 16); memcpy(outBuf, block, 16); #else *((word32*)iv[0]) = ((word32*)input)[0]; ((word32*)outBuffer)[0] = ((word32*)block)[0]; *((word32*)iv[1]) = ((word32*)input)[1]; ((word32*)outBuffer)[1] = ((word32*)block)[1]; *((word32*)iv[2]) = ((word32*)input)[2]; ((word32*)outBuffer)[2] = ((word32*)block)[2]; *((word32*)iv[3]) = ((word32*)input)[3]; ((word32*)outBuffer)[3] = ((word32*)block)[3]; #endif input += 16; outBuffer += 16; } break; case MODE_CFB1: #if STRICT_ALIGN memcpy(iv, cipher->IV, 16); #else *((word32*)iv[0]) = *((word32*)(cipher->IV)); *((word32*)iv[1]) = *((word32*)(cipher->IV+ 4)); *((word32*)iv[2]) = *((word32*)(cipher->IV+ 8)); *((word32*)iv[3]) = *((word32*)(cipher->IV+12)); #endif for (i = numBlocks; i > 0; i--) { for (k = 0; k < 128; k++) { *((word32*) block ) = *((word32*)iv[0]); *((word32*)(block+ 4)) = *((word32*)iv[1]); *((word32*)(block+ 8)) = *((word32*)iv[2]); *((word32*)(block+12)) = *((word32*)iv[3]); rijndaelEncrypt(block, block, key->keySched, key->ROUNDS); iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7); iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7); iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7); iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7); iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7); iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7); iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7); iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7); iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7); iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7); iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7); iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7); iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7); iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7); iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7); iv[3][3] = (iv[3][3] << 1) | ((input[k/8] >> (7-(k&7))) & 1); outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7); } } break; default: return BAD_CIPHER_STATE; } return 128*numBlocks; } int padDecrypt(cipherInstance *cipher, keyInstance *key, BYTE *input, int inputOctets, BYTE *outBuffer) { int i, numBlocks, padLen; word8 block[16]; word32 iv[4]; if (cipher == NULL || key == NULL || key->direction == DIR_ENCRYPT) { return BAD_CIPHER_STATE; } if (input == NULL || inputOctets <= 0) { return 0; /* nothing to do */ } if (inputOctets % 16 != 0) { return BAD_DATA; } numBlocks = inputOctets/16; switch (cipher->mode) { case MODE_ECB: /* all blocks but last */ for (i = numBlocks - 1; i > 0; i--) { rijndaelDecrypt(input, outBuffer, key->keySched, key->ROUNDS); input += 16; outBuffer += 16; } /* last block */ rijndaelDecrypt(input, block, key->keySched, key->ROUNDS); padLen = block[15]; if (padLen >= 16) { return BAD_DATA; } for (i = 16 - padLen; i < 16; i++) { if (block[i] != padLen) { return BAD_DATA; } } memcpy(outBuffer, block, 16 - padLen); break; case MODE_CBC: memcpy(iv, cipher->IV, 16); /* all blocks but last */ for (i = numBlocks - 1; i > 0; i--) { rijndaelDecrypt(input, block, key->keySched, key->ROUNDS); ((word32*)block)[0] ^= iv[0]; ((word32*)block)[1] ^= iv[1]; ((word32*)block)[2] ^= iv[2]; ((word32*)block)[3] ^= iv[3]; memcpy(iv, input, 16); memcpy(outBuffer, block, 16); input += 16; outBuffer += 16; } /* last block */ rijndaelDecrypt(input, block, key->keySched, key->ROUNDS); ((word32*)block)[0] ^= iv[0]; ((word32*)block)[1] ^= iv[1]; ((word32*)block)[2] ^= iv[2]; ((word32*)block)[3] ^= iv[3]; padLen = block[15]; if (padLen <= 0 || padLen > 16) { return BAD_DATA; } for (i = 16 - padLen; i < 16; i++) { if (block[i] != padLen) { return BAD_DATA; } } memcpy(outBuffer, block, 16 - padLen); break; default: return BAD_CIPHER_STATE; } return 16*numBlocks - padLen; } #ifdef INTERMEDIATE_VALUE_KAT /** * cipherUpdateRounds: * * Encrypts/Decrypts exactly one full block a specified number of rounds. * Only used in the Intermediate Value Known Answer Test. * * Returns: * TRUE - on success * BAD_CIPHER_STATE - cipher in bad state (e.g., not initialized) */ int cipherUpdateRounds(cipherInstance *cipher, keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer, int rounds) { int j; word8 block[4][4]; if (cipher == NULL || key == NULL) { return BAD_CIPHER_STATE; } for (j = 3; j >= 0; j--) { /* parse input stream into rectangular array */ *((word32*)block[j]) = *((word32*)(input+4*j)); } switch (key->direction) { case DIR_ENCRYPT: rijndaelEncryptRound(block, key->keySched, key->ROUNDS, rounds); break; case DIR_DECRYPT: rijndaelDecryptRound(block, key->keySched, key->ROUNDS, rounds); break; default: return BAD_KEY_DIR; } for (j = 3; j >= 0; j--) { /* parse rectangular array into output ciphertext bytes */ *((word32*)(outBuffer+4*j)) = *((word32*)block[j]); } return TRUE; } #endif /* INTERMEDIATE_VALUE_KAT */ uclmmbase-1.2.16.0/src/rijndael-api-fst.h0000644000175000017500000001025507272124020016753 0ustar enderender/* * rijndael-api-fst.h v2.4 April '2000 * * Optimised ANSI C code * * #define INTERMEDIATE_VALUE_KAT to generate the Intermediate Value Known Answer Test. */ #ifndef __RIJNDAEL_API_FST_H #define __RIJNDAEL_API_FST_H #include #include "rijndael-alg-fst.h" /* Defines: Add any additional defines you need */ #define DIR_ENCRYPT 0 /* Are we encrpyting? */ #define DIR_DECRYPT 1 /* Are we decrpyting? */ #define MODE_ECB 1 /* Are we ciphering in ECB mode? */ #define MODE_CBC 2 /* Are we ciphering in CBC mode? */ #define MODE_CFB1 3 /* Are we ciphering in 1-bit CFB mode? */ #define TRUE 1 #define FALSE 0 #define BITSPERBLOCK 128 /* Default number of bits in a cipher block */ /* Error Codes - CHANGE POSSIBLE: inclusion of additional error codes */ #define BAD_KEY_DIR -1 /* Key direction is invalid, e.g., unknown value */ #define BAD_KEY_MAT -2 /* Key material not of correct length */ #define BAD_KEY_INSTANCE -3 /* Key passed is not valid */ #define BAD_CIPHER_MODE -4 /* Params struct passed to cipherInit invalid */ #define BAD_CIPHER_STATE -5 /* Cipher in wrong state (e.g., not initialized) */ #define BAD_BLOCK_LENGTH -6 #define BAD_CIPHER_INSTANCE -7 #define BAD_DATA -8 /* Data contents are invalid, e.g., invalid padding */ #define BAD_OTHER -9 /* Unknown error */ /* CHANGE POSSIBLE: inclusion of algorithm specific defines */ #define MAX_KEY_SIZE 64 /* # of ASCII char's needed to represent a key */ #define MAX_IV_SIZE 16 /* # bytes needed to represent an IV */ /* Typedefs: Typedef'ed data storage elements. Add any algorithm specific parameters at the bottom of the structs as appropriate. */ typedef unsigned char BYTE; /* The structure for key information */ typedef struct { BYTE direction; /* Key used for encrypting or decrypting? */ int keyLen; /* Length of the key */ char keyMaterial[MAX_KEY_SIZE+1]; /* Raw key data in ASCII, e.g., user input or KAT values */ /* The following parameters are algorithm dependent, replace or add as necessary */ int ROUNDS; /* key-length-dependent number of rounds */ int blockLen; /* block length */ word8 keySched[MAXROUNDS+1][4][4]; /* key schedule */ } keyInstance; /* The structure for cipher information */ typedef struct { /* changed order of the components */ BYTE mode; /* MODE_ECB, MODE_CBC, or MODE_CFB1 */ BYTE IV[MAX_IV_SIZE]; /* A possible Initialization Vector for ciphering */ /* Add any algorithm specific parameters needed here */ int blockLen; /* Sample: Handles non-128 bit block sizes (if available) */ } cipherInstance; /* Function prototypes */ /* CHANGED: nothing TODO: implement the following extensions to setup 192-bit and 256-bit block lengths: makeKeyEx(): parameter blockLen added -- this parameter is absolutely necessary if you want to setup the round keys in a variable block length setting cipherInitEx(): parameter blockLen added (for obvious reasons) */ int makeKey(keyInstance *key, BYTE direction, int keyLen, char *keyMaterial); int cipherInit(cipherInstance *cipher, BYTE mode, char *IV); int blockEncrypt(cipherInstance *cipher, keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer); int padEncrypt(cipherInstance *cipher, keyInstance *key, BYTE *input, int inputOctets, BYTE *outBuffer); int blockDecrypt(cipherInstance *cipher, keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer); int padDecrypt(cipherInstance *cipher, keyInstance *key, BYTE *input, int inputOctets, BYTE *outBuffer); #ifdef INTERMEDIATE_VALUE_KAT int cipherUpdateRounds(cipherInstance *cipher, keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer, int Rounds); #endif /* INTERMEDIATE_VALUE_KAT */ #endif /* __RIJNDAEL_API_FST_H */ uclmmbase-1.2.16.0/src/rtp.c0000640000175000017500000032030507456653305014437 0ustar enderender/* * FILE: rtp.c * AUTHOR: Colin Perkins * MODIFIED: Orion Hodson * Markus Germeier * Bill Fenner * Timur Friedman * * The routines in this file implement the Real-time Transport Protocol, * RTP, as specified in RFC1889 with current updates under discussion in * the IETF audio/video transport working group. Portions of the code are * derived from the algorithms published in that specification. * * $Revision: 1.139 $ * $Date: 2002/04/15 22:40:05 $ * * Copyright (c) 1998-2001 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Science * Department at University College London. * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. * */ #include "config_unix.h" #include "config_win32.h" #include "memory.h" #include "debug.h" #include "net_udp.h" #include "crypt_random.h" #include "rijndael-api-fst.h" #include "drand48.h" #include "gettimeofday.h" #include "qfDES.h" #include "md5.h" #include "ntp.h" #include "rtp.h" /* * Encryption stuff. */ #define MAX_ENCRYPTION_PAD 16 static int rijndael_initialize(struct rtp *session, u_char *hash, int hash_len); static int rijndael_decrypt(struct rtp *session, unsigned char *data, unsigned int size, unsigned char *initVec); static int rijndael_encrypt(struct rtp *session, unsigned char *data, unsigned int size, unsigned char *initVec); static int des_initialize(struct rtp *session, u_char *hash, int hash_len); static int des_decrypt(struct rtp *session, unsigned char *data, unsigned int size, unsigned char *initVec); static int des_encrypt(struct rtp *session, unsigned char *data, unsigned int size, unsigned char *initVec); #define MAX_DROPOUT 3000 #define MAX_MISORDER 100 #define MIN_SEQUENTIAL 2 /* * Definitions for the RTP/RTCP packets on the wire... */ #define RTP_SEQ_MOD 0x10000 #define RTP_MAX_SDES_LEN 256 #define RTP_LOWER_LAYER_OVERHEAD 28 /* IPv4 + UDP */ #define RTCP_SR 200 #define RTCP_RR 201 #define RTCP_SDES 202 #define RTCP_BYE 203 #define RTCP_APP 204 typedef struct { #ifdef WORDS_BIGENDIAN unsigned short version:2; /* packet type */ unsigned short p:1; /* padding flag */ unsigned short count:5; /* varies by payload type */ unsigned short pt:8; /* payload type */ #else unsigned short count:5; /* varies by payload type */ unsigned short p:1; /* padding flag */ unsigned short version:2; /* packet type */ unsigned short pt:8; /* payload type */ #endif uint16_t length; /* packet length */ } rtcp_common; typedef struct { rtcp_common common; union { struct { rtcp_sr sr; rtcp_rr rr[1]; /* variable-length list */ } sr; struct { uint32_t ssrc; /* source this RTCP packet is coming from */ rtcp_rr rr[1]; /* variable-length list */ } rr; struct rtcp_sdes_t { uint32_t ssrc; rtcp_sdes_item item[1]; /* list of SDES */ } sdes; struct { uint32_t ssrc[1]; /* list of sources */ /* can't express the trailing text... */ } bye; struct { uint32_t ssrc; uint8_t name[4]; uint8_t data[1]; } app; } r; } rtcp_t; typedef struct _rtcp_rr_wrapper { struct _rtcp_rr_wrapper *next; struct _rtcp_rr_wrapper *prev; uint32_t reporter_ssrc; rtcp_rr *rr; struct timeval *ts; /* Arrival time of this RR */ } rtcp_rr_wrapper; /* * The RTP database contains source-specific information needed * to make it all work. */ typedef struct _source { struct _source *next; struct _source *prev; uint32_t ssrc; char *cname; char *name; char *email; char *phone; char *loc; char *tool; char *note; char *priv; rtcp_sr *sr; struct timeval last_sr; struct timeval last_active; int should_advertise_sdes; /* TRUE if this source is a CSRC which we need to advertise SDES for */ int sender; int got_bye; /* TRUE if we've received an RTCP bye from this source */ uint32_t base_seq; uint16_t max_seq; uint32_t bad_seq; uint32_t cycles; int received; int received_prior; int expected_prior; int probation; uint32_t jitter; uint32_t transit; uint32_t magic; /* For debugging... */ } source; /* The size of the hash table used to hold the source database. */ /* Should be large enough that we're unlikely to get collisions */ /* when sources are added, but not too large that we waste too */ /* much memory. Sedgewick ("Algorithms", 2nd Ed, Addison-Wesley */ /* 1988) suggests that this should be around 1/10th the number */ /* of entries that we expect to have in the database and should */ /* be a prime number. Everything continues to work if this is */ /* too low, it just goes slower... for now we assume around 100 */ /* participants is a sensible limit so we set this to 11. */ #define RTP_DB_SIZE 11 /* * Options for an RTP session are stored in the "options" struct. */ typedef struct { int promiscuous_mode; int wait_for_rtcp; int filter_my_packets; int reuse_bufs; } options; /* * Encryption function types */ typedef int (*rtp_encrypt_func)(struct rtp *, unsigned char *data, unsigned int size, unsigned char *initvec); typedef int (*rtp_decrypt_func)(struct rtp *, unsigned char *data, unsigned int size, unsigned char *initvec); /* * The "struct rtp" defines an RTP session. */ struct rtp { socket_udp *rtp_socket; socket_udp *rtcp_socket; char *addr; uint16_t rx_port; uint16_t tx_port; int ttl; uint32_t my_ssrc; int last_advertised_csrc; source *db[RTP_DB_SIZE]; rtcp_rr_wrapper rr[RTP_DB_SIZE][RTP_DB_SIZE]; /* Indexed by [hash(reporter)][hash(reportee)] */ options *opt; uint8_t *userdata; int invalid_rtp_count; int invalid_rtcp_count; int bye_count; int csrc_count; int ssrc_count; int ssrc_count_prev; /* ssrc_count at the time we last recalculated our RTCP interval */ int sender_count; int initial_rtcp; int sending_bye; /* TRUE if we're in the process of sending a BYE packet */ double avg_rtcp_size; int we_sent; double rtcp_bw; /* RTCP bandwidth fraction, in octets per second. */ struct timeval last_update; struct timeval last_rtp_send_time; struct timeval last_rtcp_send_time; struct timeval next_rtcp_send_time; double rtcp_interval; int sdes_count_pri; int sdes_count_sec; int sdes_count_ter; uint16_t rtp_seq; uint32_t rtp_pcount; uint32_t rtp_bcount; char *encryption_algorithm; int encryption_enabled; rtp_encrypt_func encrypt_func; rtp_decrypt_func decrypt_func; int encryption_pad_length; union { struct { keyInstance keyInstEncrypt; keyInstance keyInstDecrypt; cipherInstance cipherInst; } rijndael; struct { char *encryption_key; } des; } crypto_state; rtp_callback callback; uint32_t magic; /* For debugging... */ }; static inline int filter_event(struct rtp *session, uint32_t ssrc) { return session->opt->filter_my_packets && (ssrc == rtp_my_ssrc(session)); } static inline double tv_diff(struct timeval curr_time, struct timeval prev_time) { /* Return curr_time - prev_time */ double ct, pt; ct = (double) curr_time.tv_sec + (((double) curr_time.tv_usec) / 1000000.0); pt = (double) prev_time.tv_sec + (((double) prev_time.tv_usec) / 1000000.0); return (ct - pt); } static void tv_add(struct timeval *ts, double offset) { /* Add offset seconds to ts */ double offset_sec, offset_usec; offset_usec = modf(offset, &offset_sec) * 1000000; ts->tv_sec += (long) offset_sec; ts->tv_usec += (long) offset_usec; if (ts->tv_usec > 1000000) { ts->tv_sec++; ts->tv_usec -= 1000000; } } static int tv_gt(struct timeval a, struct timeval b) { /* Returns (a>b) */ if (a.tv_sec > b.tv_sec) { return TRUE; } if (a.tv_sec < b.tv_sec) { return FALSE; } assert(a.tv_sec == b.tv_sec); return a.tv_usec > b.tv_usec; } static uint32_t next_csrc(struct rtp *session) { /* This returns each source marked "should_advertise_sdes" in turn. */ int chain, cc; source *s; cc = 0; for (chain = 0; chain < RTP_DB_SIZE; chain++) { /* Check that the linked lists making up the chains in */ /* the hash table are correctly linked together... */ for (s = session->db[chain]; s != NULL; s = s->next) { if (s->should_advertise_sdes) { if (cc == session->last_advertised_csrc) { session->last_advertised_csrc++; if (session->last_advertised_csrc == session->csrc_count) { session->last_advertised_csrc = 0; } return s->ssrc; } else { cc++; } } } } /* We should never get here... */ abort(); } static int ssrc_hash(uint32_t ssrc) { /* Hash from an ssrc to a position in the source database. */ /* Assumes that ssrc values are uniformly distributed, which */ /* should be true but probably isn't (Rosenberg has reported */ /* that many implementations generate ssrc values which are */ /* not uniformly distributed over the space, and the H.323 */ /* spec requires that they are non-uniformly distributed). */ /* This routine is written as a function rather than inline */ /* code to allow it to be made smart in future: probably we */ /* should run MD5 on the ssrc and derive a hash value from */ /* that, to ensure it's more uniformly distributed? */ return ssrc % RTP_DB_SIZE; } static void insert_rr(struct rtp *session, uint32_t reporter_ssrc, rtcp_rr *rr, struct timeval *ts) { /* Insert the reception report into the receiver report */ /* database. This database is a two dimensional table of */ /* rr_wrappers indexed by hashes of reporter_ssrc and */ /* reportee_src. The rr_wrappers in the database are */ /* sentinels to reduce conditions in list operations. */ /* The ts is used to determine when to timeout this rr. */ rtcp_rr_wrapper *cur, *start; start = &session->rr[ssrc_hash(reporter_ssrc)][ssrc_hash(rr->ssrc)]; cur = start->next; while (cur != start) { if (cur->reporter_ssrc == reporter_ssrc && cur->rr->ssrc == rr->ssrc) { /* Replace existing entry in the database */ xfree(cur->rr); xfree(cur->ts); cur->rr = rr; cur->ts = (struct timeval *) xmalloc(sizeof(struct timeval)); memcpy(cur->ts, ts, sizeof(struct timeval)); return; } cur = cur->next; } /* No entry in the database so create one now. */ cur = (rtcp_rr_wrapper*)xmalloc(sizeof(rtcp_rr_wrapper)); cur->reporter_ssrc = reporter_ssrc; cur->rr = rr; cur->ts = (struct timeval *) xmalloc(sizeof(struct timeval)); memcpy(cur->ts, ts, sizeof(struct timeval)); /* Fix links */ cur->next = start->next; cur->next->prev = cur; cur->prev = start; cur->prev->next = cur; debug_msg("Created new rr entry for 0x%08lx from source 0x%08lx\n", rr->ssrc, reporter_ssrc); return; } static void remove_rr(struct rtp *session, uint32_t ssrc) { /* Remove any RRs from "s" which refer to "ssrc" as either */ /* reporter or reportee. */ rtcp_rr_wrapper *start, *cur, *tmp; int i; /* Remove rows, i.e. ssrc == reporter_ssrc */ for(i = 0; i < RTP_DB_SIZE; i++) { start = &session->rr[ssrc_hash(ssrc)][i]; cur = start->next; while (cur != start) { if (cur->reporter_ssrc == ssrc) { tmp = cur; cur = cur->prev; tmp->prev->next = tmp->next; tmp->next->prev = tmp->prev; xfree(tmp->ts); xfree(tmp->rr); xfree(tmp); } cur = cur->next; } } /* Remove columns, i.e. ssrc == reporter_ssrc */ for(i = 0; i < RTP_DB_SIZE; i++) { start = &session->rr[i][ssrc_hash(ssrc)]; cur = start->next; while (cur != start) { if (cur->rr->ssrc == ssrc) { tmp = cur; cur = cur->prev; tmp->prev->next = tmp->next; tmp->next->prev = tmp->prev; xfree(tmp->ts); xfree(tmp->rr); xfree(tmp); } cur = cur->next; } } } static void timeout_rr(struct rtp *session, struct timeval *curr_ts) { /* Timeout any reception reports which have been in the database for more than 3 */ /* times the RTCP reporting interval without refresh. */ rtcp_rr_wrapper *start, *cur, *tmp; rtp_event event; int i, j; for(i = 0; i < RTP_DB_SIZE; i++) { for(j = 0; j < RTP_DB_SIZE; j++) { start = &session->rr[i][j]; cur = start->next; while (cur != start) { if (tv_diff(*curr_ts, *(cur->ts)) > (session->rtcp_interval * 3)) { /* Signal the application... */ if (!filter_event(session, cur->reporter_ssrc)) { event.ssrc = cur->reporter_ssrc; event.type = RR_TIMEOUT; event.data = cur->rr; event.ts = curr_ts; session->callback(session, &event); } /* Delete this reception report... */ tmp = cur; cur = cur->prev; tmp->prev->next = tmp->next; tmp->next->prev = tmp->prev; xfree(tmp->ts); xfree(tmp->rr); xfree(tmp); } cur = cur->next; } } } } static const rtcp_rr* get_rr(struct rtp *session, uint32_t reporter_ssrc, uint32_t reportee_ssrc) { rtcp_rr_wrapper *cur, *start; start = &session->rr[ssrc_hash(reporter_ssrc)][ssrc_hash(reportee_ssrc)]; cur = start->next; while (cur != start) { if (cur->reporter_ssrc == reporter_ssrc && cur->rr->ssrc == reportee_ssrc) { return cur->rr; } cur = cur->next; } return NULL; } static inline void check_source(source *s) { #ifdef DEBUG assert(s != NULL); assert(s->magic == 0xc001feed); #else UNUSED(s); #endif } static inline void check_database(struct rtp *session) { /* This routine performs a sanity check on the database. */ /* This should not call any of the other routines which */ /* manipulate the database, to avoid common failures. */ #ifdef DEBUG source *s; int source_count; int chain; assert(session != NULL); assert(session->magic == 0xfeedface); /* Check that we have a database entry for our ssrc... */ /* We only do this check if ssrc_count > 0 since it is */ /* performed during initialisation whilst creating the */ /* source entry for my_ssrc. */ if (session->ssrc_count > 0) { for (s = session->db[ssrc_hash(session->my_ssrc)]; s != NULL; s = s->next) { if (s->ssrc == session->my_ssrc) { break; } } assert(s != NULL); } source_count = 0; for (chain = 0; chain < RTP_DB_SIZE; chain++) { /* Check that the linked lists making up the chains in */ /* the hash table are correctly linked together... */ for (s = session->db[chain]; s != NULL; s = s->next) { check_source(s); source_count++; if (s->prev == NULL) { assert(s == session->db[chain]); } else { assert(s->prev->next == s); } if (s->next != NULL) { assert(s->next->prev == s); } /* Check that the SR is for this source... */ if (s->sr != NULL) { assert(s->sr->ssrc == s->ssrc); } } } /* Check that the number of entries in the hash table */ /* matches session->ssrc_count */ assert(source_count == session->ssrc_count); #else UNUSED(session); #endif } static inline source * get_source(struct rtp *session, uint32_t ssrc) { source *s; check_database(session); for (s = session->db[ssrc_hash(ssrc)]; s != NULL; s = s->next) { if (s->ssrc == ssrc) { check_source(s); return s; } } return NULL; } static source * create_source(struct rtp *session, uint32_t ssrc, int probation) { /* Create a new source entry, and add it to the database. */ /* The database is a hash table, using the separate chaining */ /* algorithm. */ rtp_event event; struct timeval event_ts; source *s = get_source(session, ssrc); int h; if (s != NULL) { /* Source is already in the database... Mark it as */ /* active and exit (this is the common case...) */ gettimeofday(&(s->last_active), NULL); return s; } check_database(session); /* This is a new source, we have to create it... */ h = ssrc_hash(ssrc); s = (source *) xmalloc(sizeof(source)); memset(s, 0, sizeof(source)); s->magic = 0xc001feed; s->next = session->db[h]; s->ssrc = ssrc; if (probation) { /* This is a probationary source, which only counts as */ /* valid once several consecutive packets are received */ s->probation = -1; } else { s->probation = 0; } gettimeofday(&(s->last_active), NULL); /* Now, add it to the database... */ if (session->db[h] != NULL) { session->db[h]->prev = s; } session->db[ssrc_hash(ssrc)] = s; session->ssrc_count++; check_database(session); debug_msg("Created database entry for ssrc 0x%08lx (%d valid sources)\n", ssrc, session->ssrc_count); if (ssrc != session->my_ssrc) { /* Do not send during rtp_init since application cannot map the address */ /* of the rtp session to anything since rtp_init has not returned yet. */ if (!filter_event(session, ssrc)) { gettimeofday(&event_ts, NULL); event.ssrc = ssrc; event.type = SOURCE_CREATED; event.data = NULL; event.ts = &event_ts; session->callback(session, &event); } } return s; } static void delete_source(struct rtp *session, uint32_t ssrc) { /* Remove a source from the RTP database... */ source *s = get_source(session, ssrc); int h = ssrc_hash(ssrc); rtp_event event; struct timeval event_ts; assert(s != NULL); /* Deleting a source which doesn't exist is an error... */ gettimeofday(&event_ts, NULL); check_source(s); check_database(session); if (session->db[h] == s) { /* It's the first entry in this chain... */ session->db[h] = s->next; if (s->next != NULL) { s->next->prev = NULL; } } else { assert(s->prev != NULL); /* Else it would be the first in the chain... */ s->prev->next = s->next; if (s->next != NULL) { s->next->prev = s->prev; } } /* Free the memory allocated to a source... */ if (s->cname != NULL) xfree(s->cname); if (s->name != NULL) xfree(s->name); if (s->email != NULL) xfree(s->email); if (s->phone != NULL) xfree(s->phone); if (s->loc != NULL) xfree(s->loc); if (s->tool != NULL) xfree(s->tool); if (s->note != NULL) xfree(s->note); if (s->priv != NULL) xfree(s->priv); if (s->sr != NULL) xfree(s->sr); remove_rr(session, ssrc); /* Reduce our SSRC count, and perform reverse reconsideration on the RTCP */ /* reporting interval (draft-ietf-avt-rtp-new-05.txt, section 6.3.4). To */ /* make the transmission rate of RTCP packets more adaptive to changes in */ /* group membership, the following "reverse reconsideration" algorithm */ /* SHOULD be executed when a BYE packet is received that reduces members */ /* to a value less than pmembers: */ /* o The value for tn is updated according to the following formula: */ /* tn = tc + (members/pmembers)(tn - tc) */ /* o The value for tp is updated according the following formula: */ /* tp = tc - (members/pmembers)(tc - tp). */ /* o The next RTCP packet is rescheduled for transmission at time tn, */ /* which is now earlier. */ /* o The value of pmembers is set equal to members. */ session->ssrc_count--; if (session->ssrc_count < session->ssrc_count_prev) { gettimeofday(&(session->next_rtcp_send_time), NULL); gettimeofday(&(session->last_rtcp_send_time), NULL); tv_add(&(session->next_rtcp_send_time), (session->ssrc_count / session->ssrc_count_prev) * tv_diff(session->next_rtcp_send_time, event_ts)); tv_add(&(session->last_rtcp_send_time), - ((session->ssrc_count / session->ssrc_count_prev) * tv_diff(event_ts, session->last_rtcp_send_time))); session->ssrc_count_prev = session->ssrc_count; } /* Reduce our csrc count... */ if (s->should_advertise_sdes == TRUE) { session->csrc_count--; } if (session->last_advertised_csrc == session->csrc_count) { session->last_advertised_csrc = 0; } /* Signal to the application that this source is dead... */ if (!filter_event(session, ssrc)) { event.ssrc = ssrc; event.type = SOURCE_DELETED; event.data = NULL; event.ts = &event_ts; session->callback(session, &event); } xfree(s); check_database(session); } static inline void init_seq(source *s, uint16_t seq) { /* Taken from draft-ietf-avt-rtp-new-01.txt */ check_source(s); s->base_seq = seq; s->max_seq = seq; s->bad_seq = RTP_SEQ_MOD + 1; s->cycles = 0; s->received = 0; s->received_prior = 0; s->expected_prior = 0; } static int update_seq(source *s, uint16_t seq) { /* Taken from draft-ietf-avt-rtp-new-01.txt */ uint16_t udelta = seq - s->max_seq; /* * Source is not valid until MIN_SEQUENTIAL packets with * sequential sequence numbers have been received. */ check_source(s); if (s->probation) { /* packet is in sequence */ if (seq == s->max_seq + 1) { s->probation--; s->max_seq = seq; if (s->probation == 0) { init_seq(s, seq); s->received++; return 1; } } else { s->probation = MIN_SEQUENTIAL - 1; s->max_seq = seq; } return 0; } else if (udelta < MAX_DROPOUT) { /* in order, with permissible gap */ if (seq < s->max_seq) { /* * Sequence number wrapped - count another 64K cycle. */ s->cycles += RTP_SEQ_MOD; } s->max_seq = seq; } else if (udelta <= RTP_SEQ_MOD - MAX_MISORDER) { /* the sequence number made a very large jump */ if (seq == s->bad_seq) { /* * Two sequential packets -- assume that the other side * restarted without telling us so just re-sync * (i.e., pretend this was the first packet). */ init_seq(s, seq); } else { s->bad_seq = (seq + 1) & (RTP_SEQ_MOD-1); return 0; } } else { /* duplicate or reordered packet */ } s->received++; return 1; } static double rtcp_interval(struct rtp *session) { /* Minimum average time between RTCP packets from this site (in */ /* seconds). This time prevents the reports from `clumping' when */ /* sessions are small and the law of large numbers isn't helping */ /* to smooth out the traffic. It also keeps the report interval */ /* from becoming ridiculously small during transient outages like */ /* a network partition. */ double const RTCP_MIN_TIME = 5.0; /* Fraction of the RTCP bandwidth to be shared among active */ /* senders. (This fraction was chosen so that in a typical */ /* session with one or two active senders, the computed report */ /* time would be roughly equal to the minimum report time so that */ /* we don't unnecessarily slow down receiver reports.) The */ /* receiver fraction must be 1 - the sender fraction. */ double const RTCP_SENDER_BW_FRACTION = 0.25; double const RTCP_RCVR_BW_FRACTION = (1-RTCP_SENDER_BW_FRACTION); /* To compensate for "unconditional reconsideration" converging */ /* to a value below the intended average. */ double const COMPENSATION = 2.71828 - 1.5; double t; /* interval */ double rtcp_min_time = RTCP_MIN_TIME; int n; /* no. of members for computation */ double rtcp_bw = session->rtcp_bw; /* Very first call at application start-up uses half the min */ /* delay for quicker notification while still allowing some time */ /* before reporting for randomization and to learn about other */ /* sources so the report interval will converge to the correct */ /* interval more quickly. */ if (session->initial_rtcp) { rtcp_min_time /= 2; } /* If there were active senders, give them at least a minimum */ /* share of the RTCP bandwidth. Otherwise all participants share */ /* the RTCP bandwidth equally. */ if (session->sending_bye) { n = session->bye_count; } else { n = session->ssrc_count; } if (session->sender_count > 0 && session->sender_count < n * RTCP_SENDER_BW_FRACTION) { if (session->we_sent) { rtcp_bw *= RTCP_SENDER_BW_FRACTION; n = session->sender_count; } else { rtcp_bw *= RTCP_RCVR_BW_FRACTION; n -= session->sender_count; } } /* The effective number of sites times the average packet size is */ /* the total number of octets sent when each site sends a report. */ /* Dividing this by the effective bandwidth gives the time */ /* interval over which those packets must be sent in order to */ /* meet the bandwidth target, with a minimum enforced. In that */ /* time interval we send one report so this time is also our */ /* average time between reports. */ t = session->avg_rtcp_size * n / rtcp_bw; if (t < rtcp_min_time) { t = rtcp_min_time; } session->rtcp_interval = t; /* To avoid traffic bursts from unintended synchronization with */ /* other sites, we then pick our actual next report interval as a */ /* random number uniformly distributed between 0.5*t and 1.5*t. */ return (t * (drand48() + 0.5)) / COMPENSATION; } #define MAXCNAMELEN 255 static char *get_cname(socket_udp *s) { /* Set the CNAME. This is "user@hostname" or just "hostname" if the username cannot be found. */ const char *hname; char *uname; char *cname; #ifndef WIN32 struct passwd *pwent; #else char *name; int namelen; #endif cname = (char *) xmalloc(MAXCNAMELEN + 1); cname[0] = '\0'; /* First, fill in the username... */ #ifdef WIN32 name = NULL; namelen = 0; GetUserName(NULL, &namelen); if (namelen > 0) { name = (char*)xmalloc(namelen+1); GetUserName(name, &namelen); } else { uname = getenv("USER"); if (uname != NULL) { name = xstrdup(uname); } } if (name != NULL) { strncpy(cname, name, MAXCNAMELEN - 1); strcat(cname, "@"); xfree(name); } #else pwent = getpwuid(getuid()); uname = pwent->pw_name; if (uname != NULL) { strncpy(cname, uname, MAXCNAMELEN - 1); strcat(cname, "@"); } #endif /* Now the hostname. Must be dotted-quad IP address. */ hname = udp_host_addr(s); if (hname == NULL) { /* If we can't get our IP address we use the loopback address... */ /* This is horrible, but it stops the code from failing. */ hname = "127.0.0.1"; } strncpy(cname + strlen(cname), hname, MAXCNAMELEN - strlen(cname)); return cname; } static void init_opt(struct rtp *session) { /* Default option settings. */ rtp_set_option(session, RTP_OPT_PROMISC, FALSE); rtp_set_option(session, RTP_OPT_WEAK_VALIDATION, FALSE); rtp_set_option(session, RTP_OPT_FILTER_MY_PACKETS, FALSE); rtp_set_option(session, RTP_OPT_REUSE_PACKET_BUFS, FALSE); } static void init_rng(const char *s) { static uint32_t seed; if (s == NULL) { /* This should never happen, but just in case */ s = "ARANDOMSTRINGSOWEDONTCOREDUMP"; } if (seed == 0) { pid_t p = getpid(); int32_t i, n; while (*s) { seed += (uint32_t)*s++; seed = seed * 31 + 1; } seed = 1 + seed * 31 + (uint32_t)p; srand48(seed); /* At time of writing we use srand48 -> srand on Win32 which is only 16 bit. lrand48 -> rand which is only 15 bits, step a long way through table seq */ #ifdef WIN32 n = (seed >> 16) & 0xffff; for(i = 0; i < n; i++) { seed = lrand48(); } #endif /* WIN32 */ UNUSED(i); UNUSED(n); } } /* See rtp_init_if(); calling rtp_init() is just like calling * rtp_init_if() with a NULL interface argument. */ /** * rtp_init: * @addr: IP destination of this session (unicast or multicast), * as an ASCII string. May be a host name, which will be looked up, * or may be an IPv4 dotted quad or IPv6 literal adddress. * @rx_port: The port to which to bind the UDP socket * @tx_port: The port to which to send UDP packets * @ttl: The TTL with which to send multicasts * @rtcp_bw: The total bandwidth (in units of bytes per second) that is * allocated to RTCP. * @callback: See section on #rtp_callback. * @userdata: Opaque data associated with the session. See * rtp_get_userdata(). * * * Returns: An opaque session identifier to be used in future calls to * the RTP library functions, or NULL on failure. */ struct rtp *rtp_init(const char *addr, uint16_t rx_port, uint16_t tx_port, int ttl, double rtcp_bw, rtp_callback callback, uint8_t *userdata) { return rtp_init_if(addr, NULL, rx_port, tx_port, ttl, rtcp_bw, callback, userdata); } /** * rtp_init_if: * @addr: IP destination of this session (unicast or multicast), * as an ASCII string. May be a host name, which will be looked up, * or may be an IPv4 dotted quad or IPv6 literal adddress. * @iface: If the destination of the session is multicast, * the optional interface to bind to. May be NULL, in which case * the default multicast interface as determined by the system * will be used. * @rx_port: The port to which to bind the UDP socket * @tx_port: The port to which to send UDP packets * @ttl: The TTL with which to send multicasts * @rtcp_bw: The total bandwidth (in units of ___) that is * allocated to RTCP. * @callback: See section on #rtp_callback. * @userdata: Opaque data associated with the session. See * rtp_get_userdata(). * * Creates and initializes an RTP session. * * Returns: An opaque session identifier to be used in future calls to * the RTP library functions, or NULL on failure. */ struct rtp *rtp_init_if(const char *addr, char *iface, uint16_t rx_port, uint16_t tx_port, int ttl, double rtcp_bw, rtp_callback callback, uint8_t *userdata) { struct rtp *session; int i, j; char *cname; if (ttl < 0) { debug_msg("ttl must be greater than zero\n"); return NULL; } if (rx_port % 2) { debug_msg("rx_port must be even\n"); return NULL; } if (tx_port % 2) { debug_msg("tx_port must be even\n"); return NULL; } session = (struct rtp *) xmalloc(sizeof(struct rtp)); memset (session, 0, sizeof(struct rtp)); session->magic = 0xfeedface; session->opt = (options *) xmalloc(sizeof(options)); session->userdata = userdata; session->addr = xstrdup(addr); session->rx_port = rx_port; session->tx_port = tx_port; session->ttl = min(ttl, 127); session->rtp_socket = udp_init_if(addr, iface, rx_port, tx_port, ttl); session->rtcp_socket = udp_init_if(addr, iface, (uint16_t) (rx_port+1), (uint16_t) (tx_port+1), ttl); init_opt(session); if (session->rtp_socket == NULL || session->rtcp_socket == NULL) { xfree(session); return NULL; } init_rng(udp_host_addr(session->rtp_socket)); session->my_ssrc = (uint32_t) lrand48(); session->callback = callback; session->invalid_rtp_count = 0; session->invalid_rtcp_count = 0; session->bye_count = 0; session->csrc_count = 0; session->ssrc_count = 0; session->ssrc_count_prev = 0; session->sender_count = 0; session->initial_rtcp = TRUE; session->sending_bye = FALSE; session->avg_rtcp_size = -1; /* Sentinal value: reception of first packet starts initial value... */ session->we_sent = FALSE; session->rtcp_bw = rtcp_bw; session->sdes_count_pri = 0; session->sdes_count_sec = 0; session->sdes_count_ter = 0; session->rtp_seq = (uint16_t) lrand48(); session->rtp_pcount = 0; session->rtp_bcount = 0; gettimeofday(&(session->last_update), NULL); gettimeofday(&(session->last_rtcp_send_time), NULL); gettimeofday(&(session->next_rtcp_send_time), NULL); session->encryption_enabled = 0; session->encryption_algorithm = NULL; /* Calculate when we're supposed to send our first RTCP packet... */ tv_add(&(session->next_rtcp_send_time), rtcp_interval(session)); /* Initialise the source database... */ for (i = 0; i < RTP_DB_SIZE; i++) { session->db[i] = NULL; } session->last_advertised_csrc = 0; /* Initialize sentinels in rr table */ for (i = 0; i < RTP_DB_SIZE; i++) { for (j = 0; j < RTP_DB_SIZE; j++) { session->rr[i][j].next = &session->rr[i][j]; session->rr[i][j].prev = &session->rr[i][j]; } } /* Create a database entry for ourselves... */ create_source(session, session->my_ssrc, FALSE); cname = get_cname(session->rtp_socket); rtp_set_sdes(session, session->my_ssrc, RTCP_SDES_CNAME, cname, strlen(cname)); xfree(cname); /* cname is copied by rtp_set_sdes()... */ return session; } /** * rtp_set_my_ssrc: * @session: the RTP session * @ssrc: the SSRC to be used by the RTP session * * This function coerces the local SSRC identifer to be ssrc. For * this function to succeed it must be called immediately after * rtp_init or rtp_init_if. The intended purpose of this * function is to co-ordinate SSRC's between layered sessions, it * should not be used otherwise. * * Returns: TRUE on success, FALSE otherwise. */ int rtp_set_my_ssrc(struct rtp *session, uint32_t ssrc) { source *s; uint32_t h; if (session->ssrc_count != 1 && session->sender_count != 0) { return FALSE; } /* Remove existing source */ h = ssrc_hash(session->my_ssrc); s = session->db[h]; session->db[h] = NULL; /* Fill in new ssrc */ session->my_ssrc = ssrc; s->ssrc = ssrc; h = ssrc_hash(ssrc); /* Put source back */ session->db[h] = s; return TRUE; } /** * rtp_set_option: * @session: The RTP session. * @optname: The option name, see #rtp_option. * @optval: The value to set. * * Sets the value of a session option. See #rtp_option for * documentation on the options and their legal values. * * Returns: TRUE on success, else FALSE. */ int rtp_set_option(struct rtp *session, rtp_option optname, int optval) { assert((optval == TRUE) || (optval == FALSE)); switch (optname) { case RTP_OPT_WEAK_VALIDATION: session->opt->wait_for_rtcp = optval; break; case RTP_OPT_PROMISC: session->opt->promiscuous_mode = optval; break; case RTP_OPT_FILTER_MY_PACKETS: session->opt->filter_my_packets = optval; break; case RTP_OPT_REUSE_PACKET_BUFS: session->opt->reuse_bufs = optval; break; default: debug_msg("Ignoring unknown option (%d) in call to rtp_set_option().\n", optname); return FALSE; } return TRUE; } /** * rtp_get_option: * @session: The RTP session. * @optname: The option name, see #rtp_option. * @optval: The return value. * * Retrieves the value of a session option. See #rtp_option for * documentation on the options and their legal values. * * Returns: TRUE and the value of the option in optval on success, else FALSE. */ int rtp_get_option(struct rtp *session, rtp_option optname, int *optval) { switch (optname) { case RTP_OPT_WEAK_VALIDATION: *optval = session->opt->wait_for_rtcp; break; case RTP_OPT_PROMISC: *optval = session->opt->promiscuous_mode; break; case RTP_OPT_FILTER_MY_PACKETS: *optval = session->opt->filter_my_packets; break; case RTP_OPT_REUSE_PACKET_BUFS: *optval = session->opt->reuse_bufs; break; default: *optval = 0; debug_msg("Ignoring unknown option (%d) in call to rtp_get_option().\n", optname); return FALSE; } return TRUE; } /** * rtp_get_userdata: * @session: The RTP session. * * This function returns the userdata pointer that was passed to the * rtp_init() or rtp_init_if() function when creating this session. * * Returns: pointer to userdata. */ uint8_t *rtp_get_userdata(struct rtp *session) { check_database(session); return session->userdata; } /** * rtp_my_ssrc: * @session: The RTP Session. * * Returns: The SSRC we are currently using in this session. Note that our * SSRC can change at any time (due to collisions) so applications must not * store the value returned, but rather should call this function each time * they need it. */ uint32_t rtp_my_ssrc(struct rtp *session) { check_database(session); return session->my_ssrc; } static void process_rtp(struct rtp *session, uint32_t curr_rtp_ts, rtp_packet *packet, source *s) { int i, d, transit; rtp_event event; struct timeval event_ts; if (packet->cc > 0) { for (i = 0; i < packet->cc; i++) { create_source(session, packet->csrc[i], FALSE); } } /* Update the source database... */ if (s->sender == FALSE) { s->sender = TRUE; session->sender_count++; } transit = curr_rtp_ts - packet->ts; d = transit - s->transit; s->transit = transit; if (d < 0) { d = -d; } s->jitter += d - ((s->jitter + 8) / 16); /* Callback to the application to process the packet... */ if (!filter_event(session, packet->ssrc)) { gettimeofday(&event_ts, NULL); event.ssrc = packet->ssrc; event.type = RX_RTP; event.data = (void *) packet; /* The callback function MUST free this! */ event.ts = &event_ts; session->callback(session, &event); } } static int validate_rtp2(rtp_packet *packet, int len) { /* Check for valid payload types..... 72-76 are RTCP payload type numbers, with */ /* the high bit missing so we report that someone is running on the wrong port. */ if (packet->pt >= 72 && packet->pt <= 76) { debug_msg("rtp_header_validation: payload-type invalid"); if (packet->m) { debug_msg(" (RTCP packet on RTP port?)"); } debug_msg("\n"); return FALSE; } /* Check that the length of the packet is sensible... */ if (len < (12 + (4 * packet->cc))) { debug_msg("rtp_header_validation: packet length is smaller than the header\n"); return FALSE; } /* Check that the amount of padding specified is sensible. */ /* Note: have to include the size of any extension header! */ if (packet->p) { int payload_len = len - 12 - (packet->cc * 4); if (packet->x) { /* extension header and data */ payload_len -= 4 * (1 + packet->extn_len); } if (packet->data[packet->data_len - 1] > payload_len) { debug_msg("rtp_header_validation: padding greater than payload length\n"); return FALSE; } if (packet->data[packet->data_len - 1] < 1) { debug_msg("rtp_header_validation: padding zero\n"); return FALSE; } } return TRUE; } static inline int validate_rtp(struct rtp *session, rtp_packet *packet, int len) { /* This function checks the header info to make sure that the packet */ /* is valid. We return TRUE if the packet is valid, FALSE otherwise. */ /* See Appendix A.1 of the RTP specification. */ /* We only accept RTPv2 packets... */ if (packet->v != 2) { debug_msg("rtp_header_validation: v != 2\n"); return FALSE; } if (!session->opt->wait_for_rtcp) { /* We prefer speed over accuracy... */ return TRUE; } return validate_rtp2(packet, len); } static void rtp_recv_data(struct rtp *session, uint32_t curr_rtp_ts) { /* This routine preprocesses an incoming RTP packet, deciding whether to process it. */ static rtp_packet *packet = NULL; static uint8_t *buffer = NULL; static uint8_t *buffer12 = NULL; int buflen; source *s; if (!session->opt->reuse_bufs || (packet == NULL)) { packet = (rtp_packet *) xmalloc(RTP_MAX_PACKET_LEN); buffer = ((uint8_t *) packet) + RTP_PACKET_HEADER_SIZE; buffer12 = buffer + 12; } buflen = udp_recv(session->rtp_socket, buffer, RTP_MAX_PACKET_LEN - RTP_PACKET_HEADER_SIZE); if (buflen > 0) { if (session->encryption_enabled) { uint8_t initVec[8] = {0,0,0,0,0,0,0,0}; (session->decrypt_func)(session, buffer, buflen, initVec); } /* Convert header fields to host byte order... */ packet->seq = ntohs(packet->seq); packet->ts = ntohl(packet->ts); packet->ssrc = ntohl(packet->ssrc); /* Setup internal pointers, etc... */ if (packet->cc) { int i; packet->csrc = (uint32_t *)(buffer12); for (i = 0; i < packet->cc; i++) { packet->csrc[i] = ntohl(packet->csrc[i]); } } else { packet->csrc = NULL; } if (packet->x) { packet->extn = buffer12 + (packet->cc * 4); packet->extn_len = (packet->extn[2] << 8) | packet->extn[3]; packet->extn_type = (packet->extn[0] << 8) | packet->extn[1]; } else { packet->extn = NULL; packet->extn_len = 0; packet->extn_type = 0; } packet->data = buffer12 + (packet->cc * 4); packet->data_len = buflen - (packet->cc * 4) - 12; if (packet->extn != NULL) { packet->data += ((packet->extn_len + 1) * 4); packet->data_len -= ((packet->extn_len + 1) * 4); } if (validate_rtp(session, packet, buflen)) { if (session->opt->wait_for_rtcp) { s = create_source(session, packet->ssrc, TRUE); } else { s = get_source(session, packet->ssrc); } if (session->opt->promiscuous_mode) { if (s == NULL) { create_source(session, packet->ssrc, FALSE); s = get_source(session, packet->ssrc); } process_rtp(session, curr_rtp_ts, packet, s); return; /* We don't free "packet", that's done by the callback function... */ } if (s != NULL) { if (s->probation == -1) { s->probation = MIN_SEQUENTIAL; s->max_seq = packet->seq - 1; } if (update_seq(s, packet->seq)) { process_rtp(session, curr_rtp_ts, packet, s); return; /* we don't free "packet", that's done by the callback function... */ } else { /* This source is still on probation... */ debug_msg("RTP packet from probationary source ignored...\n"); } } else { debug_msg("RTP packet from unknown source ignored\n"); } } else { session->invalid_rtp_count++; debug_msg("Invalid RTP packet discarded\n"); } } if (!session->opt->reuse_bufs) { xfree(packet); } } static int validate_rtcp(uint8_t *packet, int len) { /* Validity check for a compound RTCP packet. This function returns */ /* TRUE if the packet is okay, FALSE if the validity check fails. */ /* */ /* The following checks can be applied to RTCP packets [RFC1889]: */ /* o RTP version field must equal 2. */ /* o The payload type field of the first RTCP packet in a compound */ /* packet must be equal to SR or RR. */ /* o The padding bit (P) should be zero for the first packet of a */ /* compound RTCP packet because only the last should possibly */ /* need padding. */ /* o The length fields of the individual RTCP packets must total to */ /* the overall length of the compound RTCP packet as received. */ rtcp_t *pkt = (rtcp_t *) packet; rtcp_t *end = (rtcp_t *) (((char *) pkt) + len); rtcp_t *r = pkt; int l = 0; int pc = 1; int p = 0; /* All RTCP packets must be compound packets (RFC1889, section 6.1) */ if (((ntohs(pkt->common.length) + 1) * 4) == len) { debug_msg("Bogus RTCP packet: not a compound packet\n"); return FALSE; } /* Check the RTCP version, payload type and padding of the first in */ /* the compund RTCP packet... */ if (pkt->common.version != 2) { debug_msg("Bogus RTCP packet: version number != 2 in the first sub-packet\n"); return FALSE; } if (pkt->common.p != 0) { debug_msg("Bogus RTCP packet: padding bit is set on first packet in compound\n"); return FALSE; } if ((pkt->common.pt != RTCP_SR) && (pkt->common.pt != RTCP_RR)) { debug_msg("Bogus RTCP packet: compund packet does not start with SR or RR\n"); return FALSE; } /* Check all following parts of the compund RTCP packet. The RTP version */ /* number must be 2, and the padding bit must be zero on all apart from */ /* the last packet. */ do { if (p == 1) { debug_msg("Bogus RTCP packet: padding bit set before last in compound (sub-packet %d)\n", pc); return FALSE; } if (r->common.p) { p = 1; } if (r->common.version != 2) { debug_msg("Bogus RTCP packet: version number != 2 in sub-packet %d\n", pc); return FALSE; } l += (ntohs(r->common.length) + 1) * 4; r = (rtcp_t *) (((uint32_t *) r) + ntohs(r->common.length) + 1); pc++; /* count of sub-packets, for debugging... */ } while (r < end); /* Check that the length of the packets matches the length of the UDP */ /* packet in which they were received... */ if (l != len) { debug_msg("Bogus RTCP packet: RTCP packet length does not match UDP packet length (%d != %d)\n", l, len); return FALSE; } if (r != end) { debug_msg("Bogus RTCP packet: RTCP packet length does not match UDP packet length (%p != %p)\n", r, end); return FALSE; } return TRUE; } static void process_report_blocks(struct rtp *session, rtcp_t *packet, uint32_t ssrc, rtcp_rr *rrp, struct timeval *event_ts) { int i; rtp_event event; rtcp_rr *rr; /* ...process RRs... */ if (packet->common.count == 0) { if (!filter_event(session, ssrc)) { event.ssrc = ssrc; event.type = RX_RR_EMPTY; event.data = NULL; event.ts = event_ts; session->callback(session, &event); } } else { for (i = 0; i < packet->common.count; i++, rrp++) { rr = (rtcp_rr *) xmalloc(sizeof(rtcp_rr)); rr->ssrc = ntohl(rrp->ssrc); rr->fract_lost = rrp->fract_lost; /* Endian conversion handled in the */ rr->total_lost = rrp->total_lost; /* definition of the rtcp_rr type. */ rr->last_seq = ntohl(rrp->last_seq); rr->jitter = ntohl(rrp->jitter); rr->lsr = ntohl(rrp->lsr); rr->dlsr = ntohl(rrp->dlsr); /* Create a database entry for this SSRC, if one doesn't already exist... */ create_source(session, rr->ssrc, FALSE); /* Store the RR for later use... */ insert_rr(session, ssrc, rr, event_ts); /* Call the event handler... */ if (!filter_event(session, ssrc)) { event.ssrc = ssrc; event.type = RX_RR; event.data = (void *) rr; event.ts = event_ts; session->callback(session, &event); } } } } static void process_rtcp_sr(struct rtp *session, rtcp_t *packet, struct timeval *event_ts) { uint32_t ssrc; rtp_event event; rtcp_sr *sr; source *s; ssrc = ntohl(packet->r.sr.sr.ssrc); s = create_source(session, ssrc, FALSE); if (s == NULL) { debug_msg("Source 0x%08x invalid, skipping...\n", ssrc); return; } /* Mark as an active sender, if we get a sender report... */ if (s->sender == FALSE) { s->sender = TRUE; session->sender_count++; } /* Process the SR... */ sr = (rtcp_sr *) xmalloc(sizeof(rtcp_sr)); sr->ssrc = ssrc; sr->ntp_sec = ntohl(packet->r.sr.sr.ntp_sec); sr->ntp_frac = ntohl(packet->r.sr.sr.ntp_frac); sr->rtp_ts = ntohl(packet->r.sr.sr.rtp_ts); sr->sender_pcount = ntohl(packet->r.sr.sr.sender_pcount); sr->sender_bcount = ntohl(packet->r.sr.sr.sender_bcount); /* Store the SR for later retrieval... */ if (s->sr != NULL) { xfree(s->sr); } s->sr = sr; s->last_sr = *event_ts; /* Call the event handler... */ if (!filter_event(session, ssrc)) { event.ssrc = ssrc; event.type = RX_SR; event.data = (void *) sr; event.ts = event_ts; session->callback(session, &event); } process_report_blocks(session, packet, ssrc, packet->r.sr.rr, event_ts); if (((packet->common.count * 6) + 1) < (ntohs(packet->common.length) - 5)) { debug_msg("Profile specific SR extension ignored\n"); } } static void process_rtcp_rr(struct rtp *session, rtcp_t *packet, struct timeval *event_ts) { uint32_t ssrc; source *s; ssrc = ntohl(packet->r.rr.ssrc); s = create_source(session, ssrc, FALSE); if (s == NULL) { debug_msg("Source 0x%08x invalid, skipping...\n", ssrc); return; } process_report_blocks(session, packet, ssrc, packet->r.rr.rr, event_ts); if (((packet->common.count * 6) + 1) < ntohs(packet->common.length)) { debug_msg("Profile specific RR extension ignored\n"); } } static void process_rtcp_sdes(struct rtp *session, rtcp_t *packet, struct timeval *event_ts) { int count = packet->common.count; struct rtcp_sdes_t *sd = &packet->r.sdes; rtcp_sdes_item *rsp; rtcp_sdes_item *rspn; rtcp_sdes_item *end = (rtcp_sdes_item *) ((uint32_t *)packet + packet->common.length + 1); source *s; rtp_event event; while (--count >= 0) { rsp = &sd->item[0]; if (rsp >= end) { break; } sd->ssrc = ntohl(sd->ssrc); s = create_source(session, sd->ssrc, FALSE); if (s == NULL) { debug_msg("Can't get valid source entry for 0x%08x, skipping...\n", sd->ssrc); } else { for (; rsp->type; rsp = rspn ) { rspn = (rtcp_sdes_item *)((char*)rsp+rsp->length+2); if (rspn >= end) { rsp = rspn; break; } if (rtp_set_sdes(session, sd->ssrc, rsp->type, rsp->data, rsp->length)) { if (!filter_event(session, sd->ssrc)) { event.ssrc = sd->ssrc; event.type = RX_SDES; event.data = (void *) rsp; event.ts = event_ts; session->callback(session, &event); } } else { debug_msg("Invalid sdes item for source 0x%08x, skipping...\n", sd->ssrc); } } } sd = (struct rtcp_sdes_t *) ((uint32_t *)sd + (((char *)rsp - (char *)sd) >> 2)+1); } if (count >= 0) { debug_msg("Invalid RTCP SDES packet, some items ignored.\n"); } } static void process_rtcp_bye(struct rtp *session, rtcp_t *packet, struct timeval *event_ts) { int i; uint32_t ssrc; rtp_event event; source *s; for (i = 0; i < packet->common.count; i++) { ssrc = ntohl(packet->r.bye.ssrc[i]); /* This is kind-of strange, since we create a source we are about to delete. */ /* This is done to ensure that the source mentioned in the event which is */ /* passed to the user of the RTP library is valid, and simplify client code. */ create_source(session, ssrc, FALSE); /* Call the event handler... */ if (!filter_event(session, ssrc)) { event.ssrc = ssrc; event.type = RX_BYE; event.data = NULL; event.ts = event_ts; session->callback(session, &event); } /* Mark the source as ready for deletion. Sources are not deleted immediately */ /* since some packets may be delayed and arrive after the BYE... */ s = get_source(session, ssrc); s->got_bye = TRUE; check_source(s); session->bye_count++; } } static void process_rtcp_app(struct rtp *session, rtcp_t *packet, struct timeval *event_ts) { uint32_t ssrc; rtp_event event; rtcp_app *app; source *s; int data_len; /* Update the database for this source. */ ssrc = ntohl(packet->r.app.ssrc); create_source(session, ssrc, FALSE); s = get_source(session, ssrc); if (s == NULL) { /* This should only occur in the event of database malfunction. */ debug_msg("Source 0x%08x invalid, skipping...\n", ssrc); return; } check_source(s); /* Copy the entire packet, converting the header (only) into host byte order. */ app = (rtcp_app *) xmalloc(RTP_MAX_PACKET_LEN); app->version = packet->common.version; app->p = packet->common.p; app->subtype = packet->common.count; app->pt = packet->common.pt; app->length = ntohs(packet->common.length); app->ssrc = ssrc; app->name[0] = packet->r.app.name[0]; app->name[1] = packet->r.app.name[1]; app->name[2] = packet->r.app.name[2]; app->name[3] = packet->r.app.name[3]; data_len = (app->length - 2) * 4; memcpy(app->data, packet->r.app.data, data_len); /* Callback to the application to process the app packet... */ if (!filter_event(session, ssrc)) { event.ssrc = ssrc; event.type = RX_APP; event.data = (void *) app; /* The callback function MUST free this! */ event.ts = event_ts; session->callback(session, &event); } } static void rtp_process_ctrl(struct rtp *session, uint8_t *buffer, int buflen) { /* This routine processes incoming RTCP packets */ rtp_event event; struct timeval event_ts; rtcp_t *packet; uint8_t initVec[8] = {0,0,0,0,0,0,0,0}; int first; uint32_t packet_ssrc = rtp_my_ssrc(session); gettimeofday(&event_ts, NULL); if (buflen > 0) { if (session->encryption_enabled) { /* Decrypt the packet... */ (session->decrypt_func)(session, buffer, buflen, initVec); buffer += 4; /* Skip the random prefix... */ buflen -= 4; } if (validate_rtcp(buffer, buflen)) { first = TRUE; packet = (rtcp_t *) buffer; while (packet < (rtcp_t *) (buffer + buflen)) { switch (packet->common.pt) { case RTCP_SR: if (first && !filter_event(session, ntohl(packet->r.sr.sr.ssrc))) { event.ssrc = ntohl(packet->r.sr.sr.ssrc); event.type = RX_RTCP_START; event.data = &buflen; event.ts = &event_ts; packet_ssrc = event.ssrc; session->callback(session, &event); } process_rtcp_sr(session, packet, &event_ts); break; case RTCP_RR: if (first && !filter_event(session, ntohl(packet->r.rr.ssrc))) { event.ssrc = ntohl(packet->r.rr.ssrc); event.type = RX_RTCP_START; event.data = &buflen; event.ts = &event_ts; packet_ssrc = event.ssrc; session->callback(session, &event); } process_rtcp_rr(session, packet, &event_ts); break; case RTCP_SDES: if (first && !filter_event(session, ntohl(packet->r.sdes.ssrc))) { event.ssrc = ntohl(packet->r.sdes.ssrc); event.type = RX_RTCP_START; event.data = &buflen; event.ts = &event_ts; packet_ssrc = event.ssrc; session->callback(session, &event); } process_rtcp_sdes(session, packet, &event_ts); break; case RTCP_BYE: if (first && !filter_event(session, ntohl(packet->r.bye.ssrc[0]))) { event.ssrc = ntohl(packet->r.bye.ssrc[0]); event.type = RX_RTCP_START; event.data = &buflen; event.ts = &event_ts; packet_ssrc = event.ssrc; session->callback(session, &event); } process_rtcp_bye(session, packet, &event_ts); break; case RTCP_APP: if (first && !filter_event(session, ntohl(packet->r.app.ssrc))) { event.ssrc = ntohl(packet->r.app.ssrc); event.type = RX_RTCP_START; event.data = &buflen; event.ts = &event_ts; packet_ssrc = event.ssrc; session->callback(session, &event); } process_rtcp_app(session, packet, &event_ts); break; default: debug_msg("RTCP packet with unknown type (%d) ignored.\n", packet->common.pt); break; } packet = (rtcp_t *) ((char *) packet + (4 * (ntohs(packet->common.length) + 1))); first = FALSE; } if (session->avg_rtcp_size < 0) { /* This is the first RTCP packet we've received, set our initial estimate */ /* of the average packet size to be the size of this packet. */ session->avg_rtcp_size = buflen + RTP_LOWER_LAYER_OVERHEAD; } else { /* Update our estimate of the average RTCP packet size. The constants are */ /* 1/16 and 15/16 (section 6.3.3 of draft-ietf-avt-rtp-new-02.txt). */ session->avg_rtcp_size = (0.0625 * (buflen + RTP_LOWER_LAYER_OVERHEAD)) + (0.9375 * session->avg_rtcp_size); } /* Signal that we've finished processing this packet */ if (!filter_event(session, packet_ssrc)) { event.ssrc = packet_ssrc; event.type = RX_RTCP_FINISH; event.data = NULL; event.ts = &event_ts; session->callback(session, &event); } } else { debug_msg("Invalid RTCP packet discarded\n"); session->invalid_rtcp_count++; } } } /** * rtp_recv: * @session: the session pointer (returned by rtp_init()) * @timeout: the amount of time that rtcp_recv() is allowed to block * @curr_rtp_ts: the current time expressed in units of the media * timestamp. * * Receive RTP packets and dispatch them. * * Returns: TRUE if data received, FALSE if the timeout occurred. */ int rtp_recv(struct rtp *session, struct timeval *timeout, uint32_t curr_rtp_ts) { check_database(session); udp_fd_zero(); udp_fd_set(session->rtp_socket); udp_fd_set(session->rtcp_socket); if (udp_select(timeout) > 0) { if (udp_fd_isset(session->rtp_socket)) { rtp_recv_data(session, curr_rtp_ts); } if (udp_fd_isset(session->rtcp_socket)) { uint8_t buffer[RTP_MAX_PACKET_LEN]; int buflen; buflen = udp_recv(session->rtcp_socket, buffer, RTP_MAX_PACKET_LEN); rtp_process_ctrl(session, buffer, buflen); } check_database(session); return TRUE; } check_database(session); return FALSE; } /** * rtp_add_csrc: * @session: the session pointer (returned by rtp_init()) * @csrc: Constributing SSRC identifier * * Adds @csrc to list of contributing sources used in SDES items. * Used by mixers and transcoders. * * Return value: TRUE. **/ int rtp_add_csrc(struct rtp *session, uint32_t csrc) { /* Mark csrc as something for which we should advertise RTCP SDES items, */ /* in addition to our own SDES. */ source *s; check_database(session); s = get_source(session, csrc); if (s == NULL) { s = create_source(session, csrc, FALSE); debug_msg("Created source 0x%08x as CSRC\n", csrc); } check_source(s); if (!s->should_advertise_sdes) { s->should_advertise_sdes = TRUE; session->csrc_count++; debug_msg("Added CSRC 0x%08lx as CSRC %d\n", csrc, session->csrc_count); } return TRUE; } /** * rtp_del_csrc: * @session: the session pointer (returned by rtp_init()) * @csrc: Constributing SSRC identifier * * Removes @csrc from list of contributing sources used in SDES items. * Used by mixers and transcoders. * * Return value: TRUE on success, FALSE if @csrc is not a valid source. **/ int rtp_del_csrc(struct rtp *session, uint32_t csrc) { source *s; check_database(session); s = get_source(session, csrc); if (s == NULL) { debug_msg("Invalid source 0x%08x\n", csrc); return FALSE; } check_source(s); s->should_advertise_sdes = FALSE; session->csrc_count--; if (session->last_advertised_csrc >= session->csrc_count) { session->last_advertised_csrc = 0; } return TRUE; } /** * rtp_set_sdes: * @session: the session pointer (returned by rtp_init()) * @ssrc: the SSRC identifier of a participant * @type: the SDES type represented by @value * @value: the SDES description * @length: the length of the description * * Sets session description information associated with participant * @ssrc. Under normal circumstances applications always use the * @ssrc of the local participant, this SDES information is * transmitted in receiver reports. Setting SDES information for * other participants affects the local SDES entries, but are not * transmitted onto the network. * * Return value: Returns TRUE if participant exists, FALSE otherwise. **/ int rtp_set_sdes(struct rtp *session, uint32_t ssrc, rtcp_sdes_type type, const char *value, int length) { source *s; char *v; check_database(session); s = get_source(session, ssrc); if (s == NULL) { debug_msg("Invalid source 0x%08x\n", ssrc); return FALSE; } check_source(s); v = (char *) xmalloc(length + 1); memset(v, '\0', length + 1); memcpy(v, value, length); switch (type) { case RTCP_SDES_CNAME: if (s->cname) xfree(s->cname); s->cname = v; break; case RTCP_SDES_NAME: if (s->name) xfree(s->name); s->name = v; break; case RTCP_SDES_EMAIL: if (s->email) xfree(s->email); s->email = v; break; case RTCP_SDES_PHONE: if (s->phone) xfree(s->phone); s->phone = v; break; case RTCP_SDES_LOC: if (s->loc) xfree(s->loc); s->loc = v; break; case RTCP_SDES_TOOL: if (s->tool) xfree(s->tool); s->tool = v; break; case RTCP_SDES_NOTE: if (s->note) xfree(s->note); s->note = v; break; case RTCP_SDES_PRIV: if (s->priv) xfree(s->priv); s->priv = v; break; default : debug_msg("Unknown SDES item (type=%d, value=%s)\n", type, v); xfree(v); check_database(session); return FALSE; } check_database(session); return TRUE; } /** * rtp_get_sdes: * @session: the session pointer (returned by rtp_init()) * @ssrc: the SSRC identifier of a participant * @type: the SDES information to retrieve * * Recovers session description (SDES) information on participant * identified with @ssrc. The SDES information associated with a * source is updated when receiver reports are received. There are * several different types of SDES information, e.g. username, * location, phone, email. These are enumerated by #rtcp_sdes_type. * * Return value: pointer to string containing SDES description if * received, NULL otherwise. */ const char *rtp_get_sdes(struct rtp *session, uint32_t ssrc, rtcp_sdes_type type) { source *s; check_database(session); s = get_source(session, ssrc); if (s == NULL) { debug_msg("Invalid source 0x%08x\n", ssrc); return NULL; } check_source(s); switch (type) { case RTCP_SDES_CNAME: return s->cname; case RTCP_SDES_NAME: return s->name; case RTCP_SDES_EMAIL: return s->email; case RTCP_SDES_PHONE: return s->phone; case RTCP_SDES_LOC: return s->loc; case RTCP_SDES_TOOL: return s->tool; case RTCP_SDES_NOTE: return s->note; case RTCP_SDES_PRIV: return s->priv; default: /* This includes RTCP_SDES_PRIV and RTCP_SDES_END */ debug_msg("Unknown SDES item (type=%d)\n", type); } return NULL; } /** * rtp_get_sr: * @session: the session pointer (returned by rtp_init()) * @ssrc: identifier of source * * Retrieve the latest sender report made by sender with @ssrc identifier. * * Return value: A pointer to an rtcp_sr structure on success, NULL * otherwise. The pointer must not be freed. **/ const rtcp_sr *rtp_get_sr(struct rtp *session, uint32_t ssrc) { /* Return the last SR received from this ssrc. The */ /* caller MUST NOT free the memory returned to it. */ source *s; check_database(session); s = get_source(session, ssrc); if (s == NULL) { return NULL; } check_source(s); return s->sr; } /** * rtp_get_rr: * @session: the session pointer (returned by rtp_init()) * @reporter: participant originating receiver report * @reportee: participant included in receiver report * * Retrieve the latest receiver report on @reportee made by @reporter. * Provides an indication of other receivers reception service. * * Return value: A pointer to a rtcp_rr structure on success, NULL * otherwise. The pointer must not be freed. **/ const rtcp_rr *rtp_get_rr(struct rtp *session, uint32_t reporter, uint32_t reportee) { check_database(session); return get_rr(session, reporter, reportee); } /** * rtp_send_data: * @session: the session pointer (returned by rtp_init()) * @rtp_ts: The timestamp reflects the sampling instant of the first octet of the RTP data to be sent. The timestamp is expressed in media units. * @pt: The payload type identifying the format of the data. * @m: Marker bit, interpretation defined by media profile of payload. * @cc: Number of contributing sources (excluding local participant) * @csrc: Array of SSRC identifiers for contributing sources. * @data: The RTP data to be sent. * @data_len: The size @data in bytes. * @extn: Extension data (if present). * @extn_len: size of @extn in bytes. * @extn_type: extension type indicator. * * Send an RTP packet. Most media applications will only set the * @session, @rtp_ts, @pt, @m, @data, @data_len arguments. * * Mixers and translators typically set additional contributing sources * arguments (@cc, @csrc). * * Extensions fields (@extn, @extn_len, @extn_type) are for including * application specific information. When the widest amount of * inter-operability is required these fields should be avoided as * some applications discard packets with extensions they do not * recognize. * * Return value: Number of bytes transmitted. **/ int rtp_send_data(struct rtp *session, uint32_t rtp_ts, char pt, int m, int cc, uint32_t* csrc, char *data, int data_len, char *extn, uint16_t extn_len, uint16_t extn_type) { int buffer_len, i, rc, pad, pad_len; uint8_t *buffer; rtp_packet *packet; uint8_t initVec[8] = {0,0,0,0,0,0,0,0}; check_database(session); assert(data_len > 0); buffer_len = data_len + 12 + (4 * cc); if (extn != NULL) { buffer_len += (extn_len + 1) * 4; } /* Do we need to pad this packet to a multiple of 64 bits? */ /* This is only needed if encryption is enabled, since DES */ /* only works on multiples of 64 bits. We just calculate */ /* the amount of padding to add here, so we can reserve */ /* space - the actual padding is added later. */ if ((session->encryption_enabled) && ((buffer_len % session->encryption_pad_length) != 0)) { pad = TRUE; pad_len = session->encryption_pad_length - (buffer_len % session->encryption_pad_length); buffer_len += pad_len; assert((buffer_len % session->encryption_pad_length) == 0); } else { pad = FALSE; pad_len = 0; } /* Allocate memory for the packet... */ buffer = (uint8_t *) xmalloc(buffer_len + RTP_PACKET_HEADER_SIZE); packet = (rtp_packet *) buffer; /* These are internal pointers into the buffer... */ packet->csrc = (uint32_t *) (buffer + RTP_PACKET_HEADER_SIZE + 12); packet->extn = (uint8_t *) (buffer + RTP_PACKET_HEADER_SIZE + 12 + (4 * cc)); packet->data = (uint8_t *) (buffer + RTP_PACKET_HEADER_SIZE + 12 + (4 * cc)); if (extn != NULL) { packet->data += (extn_len + 1) * 4; } /* ...and the actual packet header... */ packet->v = 2; packet->p = pad; packet->x = (extn != NULL); packet->cc = cc; packet->m = m; packet->pt = pt; packet->seq = htons(session->rtp_seq++); packet->ts = htonl(rtp_ts); packet->ssrc = htonl(rtp_my_ssrc(session)); /* ...now the CSRC list... */ for (i = 0; i < cc; i++) { packet->csrc[i] = htonl(csrc[i]); } /* ...a header extension? */ if (extn != NULL) { /* We don't use the packet->extn_type field here, that's for receive only... */ uint16_t *base = (uint16_t *) packet->extn; base[0] = htons(extn_type); base[1] = htons(extn_len); memcpy(packet->extn + 4, extn, extn_len * 4); } /* ...and the media data... */ memcpy(packet->data, data, data_len); /* ...and any padding... */ if (pad) { for (i = 0; i < pad_len; i++) { buffer[buffer_len + RTP_PACKET_HEADER_SIZE - pad_len + i] = 0; } buffer[buffer_len + RTP_PACKET_HEADER_SIZE - 1] = (char) pad_len; } /* Finally, encrypt if desired... */ if (session->encryption_enabled) { assert((buffer_len % session->encryption_pad_length) == 0); (session->encrypt_func)(session, buffer + RTP_PACKET_HEADER_SIZE, buffer_len, initVec); } rc = udp_send(session->rtp_socket, buffer + RTP_PACKET_HEADER_SIZE, buffer_len); xfree(buffer); /* Update the RTCP statistics... */ session->we_sent = TRUE; session->rtp_pcount += 1; session->rtp_bcount += buffer_len; gettimeofday(&session->last_rtp_send_time, NULL); check_database(session); return rc; } #ifndef _WIN32 int rtp_send_data_iov(struct rtp *session, uint32_t rtp_ts, char pt, int m, int cc, uint32_t csrc[], struct iovec *iov, int iov_count, char *extn, uint16_t extn_len, uint16_t extn_type) { int buffer_len, i, rc; uint8_t *buffer; rtp_packet *packet; int my_iov_count = iov_count + 1; struct iovec *my_iov; /* operation not supported on encrypted sessions */ if ((session->encryption_enabled)) { return -1; } check_database(session); buffer_len = 12 + (4 * cc); if (extn != NULL) { buffer_len += (extn_len + 1) * 4; } /* Allocate memory for the packet... */ buffer = (uint8_t *) xmalloc(buffer_len + RTP_PACKET_HEADER_SIZE); packet = (rtp_packet *) buffer; /* These are internal pointers into the buffer... */ packet->csrc = (uint32_t *) (buffer + RTP_PACKET_HEADER_SIZE + 12); packet->extn = (uint8_t *) (buffer + RTP_PACKET_HEADER_SIZE + 12 + (4 * cc)); packet->data = (uint8_t *) (buffer + RTP_PACKET_HEADER_SIZE + 12 + (4 * cc)); if (extn != NULL) { packet->data += (extn_len + 1) * 4; } /* ...and the actual packet header... */ packet->v = 2; packet->p = 0; packet->x = (extn != NULL); packet->cc = cc; packet->m = m; packet->pt = pt; packet->seq = htons(session->rtp_seq++); packet->ts = htonl(rtp_ts); packet->ssrc = htonl(rtp_my_ssrc(session)); /* ...now the CSRC list... */ for (i = 0; i < cc; i++) { packet->csrc[i] = htonl(csrc[i]); } /* ...a header extension? */ if (extn != NULL) { /* We don't use the packet->extn_type field here, that's for receive only... */ uint16_t *base = (uint16_t *) packet->extn; base[0] = htons(extn_type); base[1] = htons(extn_len); memcpy(packet->extn + 4, extn, extn_len * 4); } /* Add the RTP packet header to the beginning of the iov list */ my_iov = (struct iovec*)xmalloc(my_iov_count * sizeof(struct iovec)); my_iov[0].iov_base = buffer + RTP_PACKET_HEADER_SIZE; my_iov[0].iov_len = buffer_len; for (i = 1; i < my_iov_count; i++) { my_iov[i].iov_base = iov[i-1].iov_base; my_iov[i].iov_len = iov[i-1].iov_len; buffer_len += my_iov[i].iov_len; } /* Send the data */ rc = udp_sendv(session->rtp_socket, my_iov, my_iov_count); /* Update the RTCP statistics... */ session->we_sent = TRUE; session->rtp_pcount += 1; session->rtp_bcount += buffer_len; check_database(session); return rc; } #endif static int format_report_blocks(rtcp_rr *rrp, int remaining_length, struct rtp *session) { int nblocks = 0; int h; source *s; struct timeval now; gettimeofday(&now, NULL); for (h = 0; h < RTP_DB_SIZE; h++) { for (s = session->db[h]; s != NULL; s = s->next) { check_source(s); if ((nblocks == 31) || (remaining_length < 24)) { break; /* Insufficient space for more report blocks... */ } if (s->sender) { /* Much of this is taken from A.3 of draft-ietf-avt-rtp-new-01.txt */ int extended_max = s->cycles + s->max_seq; int expected = extended_max - s->base_seq + 1; int lost = expected - s->received; int expected_interval = expected - s->expected_prior; int received_interval = s->received - s->received_prior; int lost_interval = expected_interval - received_interval; int fraction; uint32_t lsr; uint32_t dlsr; s->expected_prior = expected; s->received_prior = s->received; if (expected_interval == 0 || lost_interval <= 0) { fraction = 0; } else { fraction = (lost_interval << 8) / expected_interval; } if (s->sr == NULL) { lsr = 0; dlsr = 0; } else { lsr = ntp64_to_ntp32(s->sr->ntp_sec, s->sr->ntp_frac); dlsr = (uint32_t)(tv_diff(now, s->last_sr) * 65536); } rrp->ssrc = htonl(s->ssrc); rrp->fract_lost = fraction; rrp->total_lost = lost & 0x00ffffff; rrp->last_seq = htonl(extended_max); rrp->jitter = htonl(s->jitter / 16); rrp->lsr = htonl(lsr); rrp->dlsr = htonl(dlsr); rrp++; remaining_length -= 24; nblocks++; s->sender = FALSE; session->sender_count--; if (session->sender_count == 0) { break; /* No point continuing, since we've reported on all senders... */ } } } } return nblocks; } static uint8_t *format_rtcp_sr(uint8_t *buffer, int buflen, struct rtp *session, uint32_t rtp_ts) { /* Write an RTCP SR into buffer, returning a pointer to */ /* the next byte after the header we have just written. */ rtcp_t *packet = (rtcp_t *) buffer; int remaining_length; uint32_t ntp_sec, ntp_frac; assert(buflen >= 28); /* ...else there isn't space for the header and sender report */ packet->common.version = 2; packet->common.p = 0; packet->common.count = 0; packet->common.pt = RTCP_SR; packet->common.length = htons(1); ntp64_time(&ntp_sec, &ntp_frac); packet->r.sr.sr.ssrc = htonl(rtp_my_ssrc(session)); packet->r.sr.sr.ntp_sec = htonl(ntp_sec); packet->r.sr.sr.ntp_frac = htonl(ntp_frac); packet->r.sr.sr.rtp_ts = htonl(rtp_ts); packet->r.sr.sr.sender_pcount = htonl(session->rtp_pcount); packet->r.sr.sr.sender_bcount = htonl(session->rtp_bcount); /* Add report blocks, until we either run out of senders */ /* to report upon or we run out of space in the buffer. */ remaining_length = buflen - 28; packet->common.count = format_report_blocks(packet->r.sr.rr, remaining_length, session); packet->common.length = htons((uint16_t) (6 + (packet->common.count * 6))); return buffer + 28 + (24 * packet->common.count); } static uint8_t *format_rtcp_rr(uint8_t *buffer, int buflen, struct rtp *session) { /* Write an RTCP RR into buffer, returning a pointer to */ /* the next byte after the header we have just written. */ rtcp_t *packet = (rtcp_t *) buffer; int remaining_length; assert(buflen >= 8); /* ...else there isn't space for the header */ packet->common.version = 2; packet->common.p = 0; packet->common.count = 0; packet->common.pt = RTCP_RR; packet->common.length = htons(1); packet->r.rr.ssrc = htonl(session->my_ssrc); /* Add report blocks, until we either run out of senders */ /* to report upon or we run out of space in the buffer. */ remaining_length = buflen - 8; packet->common.count = format_report_blocks(packet->r.rr.rr, remaining_length, session); packet->common.length = htons((uint16_t) (1 + (packet->common.count * 6))); return buffer + 8 + (24 * packet->common.count); } static int add_sdes_item(uint8_t *buf, int buflen, int type, const char *val) { /* Fill out an SDES item. It is assumed that the item is a NULL */ /* terminated string. */ rtcp_sdes_item *shdr = (rtcp_sdes_item *) buf; int namelen; if (val == NULL) { debug_msg("Cannot format SDES item. type=%d val=%xp\n", type, val); return 0; } shdr->type = type; namelen = strlen(val); shdr->length = namelen; strncpy(shdr->data, val, buflen - 2); /* The "-2" accounts for the other shdr fields */ return namelen + 2; } static uint8_t *format_rtcp_sdes(uint8_t *buffer, int buflen, uint32_t ssrc, struct rtp *session) { /* From draft-ietf-avt-profile-new-00: */ /* "Applications may use any of the SDES items described in the */ /* RTP specification. While CNAME information is sent every */ /* reporting interval, other items should be sent only every third */ /* reporting interval, with NAME sent seven out of eight times */ /* within that slot and the remaining SDES items cyclically taking */ /* up the eighth slot, as defined in Section 6.2.2 of the RTP */ /* specification. In other words, NAME is sent in RTCP packets 1, */ /* 4, 7, 10, 13, 16, 19, while, say, EMAIL is used in RTCP packet */ /* 22". */ uint8_t *packet = buffer; rtcp_common *common = (rtcp_common *) buffer; const char *item; size_t remaining_len; int pad; assert(buflen > (int) sizeof(rtcp_common)); common->version = 2; common->p = 0; common->count = 1; common->pt = RTCP_SDES; common->length = 0; packet += sizeof(common); *((uint32_t *) packet) = htonl(ssrc); packet += 4; remaining_len = buflen - (packet - buffer); item = rtp_get_sdes(session, ssrc, RTCP_SDES_CNAME); if ((item != NULL) && ((strlen(item) + (size_t) 2) <= remaining_len)) { packet += add_sdes_item(packet, remaining_len, RTCP_SDES_CNAME, item); } remaining_len = buflen - (packet - buffer); item = rtp_get_sdes(session, ssrc, RTCP_SDES_NOTE); if ((item != NULL) && ((strlen(item) + (size_t) 2) <= remaining_len)) { packet += add_sdes_item(packet, remaining_len, RTCP_SDES_NOTE, item); } remaining_len = buflen - (packet - buffer); if ((session->sdes_count_pri % 3) == 0) { session->sdes_count_sec++; if ((session->sdes_count_sec % 8) == 0) { /* Note that the following is supposed to fall-through the cases */ /* until one is found to send... The lack of break statements in */ /* the switch is not a bug. */ switch (session->sdes_count_ter % 5) { case 0: item = rtp_get_sdes(session, ssrc, RTCP_SDES_TOOL); if ((item != NULL) && ((strlen(item) + (size_t) 2) <= remaining_len)) { packet += add_sdes_item(packet, remaining_len, RTCP_SDES_TOOL, item); break; } case 1: item = rtp_get_sdes(session, ssrc, RTCP_SDES_EMAIL); if ((item != NULL) && ((strlen(item) + (size_t) 2) <= remaining_len)) { packet += add_sdes_item(packet, remaining_len, RTCP_SDES_EMAIL, item); break; } case 2: item = rtp_get_sdes(session, ssrc, RTCP_SDES_PHONE); if ((item != NULL) && ((strlen(item) + (size_t) 2) <= remaining_len)) { packet += add_sdes_item(packet, remaining_len, RTCP_SDES_PHONE, item); break; } case 3: item = rtp_get_sdes(session, ssrc, RTCP_SDES_LOC); if ((item != NULL) && ((strlen(item) + (size_t) 2) <= remaining_len)) { packet += add_sdes_item(packet, remaining_len, RTCP_SDES_LOC, item); break; } case 4: item = rtp_get_sdes(session, ssrc, RTCP_SDES_PRIV); if ((item != NULL) && ((strlen(item) + (size_t) 2) <= remaining_len)) { packet += add_sdes_item(packet, remaining_len, RTCP_SDES_PRIV, item); break; } } session->sdes_count_ter++; } else { item = rtp_get_sdes(session, ssrc, RTCP_SDES_NAME); if (item != NULL) { packet += add_sdes_item(packet, remaining_len, RTCP_SDES_NAME, item); } } } session->sdes_count_pri++; /* Pad to a multiple of 4 bytes... */ pad = 4 - ((packet - buffer) & 0x3); while (pad--) { *packet++ = RTCP_SDES_END; } common->length = htons((uint16_t) (((int) (packet - buffer) / 4) - 1)); return packet; } static uint8_t *format_rtcp_app(uint8_t *buffer, int buflen, uint32_t ssrc, rtcp_app *app) { /* Write an RTCP APP into the outgoing packet buffer. */ rtcp_app *packet = (rtcp_app *) buffer; int pkt_octets = (app->length + 1) * 4; int data_octets = pkt_octets - 12; assert(data_octets >= 0); /* ...else not a legal APP packet. */ assert(buflen >= pkt_octets); /* ...else there isn't space for the APP packet. */ /* Copy one APP packet from "app" to "packet". */ packet->version = RTP_VERSION; packet->p = app->p; packet->subtype = app->subtype; packet->pt = RTCP_APP; packet->length = htons(app->length); packet->ssrc = htonl(ssrc); memcpy(packet->name, app->name, 4); memcpy(packet->data, app->data, data_octets); /* Return a pointer to the byte that immediately follows the last byte written. */ return buffer + pkt_octets; } static void send_rtcp(struct rtp *session, uint32_t rtp_ts, rtcp_app_callback appcallback) { /* Construct and send an RTCP packet. The order in which packets are packed into a */ /* compound packet is defined by section 6.1 of draft-ietf-avt-rtp-new-03.txt and */ /* we follow the recommended order. */ uint8_t buffer[RTP_MAX_PACKET_LEN + MAX_ENCRYPTION_PAD]; /* The +8 is to allow for padding when encrypting */ uint8_t *ptr = buffer; uint8_t *old_ptr; uint8_t *lpt; /* the last packet in the compound */ rtcp_app *app; uint8_t initVec[8] = {0,0,0,0,0,0,0,0}; check_database(session); /* If encryption is enabled, add a 32 bit random prefix to the packet */ if (session->encryption_enabled) { *((uint32_t *) ptr) = lbl_random(); ptr += 4; } /* The first RTCP packet in the compound packet MUST always be a report packet... */ if (session->we_sent) { ptr = format_rtcp_sr(ptr, RTP_MAX_PACKET_LEN - (ptr - buffer), session, rtp_ts); } else { ptr = format_rtcp_rr(ptr, RTP_MAX_PACKET_LEN - (ptr - buffer), session); } /* Add the appropriate SDES items to the packet... This should really be after the */ /* insertion of the additional report blocks, but if we do that there are problems */ /* with us being unable to fit the SDES packet in when we run out of buffer space */ /* adding RRs. The correct fix would be to calculate the length of the SDES items */ /* in advance and subtract this from the buffer length but this is non-trivial and */ /* probably not worth it. */ lpt = ptr; ptr = format_rtcp_sdes(ptr, RTP_MAX_PACKET_LEN - (ptr - buffer), rtp_my_ssrc(session), session); /* If we have any CSRCs, we include SDES items for each of them in turn... */ if (session->csrc_count > 0) { ptr = format_rtcp_sdes(ptr, RTP_MAX_PACKET_LEN - (ptr - buffer), next_csrc(session), session); } /* Following that, additional RR packets SHOULD follow if there are more than 31 */ /* senders, such that the reports do not fit into the initial packet. We give up */ /* if there is insufficient space in the buffer: this is bad, since we always drop */ /* the reports from the same sources (those at the end of the hash table). */ while ((session->sender_count > 0) && ((RTP_MAX_PACKET_LEN - (ptr - buffer)) >= 8)) { lpt = ptr; ptr = format_rtcp_rr(ptr, RTP_MAX_PACKET_LEN - (ptr - buffer), session); } /* Finish with as many APP packets as the application will provide. */ old_ptr = ptr; if (appcallback) { while ((app = (*appcallback)(session, rtp_ts, RTP_MAX_PACKET_LEN - (ptr - buffer)))) { lpt = ptr; ptr = format_rtcp_app(ptr, RTP_MAX_PACKET_LEN - (ptr - buffer), rtp_my_ssrc(session), app); assert(ptr > old_ptr); old_ptr = ptr; assert(RTP_MAX_PACKET_LEN - (ptr - buffer) >= 0); } } /* And encrypt if desired... */ if (session->encryption_enabled) { if (((ptr - buffer) % session->encryption_pad_length) != 0) { /* Add padding to the last packet in the compound, if necessary. */ /* We don't have to worry about overflowing the buffer, since we */ /* intentionally allocated it 8 bytes longer to allow for this. */ int padlen = session->encryption_pad_length - ((ptr - buffer) % session->encryption_pad_length); int i; for (i = 0; i < padlen-1; i++) { *(ptr++) = '\0'; } *(ptr++) = (uint8_t) padlen; assert(((ptr - buffer) % session->encryption_pad_length) == 0); ((rtcp_t *) lpt)->common.p = TRUE; ((rtcp_t *) lpt)->common.length = htons((int16_t)(((ptr - lpt) / 4) - 1)); } (session->encrypt_func)(session, buffer, ptr - buffer, initVec); } udp_send(session->rtcp_socket, buffer, ptr - buffer); /* Loop the data back to ourselves so local participant can */ /* query own stats when using unicast or multicast with no */ /* loopback. */ rtp_process_ctrl(session, buffer, ptr - buffer); check_database(session); } /** * rtp_send_ctrl: * @session: the session pointer (returned by rtp_init()) * @rtp_ts: the current time expressed in units of the media timestamp. * @appcallback: a callback to create an APP RTCP packet, if needed. * * Checks RTCP timer and sends RTCP data when nececessary. The * interval between RTCP packets is randomized over an interval that * depends on the session bandwidth, the number of participants, and * whether the local participant is a sender. This function should be * called at least once per second, and can be safely called more * frequently. */ void rtp_send_ctrl(struct rtp *session, uint32_t rtp_ts, rtcp_app_callback appcallback) { /* Send an RTCP packet, if one is due... */ struct timeval curr_time; check_database(session); gettimeofday(&curr_time, NULL); if (tv_gt(curr_time, session->next_rtcp_send_time)) { /* The RTCP transmission timer has expired. The following */ /* implements draft-ietf-avt-rtp-new-02.txt section 6.3.6 */ int h; source *s; struct timeval new_send_time; double new_interval; new_interval = rtcp_interval(session) / (session->csrc_count + 1); new_send_time = session->last_rtcp_send_time; tv_add(&new_send_time, new_interval); if (tv_gt(curr_time, new_send_time)) { send_rtcp(session, rtp_ts, appcallback); session->initial_rtcp = FALSE; session->last_rtcp_send_time = curr_time; session->next_rtcp_send_time = curr_time; tv_add(&(session->next_rtcp_send_time), rtcp_interval(session) / (session->csrc_count + 1)); /* We're starting a new RTCP reporting interval, zero out */ /* the per-interval statistics. */ session->sender_count = 0; for (h = 0; h < RTP_DB_SIZE; h++) { for (s = session->db[h]; s != NULL; s = s->next) { check_source(s); s->sender = FALSE; } } } else { session->next_rtcp_send_time = new_send_time; } session->ssrc_count_prev = session->ssrc_count; } check_database(session); } /** * rtp_update: * @session: the session pointer (returned by rtp_init()) * * Trawls through the internal data structures and performs * housekeeping. This function should be called at least once per * second. It uses an internal timer to limit the number of passes * through the data structures to once per second, it can be safely * called more frequently. */ void rtp_update(struct rtp *session) { /* Perform housekeeping on the source database... */ int h; source *s, *n; struct timeval curr_time; double delay; gettimeofday(&curr_time, NULL); if (tv_diff(curr_time, session->last_update) < 1.0) { /* We only perform housekeeping once per second... */ return; } session->last_update = curr_time; /* Update we_sent (section 6.3.8 of RTP spec) */ delay = tv_diff(curr_time, session->last_rtp_send_time); if (delay >= 2 * rtcp_interval(session)) { session->we_sent = FALSE; } check_database(session); for (h = 0; h < RTP_DB_SIZE; h++) { for (s = session->db[h]; s != NULL; s = n) { check_source(s); n = s->next; /* Expire sources which haven't been heard from for a long time. */ /* Section 6.2.1 of the RTP specification details the timers used. */ /* How long since we last heard from this source? */ delay = tv_diff(curr_time, s->last_active); /* Check if we've received a BYE packet from this source. */ /* If we have, and it was received more than 2 seconds ago */ /* then the source is deleted. The arbitrary 2 second delay */ /* is to ensure that all delayed packets are received before */ /* the source is timed out. */ if (s->got_bye && (delay > 2.0)) { debug_msg("Deleting source 0x%08lx due to reception of BYE %f seconds ago...\n", s->ssrc, delay); delete_source(session, s->ssrc); } /* Sources are marked as inactive if they haven't been heard */ /* from for more than 2 intervals (RTP section 6.3.5) */ if ((s->ssrc != rtp_my_ssrc(session)) && (delay > (session->rtcp_interval * 2))) { if (s->sender) { s->sender = FALSE; session->sender_count--; } } /* If a source hasn't been heard from for more than 5 RTCP */ /* reporting intervals, we delete it from our database... */ if ((s->ssrc != rtp_my_ssrc(session)) && (delay > (session->rtcp_interval * 5))) { debug_msg("Deleting source 0x%08lx due to timeout...\n", s->ssrc); delete_source(session, s->ssrc); } } } /* Timeout those reception reports which haven't been refreshed for a long time */ timeout_rr(session, &curr_time); check_database(session); } static void rtp_send_bye_now(struct rtp *session) { /* Send a BYE packet immediately. This is an internal function, */ /* hidden behind the rtp_send_bye() wrapper which implements BYE */ /* reconsideration for the application. */ uint8_t buffer[RTP_MAX_PACKET_LEN + MAX_ENCRYPTION_PAD]; /* + 8 to allow for padding when encrypting */ uint8_t *ptr = buffer; rtcp_common *common; uint8_t initVec[8] = {0,0,0,0,0,0,0,0}; check_database(session); /* If encryption is enabled, add a 32 bit random prefix to the packet */ if (session->encryption_enabled) { *((uint32_t *) ptr) = lbl_random(); ptr += 4; } ptr = format_rtcp_rr(ptr, RTP_MAX_PACKET_LEN - (ptr - buffer), session); common = (rtcp_common *) ptr; common->version = 2; common->p = 0; common->count = 1; common->pt = RTCP_BYE; common->length = htons(1); ptr += sizeof(common); *((uint32_t *) ptr) = htonl(session->my_ssrc); ptr += 4; if (session->encryption_enabled) { if (((ptr - buffer) % session->encryption_pad_length) != 0) { /* Add padding to the last packet in the compound, if necessary. */ /* We don't have to worry about overflowing the buffer, since we */ /* intentionally allocated it 8 bytes longer to allow for this. */ int padlen = session->encryption_pad_length - ((ptr - buffer) % session->encryption_pad_length); int i; for (i = 0; i < padlen-1; i++) { *(ptr++) = '\0'; } *(ptr++) = (uint8_t) padlen; common->p = TRUE; common->length = htons((int16_t)(((ptr - (uint8_t *) common) / 4) - 1)); } assert(((ptr - buffer) % session->encryption_pad_length) == 0); (session->encrypt_func)(session, buffer, ptr - buffer, initVec); } udp_send(session->rtcp_socket, buffer, ptr - buffer); /* Loop the data back to ourselves so local participant can */ /* query own stats when using unicast or multicast with no */ /* loopback. */ rtp_process_ctrl(session, buffer, ptr - buffer); check_database(session); } /** * rtp_send_bye: * @session: The RTP session * * Sends a BYE message on the RTP session, indicating that this * participant is leaving the session. The process of sending a * BYE may take some time, and this function will block until * it is complete. During this time, RTCP events are reported * to the application via the callback function (data packets * are silently discarded). */ void rtp_send_bye(struct rtp *session) { struct timeval curr_time, timeout, new_send_time; uint8_t buffer[RTP_MAX_PACKET_LEN]; int buflen; double new_interval; check_database(session); /* "...a participant which never sent an RTP or RTCP packet MUST NOT send */ /* a BYE packet when they leave the group." (section 6.3.7 of RTP spec) */ if ((session->we_sent == FALSE) && (session->initial_rtcp == TRUE)) { debug_msg("Silent BYE\n"); return; } /* If the session is small, send an immediate BYE. Otherwise, we delay and */ /* perform BYE reconsideration as needed. */ if (session->ssrc_count < 50) { rtp_send_bye_now(session); } else { gettimeofday(&curr_time, NULL); session->sending_bye = TRUE; session->last_rtcp_send_time = curr_time; session->next_rtcp_send_time = curr_time; session->bye_count = 1; session->initial_rtcp = TRUE; session->we_sent = FALSE; session->sender_count = 0; session->avg_rtcp_size = 70.0 + RTP_LOWER_LAYER_OVERHEAD; /* FIXME */ tv_add(&session->next_rtcp_send_time, rtcp_interval(session) / (session->csrc_count + 1)); debug_msg("Preparing to send BYE...\n"); while (1) { /* Schedule us to block in udp_select() until the time we are due to send our */ /* BYE packet. If we receive an RTCP packet from another participant before */ /* then, we are woken up to handle it... */ timeout.tv_sec = 0; timeout.tv_usec = 0; tv_add(&timeout, tv_diff(session->next_rtcp_send_time, curr_time)); udp_fd_zero(); udp_fd_set(session->rtcp_socket); if ((udp_select(&timeout) > 0) && udp_fd_isset(session->rtcp_socket)) { /* We woke up because an RTCP packet was received; process it... */ buflen = udp_recv(session->rtcp_socket, buffer, RTP_MAX_PACKET_LEN); rtp_process_ctrl(session, buffer, buflen); } /* Is it time to send our BYE? */ gettimeofday(&curr_time, NULL); new_interval = rtcp_interval(session) / (session->csrc_count + 1); new_send_time = session->last_rtcp_send_time; tv_add(&new_send_time, new_interval); if (tv_gt(curr_time, new_send_time)) { debug_msg("Sent BYE...\n"); rtp_send_bye_now(session); break; } /* No, we reconsider... */ session->next_rtcp_send_time = new_send_time; debug_msg("Reconsidered sending BYE... delay = %f\n", tv_diff(session->next_rtcp_send_time, curr_time)); /* ...and perform housekeeping in the usual manner */ rtp_update(session); } } } /** * rtp_done: * @session: the RTP session to finish * * Free the state associated with the given RTP session. This function does * not send any packets (e.g. an RTCP BYE) - an application which wishes to * exit in a clean manner should call rtp_send_bye() first. */ void rtp_done(struct rtp *session) { int i; source *s, *n; check_database(session); /* In delete_source, check database gets called and this assumes */ /* first added and last removed is us. */ for (i = 0; i < RTP_DB_SIZE; i++) { s = session->db[i]; while (s != NULL) { n = s->next; if (s->ssrc != session->my_ssrc) { delete_source(session,session->db[i]->ssrc); } s = n; } } delete_source(session, session->my_ssrc); /* * Introduce a memory leak until we add algorithm-specific * cleanup functions. if (session->encryption_key != NULL) { xfree(session->encryption_key); } */ udp_exit(session->rtp_socket); udp_exit(session->rtcp_socket); xfree(session->addr); xfree(session->opt); xfree(session); } /** * rtp_set_encryption_key: * @session: The RTP session. * @passphrase: The user-provided "pass phrase" to map to an encryption key. * * Converts the user supplied key into a form suitable for use with RTP * and install it as the active key. Passing in NULL as the passphrase * disables encryption. The passphrase is converted into a DES key as * specified in RFC1890, that is: * * - convert to canonical form * * - derive an MD5 hash of the canonical form * * - take the first 56 bits of the MD5 hash * * - add parity bits to form a 64 bit key * * Note that versions of rat prior to 4.1.2 do not convert the passphrase * to canonical form before taking the MD5 hash, and so will * not be compatible for keys which are non-invarient under this step. * * Determine from the user's encryption key which encryption * mechanism we're using. Per the RTP RFC, if the key is of the form * * string/key * * then "string" is the name of the encryption algorithm, and * "key" is the key to be used. If no / is present, then the * algorithm is assumed to be (the appropriate variant of) DES. * * Returns: TRUE on success, FALSE on failure. */ int rtp_set_encryption_key(struct rtp* session, const char *passphrase) { char *canonical_passphrase; u_char hash[16]; MD5_CTX context; char *slash; check_database(session); if (session->encryption_algorithm != NULL) { xfree(session->encryption_algorithm); session->encryption_algorithm = NULL; } if (passphrase == NULL) { /* A NULL passphrase means disable encryption... */ session->encryption_enabled = 0; check_database(session); return TRUE; } debug_msg("Enabling RTP/RTCP encryption\n"); session->encryption_enabled = 1; /* * Determine which algorithm we're using. */ slash = strchr(passphrase, '/'); if (slash == 0) { session->encryption_algorithm = xstrdup("DES"); } else { int l = slash - passphrase; session->encryption_algorithm = xmalloc(l + 1); strncpy(session->encryption_algorithm, passphrase, l); session->encryption_algorithm[l] = '\0'; passphrase = slash + 1; } debug_msg("Initializing encryption, algorithm is '%s'\n", session->encryption_algorithm); /* Step 1: convert to canonical form, comprising the following steps: */ /* a) convert the input string to the ISO 10646 character set, using */ /* the UTF-8 encoding as specified in Annex P to ISO/IEC */ /* 10646-1:1993 (ASCII characters require no mapping, but ISO */ /* 8859-1 characters do); */ /* b) remove leading and trailing white space characters; */ /* c) replace one or more contiguous white space characters by a */ /* single space (ASCII or UTF-8 0x20); */ /* d) convert all letters to lower case and replace sequences of */ /* characters and non-spacing accents with a single character, */ /* where possible. */ canonical_passphrase = (char *) xstrdup(passphrase); /* FIXME */ /* Step 2: derive an MD5 hash */ MD5Init(&context); MD5Update(&context, (u_char *) canonical_passphrase, strlen(canonical_passphrase)); MD5Final((u_char *) hash, &context); /* Initialize the encryption algorithm we've received */ if (strcmp(session->encryption_algorithm, "DES") == 0) { return des_initialize(session, hash, sizeof(hash)); } else if (strcmp(session->encryption_algorithm, "Rijndael") == 0) { return rijndael_initialize(session, hash, sizeof(hash)); } else { debug_msg("Encryption algorithm \"%s\" not found\n", session->encryption_algorithm); return FALSE; } } static int des_initialize(struct rtp *session, u_char *hash, int hashlen) { char *key; int i, j, k; UNUSED(hashlen); session->encryption_pad_length = 8; session->encrypt_func = des_encrypt; session->decrypt_func = des_decrypt; if (session->crypto_state.des.encryption_key != NULL) { xfree(session->crypto_state.des.encryption_key); } key = session->crypto_state.des.encryption_key = (char *) xmalloc(8); /* Step 3: take first 56 bits of the MD5 hash */ key[0] = hash[0]; key[1] = hash[0] << 7 | hash[1] >> 1; key[2] = hash[1] << 6 | hash[2] >> 2; key[3] = hash[2] << 5 | hash[3] >> 3; key[4] = hash[3] << 4 | hash[4] >> 4; key[5] = hash[4] << 3 | hash[5] >> 5; key[6] = hash[5] << 2 | hash[6] >> 6; key[7] = hash[6] << 1; /* Step 4: add parity bits */ for (i = 0; i < 8; ++i) { k = key[i] & 0xfe; j = k; j ^= j >> 4; j ^= j >> 2; j ^= j >> 1; j = (j & 1) ^ 1; key[i] = k | j; } check_database(session); return TRUE; } static int des_encrypt(struct rtp *session, unsigned char *data, unsigned int size, unsigned char *initVec) { qfDES_CBC_e(session->crypto_state.des.encryption_key, data, size, initVec); return TRUE; } static int des_decrypt(struct rtp *session, unsigned char *data, unsigned int size, unsigned char *initVec) { qfDES_CBC_d(session->crypto_state.des.encryption_key, data, size, initVec); return TRUE; } static int rijndael_initialize(struct rtp *session, u_char *hash, int hash_len) { int rc; session->encryption_pad_length = 16; session->encrypt_func = rijndael_encrypt; session->decrypt_func = rijndael_decrypt; rc = makeKey(&session->crypto_state.rijndael.keyInstEncrypt, DIR_ENCRYPT, hash_len * 8, (char *) hash); if (rc < 0) { debug_msg("makeKey failed: %d\n", rc); return FALSE; } rc = makeKey(&session->crypto_state.rijndael.keyInstDecrypt, DIR_DECRYPT, hash_len * 8, (char *) hash); if (rc < 0) { debug_msg("makeKey failed: %d\n", rc); return FALSE; } rc = cipherInit(&session->crypto_state.rijndael.cipherInst, MODE_ECB, NULL); if (rc < 0) { debug_msg("cipherInst failed: %d\n", rc); return FALSE; } return TRUE; } static int rijndael_encrypt(struct rtp *session, unsigned char *data, unsigned int size, unsigned char *initVec) { int rc; UNUSED(initVec); /* * Try doing this in place. If it doesn't work that way, * we'll have to allocate a buffer and copy back. */ rc = blockEncrypt(&session->crypto_state.rijndael.cipherInst, &session->crypto_state.rijndael.keyInstEncrypt, data, size * 8, data); return rc; } static int rijndael_decrypt(struct rtp *session, unsigned char *data, unsigned int size, unsigned char *initVec) { int rc; UNUSED(initVec); /* * Try doing this in place. If it doesn't work that way, * we'll have to allocate a buffer and copy back. */ rc = blockDecrypt(&session->crypto_state.rijndael.cipherInst, &session->crypto_state.rijndael.keyInstDecrypt, data, size * 8, data); return rc; } /** * rtp_get_addr: * @session: The RTP Session. * * Returns: The session's destination address, as set when creating the * session with rtp_init() or rtp_init_if(). */ char *rtp_get_addr(struct rtp *session) { check_database(session); return session->addr; } /** * rtp_get_rx_port: * @session: The RTP Session. * * Returns: The UDP port to which this session is bound, as set when * creating the session with rtp_init() or rtp_init_if(). */ uint16_t rtp_get_rx_port(struct rtp *session) { check_database(session); return session->rx_port; } /** * rtp_get_tx_port: * @session: The RTP Session. * * Returns: The UDP port to which RTP packets are transmitted, as set * when creating the session with rtp_init() or rtp_init_if(). */ uint16_t rtp_get_tx_port(struct rtp *session) { check_database(session); return session->tx_port; } /** * rtp_get_ttl: * @session: The RTP Session. * * Returns: The session's TTL, as set when creating the session with * rtp_init() or rtp_init_if(). */ int rtp_get_ttl(struct rtp *session) { check_database(session); return session->ttl; } uclmmbase-1.2.16.0/src/rtp.h0000640000175000017500000002254207456653305014446 0ustar enderender/* * FILE: rtp.h * AUTHOR: Colin Perkins * * $Revision: 1.58 $ * $Date: 2002/04/15 22:40:05 $ * * Copyright (c) 1998-2000 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Science * Department at University College London. * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ #ifndef __RTP_H__ #define __RTP_H__ #define RTP_VERSION 2 #define RTP_PACKET_HEADER_SIZE ((sizeof(char *) * 2) + sizeof(uint32_t *) + (2 * sizeof(int))) #define RTP_MAX_PACKET_LEN 1500 #if !defined(WORDS_BIGENDIAN) && !defined(WORDS_SMALLENDIAN) #error RTP library requires WORDS_BIGENDIAN or WORDS_SMALLENDIAN to be defined. #endif struct rtp; /* XXX gtkdoc doesn't seem to be able to handle functions that return * struct *'s. */ typedef struct rtp *rtp_t; typedef struct { /* The following are pointers to the data in the packet as */ /* it came off the wire. The packet it read in such that the */ /* header maps onto the latter part of this struct, and the */ /* fields in this first part of the struct point into it. The */ /* entire packet can be freed by freeing this struct, without */ /* having to free the csrc, data and extn blocks separately. */ /* WARNING: Don't change the size of the first portion of the */ /* struct without changing RTP_PACKET_HEADER_SIZE to match. */ uint32_t *csrc; char *data; int data_len; unsigned char *extn; uint16_t extn_len; /* Size of the extension in 32 bit words minus one */ uint16_t extn_type; /* Extension type field in the RTP packet header */ /* The following map directly onto the RTP packet header... */ #ifdef WORDS_BIGENDIAN unsigned short v:2; /* packet type */ unsigned short p:1; /* padding flag */ unsigned short x:1; /* header extension flag */ unsigned short cc:4; /* CSRC count */ unsigned short m:1; /* marker bit */ unsigned short pt:7; /* payload type */ #else unsigned short cc:4; /* CSRC count */ unsigned short x:1; /* header extension flag */ unsigned short p:1; /* padding flag */ unsigned short v:2; /* packet type */ unsigned short pt:7; /* payload type */ unsigned short m:1; /* marker bit */ #endif uint16_t seq; /* sequence number */ uint32_t ts; /* timestamp */ uint32_t ssrc; /* synchronization source */ /* The csrc list, header extension and data follow, but can't */ /* be represented in the struct. */ } rtp_packet; typedef struct { uint32_t ssrc; uint32_t ntp_sec; uint32_t ntp_frac; uint32_t rtp_ts; uint32_t sender_pcount; uint32_t sender_bcount; } rtcp_sr; typedef struct { uint32_t ssrc; /* The ssrc to which this RR pertains */ #ifdef WORDS_BIGENDIAN uint32_t fract_lost:8; uint32_t total_lost:24; #else uint32_t total_lost:24; uint32_t fract_lost:8; #endif uint32_t last_seq; uint32_t jitter; uint32_t lsr; uint32_t dlsr; } rtcp_rr; typedef struct { #ifdef WORDS_BIGENDIAN unsigned short version:2; /* RTP version */ unsigned short p:1; /* padding flag */ unsigned short subtype:5; /* application dependent */ #else unsigned short subtype:5; /* application dependent */ unsigned short p:1; /* padding flag */ unsigned short version:2; /* RTP version */ #endif unsigned short pt:8; /* packet type */ uint16_t length; /* packet length */ uint32_t ssrc; char name[4]; /* four ASCII characters */ char data[1]; /* variable length field */ } rtcp_app; /* rtp_event type values. */ typedef enum { RX_RTP, RX_SR, RX_RR, RX_SDES, RX_BYE, /* Source is leaving the session, database entry is still valid */ SOURCE_CREATED, SOURCE_DELETED, /* Source has been removed from the database */ RX_RR_EMPTY, /* We've received an empty reception report block */ RX_RTCP_START, /* Processing a compound RTCP packet about to start. The SSRC is not valid in this event. */ RX_RTCP_FINISH, /* Processing a compound RTCP packet finished. The SSRC is not valid in this event. */ RR_TIMEOUT, RX_APP } rtp_event_type; typedef struct { uint32_t ssrc; rtp_event_type type; void *data; struct timeval *ts; } rtp_event; /* Callback types */ typedef void (*rtp_callback)(struct rtp *session, rtp_event *e); typedef rtcp_app* (*rtcp_app_callback)(struct rtp *session, uint32_t rtp_ts, int max_size); /* SDES packet types... */ typedef enum { RTCP_SDES_END = 0, RTCP_SDES_CNAME = 1, RTCP_SDES_NAME = 2, RTCP_SDES_EMAIL = 3, RTCP_SDES_PHONE = 4, RTCP_SDES_LOC = 5, RTCP_SDES_TOOL = 6, RTCP_SDES_NOTE = 7, RTCP_SDES_PRIV = 8 } rtcp_sdes_type; typedef struct { uint8_t type; /* type of SDES item */ uint8_t length; /* length of SDES item (in bytes) */ char data[1]; /* text, not zero-terminated */ } rtcp_sdes_item; /* RTP options */ typedef enum { RTP_OPT_PROMISC = 1, RTP_OPT_WEAK_VALIDATION = 2, RTP_OPT_FILTER_MY_PACKETS = 3, RTP_OPT_REUSE_PACKET_BUFS = 4 /* Each data packet is written into the same buffer, */ /* rather than malloc()ing a new buffer each time. */ } rtp_option; /* API */ rtp_t rtp_init(const char *addr, uint16_t rx_port, uint16_t tx_port, int ttl, double rtcp_bw, rtp_callback callback, uint8_t *userdata); rtp_t rtp_init_if(const char *addr, char *iface, uint16_t rx_port, uint16_t tx_port, int ttl, double rtcp_bw, rtp_callback callback, uint8_t *userdata); void rtp_send_bye(struct rtp *session); void rtp_done(struct rtp *session); int rtp_set_option(struct rtp *session, rtp_option optname, int optval); int rtp_get_option(struct rtp *session, rtp_option optname, int *optval); int rtp_recv(struct rtp *session, struct timeval *timeout, uint32_t curr_rtp_ts); int rtp_send_data(struct rtp *session, uint32_t rtp_ts, char pt, int m, int cc, uint32_t csrc[], char *data, int data_len, char *extn, uint16_t extn_len, uint16_t extn_type); #ifndef WIN32 int rtp_send_data_iov(struct rtp *session, uint32_t rtp_ts, char pt, int m, int cc, uint32_t csrc[], struct iovec *iov, int iov_count, char *extn, uint16_t extn_len, uint16_t extn_type); #endif void rtp_send_ctrl(struct rtp *session, uint32_t rtp_ts, rtcp_app_callback appcallback); void rtp_update(struct rtp *session); uint32_t rtp_my_ssrc(struct rtp *session); int rtp_add_csrc(struct rtp *session, uint32_t csrc); int rtp_del_csrc(struct rtp *session, uint32_t csrc); int rtp_set_sdes(struct rtp *session, uint32_t ssrc, rtcp_sdes_type type, const char *value, int length); const char *rtp_get_sdes(struct rtp *session, uint32_t ssrc, rtcp_sdes_type type); const rtcp_sr *rtp_get_sr(struct rtp *session, uint32_t ssrc); const rtcp_rr *rtp_get_rr(struct rtp *session, uint32_t reporter, uint32_t reportee); int rtp_set_encryption_key(struct rtp *session, const char *passphrase); int rtp_set_my_ssrc(struct rtp *session, uint32_t ssrc); char *rtp_get_addr(struct rtp *session); uint16_t rtp_get_rx_port(struct rtp *session); uint16_t rtp_get_tx_port(struct rtp *session); int rtp_get_ttl(struct rtp *session); uint8_t *rtp_get_userdata(struct rtp *session); #endif /* __RTP_H__ */ uclmmbase-1.2.16.0/src/sap.c0000644000175000017500000001327407665113607014423 0ustar enderender/* * FILE: sap.c * AUTHOR: Ivan R. Judson * * The routines in this file implement parsing and construction of data * that's compliant with the Session Announcement Protocol, as specified * in RFC2974. * * $Revision: 1.1 $ * $Date: 2003/05/28 11:03:35 $ * * Copyright (c) 2002 Argonne National Laboratory/University of Chicago * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Mathematics and * Computer Science Division of Argonne National Laboratory. * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. * */ #include "config_unix.h" #include "config_win32.h" #include "debug.h" #include "memory.h" #include "net_udp.h" #include "hmac.h" #include "qfDES.h" #include "base64.h" #include "gettimeofday.h" #include "vsnprintf.h" #include "sap.h" /* * The "struct sap" defines an SAP session. */ #define SAP_DB_SIZE 2048 struct sap { socket_udp *s; char *addr; uint16_t port; uint16_t ttl; sap_callback callback; }; struct sap * sap_init(const char *addr, uint16_t port, int ttl, sap_callback callback) { struct sap *session; session = (struct sap *)xmalloc(sizeof(struct sap)); memset (session, 0, sizeof(struct sap)); session->addr = xstrdup(addr); session->port = port; session->ttl = min(ttl, 127); session->s = udp_init(addr, port, port, ttl); if(session->s == NULL) { xfree(session); return(NULL); } session->callback = callback; return session; } int sap_recv(struct sap *s, struct timeval *timeout) { sap_packet sap_p; sap_header *sap_h; static unsigned char *packetptr; udp_fd_zero(); udp_fd_set(s->s); if(udp_select(timeout) > 0) { if(udp_fd_isset(s->s)) { uint8_t buffer[SAP_MAX_PACKET_LEN]; int buflen; buflen = udp_recv(s->s, buffer, SAP_MAX_PACKET_LEN); packetptr = buffer; sap_h = (sap_header *)buffer; sap_p.header = sap_h; packetptr += sizeof(sap_header); sap_p.originating_source = packetptr; packetptr += (sap_h->address_type) ? 16 : 4; sap_p.authentication_data = packetptr; packetptr += ntohs(sap_h->authentication_length/4); sap_p.payload = strstr(packetptr, "v=0"); if(packetptr < sap_p.payload) { sap_p.payload_type = packetptr; } else { sap_p.payload_type = 0; } s->callback(&sap_p); } return TRUE; } return FALSE; } void sap_done(struct sap *s) { udp_exit(s->s); xfree(s->addr); xfree(s); } void print_sap_packet(sap_packet *p) { printf("SAP Header Information:\n"); printf(" Version: %d\n", p->header->version); printf(" Address Type: %d\n", p->header->address_type); printf(" Reserved Bit: %d\n", p->header->reserved); printf(" Message Type: %d\n", p->header->message_type); printf(" Encrypted Flag: %d\n", p->header->encrypted_payload); printf(" Compressed Flag: %d\n", p->header->compressed_payload); printf(" Authentication Length: %d\n", ntohs(p->header->authentication_length)); printf(" Authentication Data: %d\n", p->header->authentication_length ? strlen(p->authentication_data) : 0); printf(" Message ID Hash: %d\n", ntohs(p->header->message_identifier_hash)); if(p->header->address_type) { // This is a 128 bit IPv6 address printf(" Originating Source: %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n", p->originating_source[0], p->originating_source[1], p->originating_source[2], p->originating_source[3], p->originating_source[4], p->originating_source[5], p->originating_source[6], p->originating_source[7], p->originating_source[8], p->originating_source[9], p->originating_source[10], p->originating_source[11], p->originating_source[12], p->originating_source[13], p->originating_source[14], p->originating_source[15]); } else { // This is a 32 bit IPv4 address printf(" Originating Source: %d.%d.%d.%d\n", p->originating_source[0], p->originating_source[1], p->originating_source[2], p->originating_source[3]); } if(p->payload_type != NULL) printf(" Payload Type: %s\n", p->payload_type); printf(" Payload: \n- - - - - - - - - -\n%s- - - - - - - - - -\n", p->payload); } uclmmbase-1.2.16.0/src/sap.h0000644000175000017500000000616607665113610014424 0ustar enderender/* * FILE: sap.h * AUTHOR: Ivan R. Judson * * $Revision: 1.1 $ * $Date: 2003/05/28 11:03:36 $ * * Copyright (c) 2002 Argonne National Laboratory/University of Chicago * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Mathematics and * Computer Science Division of Argonne National Laboratory. * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ #ifndef _SAP_H #define _SAP_H struct sap; #if defined(__cplusplus) extern "C" { #endif #define SAP_MAX_PACKET_LEN 1024 typedef struct { #ifdef WORDS_BIGENDIAN unsigned short version:3; unsigned short address_type:1; unsigned short reserved:1; unsigned short message_type:1; unsigned short encrypted_payload:1; unsigned short compressed_payload:1; #else unsigned short compressed_payload:1; unsigned short encrypted_payload:1; unsigned short message_type:1; unsigned short reserved:1; unsigned short address_type:1; unsigned short version:3; #endif uint8_t authentication_length; uint16_t message_identifier_hash; } sap_header; typedef struct { sap_header *header; unsigned char *originating_source; unsigned char *authentication_data; unsigned char *payload_type; unsigned char *payload; } sap_packet; typedef void (*sap_callback)(sap_packet *packet); struct sap *sap_init(const char *addr, uint16_t port, int ttl, sap_callback callback); int sap_recv(struct sap *s, struct timeval *timeout); void sap_done(struct sap *s); void print_sap_packet(sap_packet *p); #if defined(__cplusplus) } #endif #endif uclmmbase-1.2.16.0/src/sdp.c0000644000175000017500000004515507665117522014431 0ustar enderender/* * FILE: sdp.c * AUTHOR: Ivan R. Judson * * The routines in this file implement parsing and construction of data * that's compliant with the Session Description Protocol, as specified * in RFC draft-ietf-mmusic-sdp-new-08. * * $Revision: 1.2 $ * $Date: 2003/05/28 11:36:50 $ * * Copyright (c) 2002 Argonne National Laboratory/University of Chicago * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Mathematics and * Computer Science Division of Argonne National Laboratory. * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. * */ #include "config_unix.h" #include "config_win32.h" #include "debug.h" #include "memory.h" #include "sdp.h" int sdp_check_key(char keylist[], char *currentkey, char key) { char *tempkey = keylist; while(*tempkey != key) if(*tempkey != keylist[strlen(keylist)]) tempkey++; else return 0; if(tempkey >= currentkey) { currentkey = tempkey; return 1; } else { return 0; } } sdp_media * sdp_handle_session_key(sdp *session, char key, char *value) { sdp_media *media = NULL, *curr_media = NULL; sdp_repeat *repeat = NULL, *curr_repeat = NULL; sdp_timezone *timezone = NULL; sdp_network *network = NULL; sdp_bandwidth_modifier *bwm; sdp_attribute *attr, *curr_attr; sdp_encryption *encrypt; unsigned int n_char; switch (key) { case 'v': session->protocol_version = atoi(value); break; case 'o': network = xmalloc(sizeof(sdp_network)); memset (network, 0, sizeof(sdp_network)); sscanf(value, "%as %as %ld %as %as %as\n", &(session->username),&(session->session_id), &(session->version), &(network->network_type), &(network->address_type), &(network->address)); network->number_of_addresses = 1; session->network = network; break; case 's': session->name = xstrdup(value); break; case 'i': session->information = xstrdup(value); break; case 'u': session->uri = xstrdup(value); break; case 'e': session->email = xstrdup(value); break; case 'p': session->phone = xstrdup(value); break; case 'c': network = xmalloc(sizeof(sdp_network)); memset (network, 0, sizeof(sdp_network)); sscanf(value, "%as %as %as\n", &(network->network_type), &(network->address_type), &(network->address)); network->number_of_addresses = 1; if(session->network != NULL) session->network = network; else xfree(network); break; case 'b': bwm = xmalloc(sizeof(sdp_bandwidth_modifier)); memset (bwm, 0, sizeof(sdp_bandwidth_modifier)); sscanf(value, "%a[^:]:%a[^\n]", &(bwm->modifier), &(bwm->value)); if(session->bandwidth_modifier == NULL) session->bandwidth_modifier = bwm; else xfree(bwm); break; case 't': sscanf(value, "%ld %ld\n", &(session->start_time), &(session->stop_time)); break; case 'r': repeat = xmalloc(sizeof(sdp_repeat)); memset (repeat, 0, sizeof(sdp_repeat)); sscanf(value, "%as %as %as\n", &(repeat->interval), &(repeat->duration), &(repeat->offsets)); if(session->repeats == NULL) session->repeats = repeat; else { curr_repeat = session->repeats; while(curr_repeat != NULL) curr_repeat = curr_repeat->next; curr_repeat->next = repeat; } break; case 'z': /* This is icky but for now... */ timezone = xmalloc(sizeof(sdp_timezone)); memset(timezone, 0, sizeof(sdp_timezone)); sscanf(value, "%ld %ld", &(timezone->adjustment), &(timezone->offset)); session->timezones = timezone; break; case 'k': encrypt = xmalloc(sizeof(sdp_encryption)); memset(encrypt, 0, sizeof(sdp_encryption)); sscanf(value, "%a[^:]:%a[^\n]", &(encrypt->method), &(encrypt->key)); if(session->encryption == NULL) session->encryption = encrypt; else xfree(encrypt); break; case 'a': attr = xmalloc(sizeof(sdp_attribute)); memset(attr, 0, sizeof(sdp_attribute)); n_char = strcspn(value, ":"); attr->key = xmalloc(n_char+1); memset(attr->key, '\0', n_char+1); strncpy(attr->key, value, n_char); if(strlen(value) == n_char) attr->value = NULL; else { attr->value = xmalloc(strlen(value) - n_char + 1); memset(attr->value, '\0', strlen(value) - n_char + 1); strncpy(attr->value, value+n_char+1, strlen(value) - n_char); } if(session->attributes == NULL) session->attributes = attr; else { curr_attr = session->attributes; while(curr_attr->next != NULL) curr_attr = curr_attr->next; curr_attr->next = attr; } break; case 'm': media = xmalloc(sizeof(sdp_media)); memset(media, 0, sizeof(sdp_media)); sscanf(value, "%as %d %as %as\n", &(media->name), &(media->port), &(media->transport), &(media->format_list)); media->number_of_ports = 1; if(session->media == NULL) session->media = media; else { curr_media = session->media; while(curr_media->next != NULL) curr_media = curr_media->next; curr_media->next = media; } break; } return media; } sdp_media * sdp_handle_media_key(sdp_media *media, char key, char *value) { sdp_media *new_media; sdp_network *network; sdp_bandwidth_modifier *bwm; sdp_attribute *attr, *curr_attr; sdp_encryption *encrypt; unsigned int n_char; switch (key) { case 'i': media->information = xstrdup(value); break; case 'c': network = xmalloc(sizeof(sdp_network)); memset (network, 0, sizeof(sdp_network)); sscanf(value, "%as %as %as\n", &(network->network_type), &(network->address_type), &(network->address)); network->number_of_addresses = 1; if(media->network == NULL) media->network = network; else xfree(network); break; case 'b': bwm = xmalloc(sizeof(sdp_bandwidth_modifier)); memset (bwm, 0, sizeof(sdp_bandwidth_modifier)); sscanf(value, "%as:%as\n", &(bwm->modifier), &(bwm->value)); if(media->bandwidth_modifier == NULL) media->bandwidth_modifier = bwm; else xfree(bwm); break; case 'k': encrypt = xmalloc(sizeof(sdp_encryption)); memset(encrypt, 0, sizeof(sdp_encryption)); sscanf(value, "%as:%as\n", &(encrypt->method), &(encrypt->key)); if(media->encryption == NULL) media->encryption = encrypt; else xfree(encrypt); break; case 'a': attr = xmalloc(sizeof(sdp_attribute)); memset(attr, 0, sizeof(sdp_attribute)); n_char = strcspn(value, ":"); attr->key = xmalloc(n_char+1); memset(attr->key, '\0', n_char+1); strncpy(attr->key, value, n_char); if(strlen(value) == n_char) attr->value = NULL; else { attr->value = xmalloc(strlen(value) - n_char + 1); memset(attr->value, '\0', strlen(value) - n_char + 1); strncpy(attr->value, value+n_char+1, strlen(value) - n_char); } if(media->attributes == NULL) media->attributes = attr; else { curr_attr = media->attributes; while(curr_attr->next != NULL) curr_attr = curr_attr->next; curr_attr->next = attr; } break; case 'm': new_media = xmalloc(sizeof(sdp_media)); memset(new_media, 0, sizeof(sdp_media)); sscanf(value, "%as %d %as %as\n", &(new_media->name), &(new_media->port), &(new_media->transport), &(new_media->format_list)); new_media->number_of_ports = 1; media->next = new_media; media = media->next; break; } return media; } sdp *sdp_parse(char *sdp_string) { static char sessionkeys[] = "vosiuepcbtrzkam"; static char mediakeys[] = "micbka"; static char *current_key; int goodkey = 0; sdp_media *media = NULL; char *line = NULL, key, *value = NULL; static char *pos; sdp *session = NULL; int n_char; if(sdp_string != NULL) { current_key = sessionkeys; session = xmalloc(sizeof(sdp)); memset (session, 0, sizeof(sdp)); session->original = xstrdup(sdp_string); pos = sdp_string; do { n_char = strcspn(pos, "\n"); line = xmalloc(n_char+1); memset(line, '\0', n_char+1); strncpy(line, pos, n_char); pos += n_char + 1; if(strchr(line, '=') != NULL) { key = line[0]; value = &(line[2]); if(media == NULL) { if((goodkey = sdp_check_key(sessionkeys, current_key, key)) == 1) media = sdp_handle_session_key(session, key, value); else printf("Bad Session Key!\n"); } else { if((goodkey = sdp_check_key(mediakeys, current_key, key)) == 1) media = sdp_handle_media_key(media, key, value); else printf("Bad Media Key!\n"); } } xfree(line); } while (n_char != 0); } return session; } void sdp_print(sdp *session) { if(session != NULL) { sdp_media *current_media = session->media; sdp_attribute *current_attribute = session->attributes; printf("Protocol Version: %d\n", session->protocol_version); printf("Username: %s\n", session->username); printf("Session ID: %s\n", session->session_id); printf("Version: %ld\n", session->version); printf("Name: %s\n", session->name); printf("Information: %s\n", session->information); printf("URI: %s\n", session->uri); printf("Email: %s\n", session->email); printf("Phone: %s\n", session->phone); printf("Start Time: %ld\n", session->start_time); printf("Stop Time: %ld\n", session->stop_time); if(session->network != NULL) { sdp_print_network(session->network); } if(session->bandwidth_modifier != NULL) { printf("Bandwidth Modifier\n"); printf("\tModifier: %s\n", session->bandwidth_modifier->modifier); printf("\tValue: %s\n", session->bandwidth_modifier->value); } printf("Session Attributes:\n"); while(current_attribute != NULL) { printf("\tAttribute: %s Value: %s\n", current_attribute->key, current_attribute->value); current_attribute = current_attribute->next; } current_media = session->media; while(current_media != NULL) { sdp_print_media(current_media); current_media = current_media->next; } } } void sdp_print_network(sdp_network *network) { printf("Network Information:\n"); printf("\tNetwork Type: %s\n", network->network_type); printf("\tAddress Type: %s\n", network->address_type); printf("\tAddress: %s\n", network->address); printf("\t# of Addresses: %d\n", network->number_of_addresses); } void sdp_print_media(sdp_media *media) { sdp_attribute *curr_attr = media->attributes; printf("Media Configuration:\n"); printf("\tName: %s\n", media->name); printf("\tPort: %d Number of Ports: %d\n", media->port, media->number_of_ports); if(media->network != NULL) { sdp_print_network(media->network); } printf("\tTransport: %s\n", media->transport); printf("\tInformation: %s\n", media->information); if(media->attributes != NULL) { printf("\tMedia Attributes:\n"); while(curr_attr != NULL) { printf("\t\tAttribute: %s Value: %s\n", curr_attr->key, curr_attr->value); curr_attr = curr_attr->next; } } } char * sdp_make(sdp *session) { sdp_timezone *tz; sdp_attribute *attr; sdp_media *media; char *sdp_string; sdp_string = xmalloc(4096); sprintf(sdp_string, "v=%d\n", session->protocol_version); sprintf(sdp_string, "%so=%s %s %ld", sdp_string, session->username, session->session_id, session->version); if(session->network != NULL) { sprintf(sdp_string, "%s %s %s %s\n", sdp_string, session->network->network_type, session->network->address_type, session->network->address); } sprintf(sdp_string, "%ss=%s\n", sdp_string, session->name); if(session->information != NULL) sprintf(sdp_string, "%si=%s\n", sdp_string, session->information); if(session->uri != NULL) sprintf(sdp_string, "%su=%s\n", sdp_string, session->uri); if(session->email != NULL) sprintf(sdp_string, "%se=%s\n", sdp_string, session->email); if(session->phone != NULL) sprintf(sdp_string, "%sp=%s\n", sdp_string, session->phone); if(session->network != NULL) sprintf(sdp_string, "%sc=%s %s %s\n", sdp_string, session->network->network_type, session->network->address_type, session->network->address); if(session->bandwidth_modifier != NULL) sprintf(sdp_string, "%sb=%s:%s\n", sdp_string, session->bandwidth_modifier->modifier, session->bandwidth_modifier->value); sprintf(sdp_string, "%st=%ld %ld\n", sdp_string, session->start_time, session->stop_time); if(session->timezones != NULL) { tz = session->timezones; sprintf(sdp_string, "%sz=%ld %ld", sdp_string, tz->adjustment, tz->offset); while(tz->next != NULL) { sprintf(sdp_string, "%s %ld %ld", sdp_string, tz->next->adjustment, tz->next->offset); tz = tz->next; } sprintf(sdp_string, "%s\n", sdp_string); } if(session->encryption != NULL) { if(session->encryption->key == NULL) sprintf(sdp_string, "%sk=%s\n", sdp_string, session->encryption->method); else sprintf(sdp_string, "%sk=%s:%s\n", sdp_string, session->encryption->method, session->encryption->key); } attr = session->attributes; while(attr != NULL) { sprintf(sdp_string, "%sa=%s:%s\n", sdp_string, attr->key, attr->value); attr = attr->next; } media = session->media; while(media != NULL) { if(media->number_of_ports > 1) sprintf(sdp_string, "%sm=%s %d/%d %s %s\n", sdp_string, media->name, media->port, media->number_of_ports, media->transport, media->format_list); else sprintf(sdp_string, "%sm=%s %d %s %s\n", sdp_string, media->name, media->port, media->transport, media->format_list); if(media->information != NULL) sprintf(sdp_string, "%si=%s\n", sdp_string, media->information); if(media->network != NULL) sprintf(sdp_string, "%sc=%s %s %s\n", sdp_string, media->network->network_type, media->network->address_type, media->network->address); if(media->bandwidth_modifier != NULL) sprintf(sdp_string, "%sb=%s:%s\n", sdp_string, media->bandwidth_modifier->modifier, media->bandwidth_modifier->value); if(media->encryption != NULL) { if(media->encryption->key == NULL) sprintf(sdp_string, "%sk=%s\n", sdp_string, media->encryption->method); else sprintf(sdp_string, "%sk=%s:%s\n", sdp_string, media->encryption->method, media->encryption->key); } attr = media->attributes; while(attr != NULL) { sprintf(sdp_string, "%sa=%s:%s\n", sdp_string, attr->key, attr->value); attr = attr->next; } media = media->next; } return sdp_string; } void sdp_free(sdp *session) { sdp_media *media, *cmedia; sdp_attribute *attr, *cattr; sdp_repeat *repeat, *crepeat; if(session->username != NULL) xfree(session->username); if(session->session_id != NULL) xfree(session->session_id); if(session->network != NULL) sdp_free_network(session->network); if(session->name != NULL) xfree(session->name); if(session->information != NULL) xfree(session->information); if(session->uri != NULL) xfree(session->uri); if(session->email != NULL) xfree(session->email); if(session->phone != NULL) xfree(session->phone); if(session->bandwidth_modifier != NULL) sdp_free_bandwidth_modifier(session->bandwidth_modifier); if(session->timezones != NULL) xfree(session->timezones); if(session->encryption != NULL) sdp_free_encryption(session->encryption); repeat = session->repeats; while(repeat != NULL) { crepeat = repeat; repeat = repeat->next; sdp_free_repeat(crepeat); } attr = session->attributes; while(attr != NULL) { cattr = attr; attr = attr->next; sdp_free_attribute(cattr); } media = session->media; while(media != NULL) { cmedia = media; media = media->next; sdp_free_media(cmedia); } if(session->original != NULL) xfree(session->original); xfree(session); } void sdp_free_network(sdp_network *network) { xfree(network->network_type); xfree(network->address_type); xfree(network->address); xfree(network); } void sdp_free_attribute(sdp_attribute *attr) { xfree(attr->key); if(attr->value != NULL) xfree(attr->value); xfree(attr); } void sdp_free_encryption(sdp_encryption *encr) { xfree(encr->method); xfree(encr->key); xfree(encr); } void sdp_free_bandwidth_modifier(sdp_bandwidth_modifier *bwm) { xfree(bwm->modifier); xfree(bwm->value); xfree(bwm); } void sdp_free_repeat(sdp_repeat *repeat) { xfree(repeat->interval); xfree(repeat->duration); xfree(repeat->offsets); xfree(repeat); } void sdp_free_media(sdp_media *media) { sdp_attribute *attr, *cattr; xfree(media->name); if(media->network != NULL) sdp_free_network(media->network); xfree(media->transport); xfree(media->format_list); if(media->information != NULL) xfree(media->information); if(media->bandwidth_modifier != NULL) sdp_free_bandwidth_modifier(media->bandwidth_modifier); if(media->encryption != NULL) sdp_free_encryption(media->encryption); attr = media->attributes; while(attr != NULL) { cattr = attr; attr = attr->next; sdp_free_attribute(cattr); } xfree(media); } uclmmbase-1.2.16.0/src/sdp.h0000644000175000017500000001027307665113611014422 0ustar enderender/* * FILE: sdp.h * AUTHOR: Ivan R. Judson * * $Revision: 1.1 $ * $Date: 2003/05/28 11:03:37 $ * * Copyright (c) 2002 Argonne National Laboratory/University of Chicago * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Mathematics and * Computer Science Division of Argonne National Laboratory. * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ #ifndef _SDP_H #define _SDP_H #if defined(__cplusplus) extern "C" { #endif typedef struct sdp_network { char *network_type; char *address_type; char *address; int number_of_addresses; } sdp_network; typedef struct sdp_attribute { struct sdp_attribute *next; char *key; char *value; } sdp_attribute; typedef struct sdp_encryption { char *method; char *key; } sdp_encryption; typedef struct sdp_bandwidth_modifier { char *modifier; char *value; } sdp_bandwidth_modifier; typedef struct sdp_media { struct sdp_media *next; char *name; int port; int number_of_ports; sdp_network *network; char *transport; char *format_list; char *information; sdp_bandwidth_modifier *bandwidth_modifier; sdp_encryption *encryption; sdp_attribute *attributes; } sdp_media; typedef struct sdp_timezone { struct sdp_timezone *next; long adjustment; long offset; } sdp_timezone; typedef struct sdp_repeat { struct sdp_repeat *next; char *interval; char *duration; char *offsets; } sdp_repeat; typedef struct sdp { int protocol_version; char *username; char *session_id; long version; sdp_network *network; char *name; char *information; char *uri; char *email; char *phone; sdp_bandwidth_modifier *bandwidth_modifier; sdp_timezone *timezones; sdp_encryption *encryption; sdp_attribute *attributes; long start_time; long stop_time; sdp_repeat *repeats; sdp_media *media; char *original; } sdp; int sdp_check_key(char *keylist, char *currentkey, char key); sdp_media *sdp_handle_session_key(sdp *session, char key, char *value); sdp_media *sdp_handle_media_key(sdp_media *media, char key, char *value); sdp *sdp_parse(char *sdp_string); void sdp_print(sdp *session); void sdp_print_media(sdp_media *media); void sdp_print_network(sdp_network *network); char *sdp_make(sdp *session);; void sdp_free(sdp *session); void sdp_free_media(sdp_media *media); void sdp_free_attribute(sdp_attribute *attr); void sdp_free_encryption(sdp_encryption *encr); void sdp_free_bandwidth_modifier(sdp_bandwidth_modifier *bwm); void sdp_free_repeat(sdp_repeat *repeat); void sdp_free_network(sdp_network *network); #if defined(__cplusplus) } #endif #endif uclmmbase-1.2.16.0/src/sockstorage.h0000644000175000017500000000333307057740734016166 0ustar enderender/* * Copyright (C) 1999 WIDE Project. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ struct sockaddr_storage { #ifdef HAVE_SOCKADDR_SA_LEN uint8_t __ss_len; uint8_t __ss_family; uint8_t fill[126]; #else uint8_t __ss_family; uint8_t fill[127]; #endif /* HAVE_SOCKADDR_SA_LEN */ }; uclmmbase-1.2.16.0/src/util.c0000640000175000017500000002131207314411067014571 0ustar enderender/* * FILE: util.c * PROGRAM: RAT * AUTHOR: Isidor Kouvelas + Colin Perkins + Mark Handley + Orion Hodson * * $Revision: 1.15 $ * $Date: 2001/06/21 15:26:47 $ * * Copyright (c) 1995-2000 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Science * Department at University College London * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ #include "config_unix.h" #include "config_win32.h" #include "debug.h" #include "memory.h" #include "util.h" typedef struct s_block { struct s_block *next; } block; #define BLOCK_SIZE 5 #define SIZE_TO_INDEX(s) (((s) - 1) >> BLOCK_SIZE) #define INDEX_TO_SIZE(i) (((i) + 1) << BLOCK_SIZE) #define MAX_SIZE (1 << 17) #define MAX_INDEX SIZE_TO_INDEX(MAX_SIZE) static block *blocks[MAX_INDEX]; static int blocks_alloced; #ifdef DEBUG_MEM /* Block tracking for when things are going wrong */ #define MAX_BLOCKS_OUT 1280 static struct iovec blk_out[MAX_BLOCKS_OUT]; static int nblks_out; static int get_blk_idx_from_ptr(char *addr) { int i; for(i = 0; i < nblks_out; i++) { if (blk_out[i].iov_base == addr) { return i; } } return -1; } #endif /* DEBUG_MEM */ void * _block_alloc(unsigned int size, const char *filen, int line) { int i; unsigned int *c; char *p; assert(size > 0); assert(size < MAX_SIZE); i = SIZE_TO_INDEX(size); if (blocks[i] != NULL) { p = (char *)blocks[i]; blocks[i] = blocks[i]->next; xclaim((char*)p - 8, filen, line); } else { #ifdef DEBUG_MEM_BREAK /* This can only go here if this file is merged with memory.c! [oh] */ mem_item[naddr].blen = size; #endif /* DEBUG_MEM_BREAK */ p = (char *) _xmalloc(INDEX_TO_SIZE(i) + 8,filen,line); *((int *)p) = INDEX_TO_SIZE(i); p += 8; blocks_alloced++; } c = (unsigned int *)((char *)p - 8); if (size > *c) { fprintf(stderr, "block_alloc: block is too small %d %d!\n", size, *c); } #ifdef DEBUG_MEM if (blocks_alloced == MAX_BLOCKS_OUT) { debug_msg("Too many blocks allocated.\n"); xmemdist(stderr); xmemdmp(); } blk_out[nblks_out].iov_base = (char*)c; blk_out[nblks_out].iov_len = size; nblks_out++; #endif /* DEBUG_MEM */ c++; *c = size; assert(p != NULL); return (void*)p; } void block_trash_check() { #ifdef DEBUG_MEM int i,n,*c; block *b; for(i = 0; inext; assert(n++ < blocks_alloced); } } for (i = 0; i *c) { fprintf(stderr, "block_free: block was too small! %d %d\n", size, *c); } c++; if (size != *c) { fprintf(stderr, "block_free: Incorrect block size given! %d %d\n", size, *c); assert(size == *c); } i = SIZE_TO_INDEX(size); #ifdef DEBUG_MEM bp = blocks[i]; n = 0; while(bp) { if (bp == (block*)p) { debug_msg("already freed line %d\n", *((int *)p+1)); assert(0); } bp = bp->next; n++; } if (i >= 4) { *((int*)p+1) = line; } #endif /* DEBUG_MEM */ ((block *)p)->next = blocks[i]; blocks[i] = (block *)p; #ifdef DEBUG_MEM c--; i = get_blk_idx_from_ptr((char*)c); assert(i != -1); memmove(blk_out+i, blk_out + i + 1, sizeof(struct iovec) * (nblks_out - i)); nblks_out --; #endif /* DEBUG_MEM */ } void block_release_all(void) { int i; char *p,*q; printf("Freeing memory: "); fflush(stdout); for(i=0;inext; xfree(p-8); printf("+"); fflush(stdout); p = q; } } printf("\n"); } void purge_chars(char *src, char *to_go) { char *r, *w; r = w = src; while(*r) { *w = *r; if (!strchr(to_go, (int)*r)) { w++; } r++; } *w = '\0'; } static int string_to_words(char *s, char**w, int max_words) { int n; n = 0; w[0] = (char *) strtok(s, " "); if (w[0] == NULL) { return n; } while(++n < max_words) { w[n] = (char *) strtok(NULL, " "); if (w[n] == NULL) break; } return n; } int overlapping_words(const char *s1, const char *s2, int max_words) { char *c1, *c2, **w1, **w2; int nw1, nw2, nover, i, j; c1 = xstrdup(s1); c2 = xstrdup(s2); w1 = (char**)xmalloc(sizeof(char*)*max_words); w2 = (char**)xmalloc(sizeof(char*)*max_words); nw1 = string_to_words(c1, w1, max_words); nw2 = string_to_words(c2, w2, max_words); nover = 0; for(i = 0; i < nw1; i++) { for(j = 0; j < nw2; j++) { if (strcmp(w1[i], w2[j]) == 0) { nover++; continue; } } } xfree(w1); xfree(w2); xfree(c1); xfree(c2); return nover; } int strfind(const char *haystack, const char *needle_start, const char *needle_end) { /* Returns TRUE if the string between needle_start and needle_end */ /* is found in haystack. The haystack MUST be zero terminated. */ const char *n, *h; const char *h_end = haystack + strlen(haystack); #ifdef DEBUG /* Paranoia check that memory between needle_start and needle_end */ /* is a valid string, and doesn't contain a zero byte. */ /* check that start is before end */ assert(needle_start < needle_end); for (n = needle_start; n != needle_end; n++) { assert(*n != '\0'); } #endif n = needle_start; h = haystack; do { if (*n == *h) { n++; h++; } else { h = h - (n - needle_start) + 1; n = needle_start; } } while ((h < h_end) && (n <= needle_end)); if (n == (needle_end + 1)) { return TRUE; } return FALSE; } uclmmbase-1.2.16.0/src/util.h0000640000175000017500000000542707252665777014633 0ustar enderender/* * FILE: util.h * PROGRAM: RAT * AUTHOR: Isidor Kouvelas + Colin Perkins + Orion Hodson * * $Revision: 1.7 $ * $Date: 2001/03/11 12:13:51 $ * * Copyright (c) 1995-2000 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Science * Department at University College London * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ #ifndef _UTIL_H #define _UTIL_H #if defined(__cplusplus) extern "C" { #endif #define block_alloc(x) _block_alloc(x,__FILE__,__LINE__) #define block_free(x,y) _block_free(x,y,__LINE__) void *_block_alloc(unsigned size, const char *filen, int line); void _block_free(void *p, int size, int line); void block_release_all(void); void block_trash_check(void); void block_check(char *p); /* purge_chars: removes occurances of chars in to_go from src */ void purge_chars(char *src, char *to_go); /* overlapping_words: returns how many words match in two strings */ int overlapping_words(const char *s1, const char *s2, int max_words); /* The strfind() function is mainly for internal use, but might be useful to others... */ int strfind(const char *haystack, const char *needle_start, const char *needle_end); #if defined(__cplusplus) } #endif #endif uclmmbase-1.2.16.0/src/vsnprintf.c0000644000175000017500000000435107250223320015645 0ustar enderender/* * FILE: vsnprintf.c * AUTHOR: Colin Perkins * * Copyright (c) 1997-2001 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Science * Department at University College London * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ #include "config_unix.h" #include "debug.h" #include "vsnprintf.h" #ifndef HAVE_VSNPRINTF int vsnprintf(char *s, size_t buf_size, const char *format, va_list ap) { /* Quick hack replacement for vsnprintf... note that this */ /* doesn't check for buffer overflows, and so is open to */ /* many really nasty attacks! */ UNUSED(buf_size); return vsprintf(s,format,ap); } #endif uclmmbase-1.2.16.0/src/vsnprintf.h0000644000175000017500000000032007250223320015642 0ustar enderender#ifndef HAVE_VSNPRINTF #if defined(__cplusplus) extern "C" { #endif int vsnprintf(char *s, size_t buf_size, const char *format, va_list ap); #if defined(__cplusplus) } #endif #endif /* HAVE_VSNPRINTF */ uclmmbase-1.2.16.0/src/mbus_parser.c0000640000175000017500000001614410000553744016140 0ustar enderender/* * FILE: mbus_parser.c * AUTHOR: Colin Perkins * * Copyright (c) 1997-2000 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Science * Department at University College London * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ #include "config_unix.h" #include "config_win32.h" #include "debug.h" #include "memory.h" #include "mbus_parser.h" #define MBUS_PARSER_MAGIC 0xbadface struct mbus_parser { char *buffer; /* Temporary storage for parsing mbus commands */ char *bufend; /* End of space allocated for parsing, to check for overflows */ uint32_t magic; /* For debugging... */ }; struct mbus_parser *mbus_parse_init(char *str) { struct mbus_parser *m; m = (struct mbus_parser *) xmalloc(sizeof(struct mbus_parser)); m->buffer = str; m->bufend = str + strlen(str); m->magic = MBUS_PARSER_MAGIC; return m; } void mbus_parse_done(struct mbus_parser *m) { assert(m->magic == MBUS_PARSER_MAGIC); xfree(m); } #define CHECK_OVERRUN if (m->buffer > m->bufend) {\ debug_msg("parse m->buffer overflow\n");\ return FALSE;\ } int mbus_parse_lst(struct mbus_parser *m, char **l) { int instr = FALSE; int inlst = 0; assert(m->magic == MBUS_PARSER_MAGIC); while (isspace((unsigned char)*m->buffer)) { m->buffer++; CHECK_OVERRUN; } if (*m->buffer != '(') { return FALSE; } m->buffer++; *l = m->buffer; while (*m->buffer != '\0') { if ((*m->buffer == '"') && (*(m->buffer-1) != '\\')) { instr = !instr; } if ((*m->buffer == '(') && (*(m->buffer-1) != '\\') && !instr) { inlst++; } if ((*m->buffer == ')') && (*(m->buffer-1) != '\\') && !instr) { if (inlst > 0) { inlst--; } else { *m->buffer = '\0'; m->buffer++; CHECK_OVERRUN; return TRUE; } } m->buffer++; CHECK_OVERRUN; } return FALSE; } int mbus_parse_str(struct mbus_parser *m, char **s) { assert(m->magic == MBUS_PARSER_MAGIC); while (isspace((unsigned char)*m->buffer)) { m->buffer++; CHECK_OVERRUN; } if (*m->buffer != '"') { return FALSE; } *s = m->buffer++; while (*m->buffer != '\0') { if ((*m->buffer == '"') && (*(m->buffer-1) != '\\')) { m->buffer++; *m->buffer = '\0'; m->buffer++; return TRUE; } m->buffer++; CHECK_OVERRUN; } return FALSE; } int mbus_parse_sym(struct mbus_parser *m, char **s) { assert(m->magic == MBUS_PARSER_MAGIC); while (isspace((unsigned char)*m->buffer)) { m->buffer++; CHECK_OVERRUN; } if (!isgraph((unsigned char)*m->buffer)) { return FALSE; } *s = m->buffer++; while (!isspace((unsigned char)*m->buffer) && (*m->buffer != '\0')) { m->buffer++; CHECK_OVERRUN; } *m->buffer = '\0'; m->buffer++; CHECK_OVERRUN; return TRUE; } int mbus_parse_int(struct mbus_parser *m, int *i) { char *p; assert(m->magic == MBUS_PARSER_MAGIC); while (isspace((unsigned char)*m->buffer)) { m->buffer++; CHECK_OVERRUN; } *i = strtol(m->buffer, &p, 10); if (((*i == LONG_MAX) || (*i == LONG_MIN)) && (errno == ERANGE)) { debug_msg("integer out of range\n"); return FALSE; } if (p == m->buffer) { return FALSE; } if (!isspace((unsigned char)*p) && (*p != '\0')) { return FALSE; } m->buffer = p; CHECK_OVERRUN; return TRUE; } int mbus_parse_ts(struct mbus_parser *m, struct timeval *ts){ char *s; char *p; assert(m->magic == MBUS_PARSER_MAGIC); while (isspace((unsigned char)*m->buffer)) { m->buffer++; CHECK_OVERRUN; } s = m->buffer; while (!isspace((unsigned char)*m->buffer)){ m->buffer++; CHECK_OVERRUN; } if((m->buffer - s) < 4){ /* less than 1 sec */ ts->tv_sec = 0; ts->tv_usec = strtol(m->buffer - (m->buffer - s), &p, 10) * 1000; if(m->buffer != p){ debug_msg("failed to parse msec\n"); return FALSE; } } else { /* more than 1 sec */ ts->tv_usec = strtol(m->buffer-3, &p, 10) * 1000; if(m->buffer != p){ debug_msg("failed to parse msec\n"); return FALSE; } *(m->buffer - 3) = '\0'; ts->tv_sec = strtol(s, &p, 10); if((m->buffer-3 != p) || (ts->tv_sec == LONG_MAX) || (ts->tv_sec == LONG_MIN)){ debug_msg("failed to parse sec\n"); return FALSE; } } *m->buffer = '\0'; m->buffer++; CHECK_OVERRUN; return TRUE; } int mbus_parse_flt(struct mbus_parser *m, double *d) { char *p; assert(m->magic == MBUS_PARSER_MAGIC); while (isspace((unsigned char)*m->buffer)) { m->buffer++; CHECK_OVERRUN; } *d = strtod(m->buffer, &p); if (errno == ERANGE) { debug_msg("float out of range\n"); return FALSE; } if (p == m->buffer) { return FALSE; } if (!isspace((unsigned char)*p) && (*p != '\0')) { return FALSE; } m->buffer = p; CHECK_OVERRUN; return TRUE; } char *mbus_decode_str(char *s) { int l = strlen(s); int i, j; /* Check that this an encoded string... */ assert(s[0] == '\"'); assert(s[l-1] == '\"'); for (i=1,j=0; i < l - 1; i++,j++) { if (s[i] == '\\') { i++; } s[j] = s[i]; } s[j] = '\0'; return s; } char *mbus_encode_str(const char *s) { int i, j; int len = strlen(s); char *buf = (char *) xmalloc((len * 2) + 3); for (i = 0, j = 1; i < len; i++,j++) { if (s[i] == ' ') { buf[j] = '\\'; buf[j+1] = ' '; j++; } else if (s[i] == '\"') { buf[j] = '\\'; buf[j+1] = '\"'; j++; } else { buf[j] = s[i]; } } buf[0] = '\"'; buf[j] = '\"'; buf[j+1] = '\0'; return buf; } uclmmbase-1.2.16.0/COPYRIGHT0000640000175000017500000000361307034372531014161 0ustar enderenderCopyright (C) 1995-2000 University College London All rights reserved. Redistribution and use in source and binary forms, with or without modification, is permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the 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 the Computer Science Department at University College London 4. Neither the name of the University nor of the Department may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 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 OF SUCH DAMAGE. This product includes software developed by the Computer Systems Engineering Group at Lawrence Berkeley Laboratory. Encryption features of this software use the RSA Data Security, Inc. MD5 Message-Digest Algorithm. uclmmbase-1.2.16.0/MODS0000640000175000017500000005006010000554170013335 0ustar enderenderCommon Code Library: Modification history v1.0.0 - Initial version, based on RAT v3.2.7 * 14 November 1998 v1.0.1 - Added HMAC authentication code - Added timeout to udp_recv() - Added authentication of Mbus messages - Added RTP library - Added select and fd_set functions to net_udp.[ch] - IPv6 code now runs on the pre-release stack for Solaris 2.7 - Mbus code support a configuration file on Unix, and the registry on Win32, to save/restore settings - Add udp_host_addr() to get a text-version of the address to which a socket is bound. - Set IPv6 ttl and loopback state correctly on Solaris - Move mbus hearbeat code into this library - Remove key expiry from the mbus code, since it created race conditions when multiple tools for a single conference were started either side of the expiry time. - Update mbus addressing scheme - names are now sets of tokens, if the set of tokens in the destination address is a subset of the address of the entity receiving that message then the message is accepted. An empty set is a valid destination address for a message, and that will be accepted by all receivers (ie: a wildcard). - Remove channel ID from mbus code. - Fix configure script to work with solaris 2.7 where inet_aton() and inet_pton() have prototypes but no implementation. * 31 March 1999 [rat v4.0.0] v1.0.2 - Assorted fixes to RTP library - Fix bounds overruns in memory.c - will now run with -DDEBUG_MEM with the bounds checker on. - Add timestamp to mbus packet headers. - Add mbus_qmsgf() - Cleanup mbus transmission path - Add support for DES encryption to the mbus (on by default) - Fix DES code - Mbus keeps a cache of other entities, and only allows sending of reliable messages to known unicast addresses. - Mbus error function now takes a "type of error" argument - Added xrealloc() - Fix reordering of mbus messages * 14 May 1999 [rat v4.0.1] v1.0.3 - Fix inet_aton() in net_udp.c * 15 May 1999 [rat v4.0.2] v1.0.4 - Fix compilation with Microsoft IPv6 stack - Solaris 2.5.1 doesn't have vsnprintf(), use vsprintf() instead and don't worry about the possible buffer overflow problems. Reported by Holger Wirtz. - Added mbus_addr_valid() - Added timeout to mbus_recv() - Fixes to mbus code from Dirk Kutscher * 2 June 1999 [rat v4.0.3] v1.0.5 - Not quite sure what happened with this version, but if you have it it's probably not a good idea to use it! :-) v1.0.6 - Add ability to send to one port whilst receiving on another, requested by Henning Schulzrinne. - Add mbus_cmd_handler() to change the function handling the reception of mbus commands. - Compilation fixes for Irix 6.5 contributed by Bob Olson. - Add extra sanity checking to mbus_recv() - Add extra sanity checking to mbus_parse_* - Fix source address passed to mbus_recv() callback - was missing the "(" and ")" around it. - Fix memory leak in mbus_recv() - Fixes for configure script on 64 bit IRIX from Peter Orbaek - Move base64 tests into test_base64.c and integrate with the test suite * Released 5 July 1999 v1.0.7 - Add udp_exit to close sockets and leave multicast groups if necessary. - Fix mbus_exit close sockets. - Move the code to deal with the mbus configuration into mbus_config.c which will make it easier to write an mbus packet logger without code duplication (such a logger can't easily be part of mbus.c, since it's needs conflict with correct protocol operation). - Note that v1.3 of the Microsoft Research IPv6 stack requires an explicit route to be added for multicast traffic before a group can be joined. If you get errors in the IPV6_ADD_MEMBERSHIP setsockopt, this is probably the reason. We could specify an interface explicitly, but which one to pick? - Updates to the IPv6 code for the Detexis Musica IPv6 stack - Updates to the RTP code from Markus Germeier: time-out and delete sources, fix X but in RTP header, add support for sending BYE packets. - Add inet_pton() and inet_ntop() implementations, for those platforms which are missing them. - Add gettimeofday() workaround for win32 - Add drand48() workaround for win32 * Released 20 August 1999 v1.0.8 - Add mbus_sent_all() - Add loop count to mbus_recv(), so it will always return after 10 packets have been received. The prevents a denial of service attack if packets are sent faster than the timeout period. - Add binary tree. - Add OpenBSD fixes from Angelos D. Keromytis - Add Jerry Isdale's debug_dump() routine. - Add fix to RTP init_seq() to correct bug(?) in RFC1889 which means we incorrectly report the one packet lost in the first reporting interval. Fix by Bill Fenner. - Make the RTP create_source() routine return a pointer to the source. Patch from Bill Fenner. - Changes to the probation code in rtp.c from Bill Fenner. - Fix types in the RTP source struct. - Add a SOURCE_CREATED event to the RTP callback. - Add option to accept RTP packets before a corresponding RTCP packet has been received. - Add RX_RR_EMPTY event to the RTP code, to indicate that an empty reception report (ie: no report blocks) has been received. - Add RX_RTCP_START and RX_RTCP_FINISH events to the RTP code. - debug_msg() now displays the pid - The mbus code now maintains the list of active sources more correctly, making mbus_addr_valid() useful - rtp_init() now takes separate rx_port and tx_port, instead of a single port for both sending and receiving. - Add rtp_get_addr(), rtp_get_rx_port(), rtp_get_tx_port() and rtp_get_ttl() - Change return type of rtp_recv to int (was void). Returns TRUE if packets were processed, FALSE otherwise. - Timeout RRs from the RTP database, if they're not refreshed for 3 times the RTCP reporting interval - rtp_update() only expires sources once per reporting interval, to avoid burning too many cycles. - Mbus updates contributed by Markus Germeier - we now can configure the multicast address and port which the mbus should use in ~/.mbus - honor the SCOPE setting in ~/.mbus - expire sources we haven't heard from for a while - fixes small memory leak in remove_other_addr - mbus_exit now sends a mbus.quit and cleans up other_* structures - RTP updates contributed by Timur Friedman. - Add support for RTCP APP packets - Add support for a promiscuous mode to the RTP code, when in promiscuous mode there is no wait for a minimum number of RTP packets before recognizing a source. - Add the functions rtp_setopt() and rtp_getopt() that can be used to control various options (right now just promiscuous mode). - Split rtp_recv_data() into two functions. * 5 October 1999 v1.0.9 - Ignore ECONNREFUSED in net_udp.c - Add mbus_rendezvous_waiting() and mbus_rendezvous_go() to enable easy rendezvous between multiple processes. - Change rtp_setopt() and rtp_getopt() to take boolean options only. - Remove rtp_weak_validation(), use rtp_setopt(RTP_OPT_WEAK_VALIDATION) instead. - Delete RTP database entries which haven't been heard from for more than 5 times the RTCP reporting interval. * 2 November 1999 [rat v4.1.1] v1.0.10 - Mbus updates from Markus Germeier, which fix compatibility with the Uni Bremen implementation: - mbus.bye() signals an entity when it leaves. (mbus.quit commands an entity to leave) - Generate and work with 64 bit DES keys. Generate parity bits for key. Check if key in configuration file sets parity bits correctly. - mbus_heartbeat(m, 1) should send an mbus.hello() every second and not every two seconds - HMAC-MD5 should read HMAC-MD5-96 - Honor the MBUS environment variable for the MBUS configuration file - The TZI Mbus implementations generate spaces in configuration file, which mislead the UCL Mbus to dump core. Allow Spaces in .mbus - Address must be unique - Delete failed reliable messages if err_handler is present - Fix uninitialized use of session->last_update in RTP code - Fix assertion failures in RTP library when sending RTCP packets - Recognize, but ignore, profile specific extensions to RTCP SR/RR packets - Update RTCP reporting interval calculation - Implement reverse reconsideration of RTCP reporting interval - Fix tv_diff in rtp.c to handle negative results - Remove rtp_get_encryption_key(), the user of the library is assumed to remember the passphrase used and doesn't need access to the internal form of the key. - GNU autoconf modifications from Bill Fenner - Global change of integer types, and removal of compatibility defines: u_int8 -> u_int8_t u_int16 -> u_int16_t u_int32 -> u_int32_t and the same for the signed varients. - Implement encryption in the RTP code - Ignore connection refused errors in IPv4 UDP send. - Hide definition of struct mbus_config - Add a version number to the mbus config file - Fixes for FreeBSD v3.2 with INRIA IPv6 stack from Fred Templin - Add configure check for sin6_len in struct sockaddr_in6 (seems that FreeBSD has this, but many systems don't) - Fix batching of multiple mbus messages into one packet. * 13 December 1999 [rat v4.1.2] v1.1.0 - Changed autoconf generated header to uclconf.h. - Changed library name to uclmmbase to be consistent with other libs. - Add RTP_OPT_FILTER_MY_PACKETS - Cleanup test routines - Fix various potential buffer overflow problems - Update copyright notices to welcome in the new millennium - Previous versions of udp_send() would sometimes return -1 on error, and would sometimes abort(). We now always return -1 and never abort. - Add test routines for code in net_udp.c - Fix SCOPE parameter in mbus configuration on windows - Fix sending of hearbeat messages whilst in mbus.waiting() and mbus.go() loops - Tidy up mbus_qmsg(); - Add workaround for buffer overflow bug in _dprintf() which caused a crash under Windows NT service pack 6. This is not a real fix, we need to use vsnprintf() in there, but Windows doesn't implement it and I don't have time before we give the demo... Sigh, only two days wasted. - Fix buffer overflow in _dprintf() on Windows, using _vsnprintf(). - Update IPv6 support for Microsoft Research IPv6 stack, v1.4 - Use the versions of inet_ntop() and inet_pton() provided with the IPv6 stack, but retain our own implementation when building with IPv4 support only. - Use getaddrinfo() rather than getnodebyname() to get our IPv6 address if running with the Microsoft Research IPv6 stack. - We now require getaddrinfo() to be present in all IPv6 stacks: those which do not have this call (eg: the Musica IPv6 stack) MUST provide a workaround implementation. versions of MSR IPv6 prior to 1.4 are no longer supported. - Update IPv6 support for Red Hat Linux 6.1 - Fix generation of version.h on Win32 - Add VC++ project file to build the test suite under Win32 - Add extra debug code to the mbus library - Rewrite mbus code: mbus_parser.[ch] exist now, and include routines moved from the main mbus.[ch] files. Note that the interface to the mbus_parse_*() functions has now changed and is not backwards compatible. - Remove the mbus_addr() function, add an extra parameter to mbus_init() instead. * 28 January 2000 v1.1.1 - Add extra debugging code * 1 February 2000 v1.1.2 - Add routines for handling NTP format timestamps, in ntp.[ch] - Add udp_addr_valid. - Fix cname setup for Win32. - Add udp_init_if() call, to open a UDP/IP socket bound to a specific interface - Add rtp_init_if() call, to open an RTP socket bound to a specific interface - Add asarray.[ch] string holding associative array. - Fix compilation with -Wwrite-strings and -Wcast-align - Split mbus_addr_match() and mbus_add_identical() into mbus_addr.[ch] * 14 February 2000 v1.1.3 - Fix debug_set_core_dir() when not debugging. * 14 February 2000 v1.1.4 - Add tests for mbus_parser.c/mbus_addr.c and fix bugs found - Fix use of free()'d memory in mbus.c * 24 February 2000 v1.1.5 - Remove SunOS and Solaris defines from the configure script, they shouldn't be necessary any longer. - Add workaround for missing getaddrinfo() on some platforms. - Remove most of the abort() statements from udp_init(), we now return NULL in most cases of an error. - Fix header extension handling when padding bit set for RTP packets. - Change RTP event type #defines into rtp_event_type so compiler can check all cases are covered in decision blocks. - Fix waiting_ack next is set to null when message is put on ack list. - Add check for udp socket allocation success in mbus_init. - Add get_appname to util.[ch]. - Bound ttl to max 127 in rtp.c rather than asserting <= 127. - Change rtp_init to return NULL in rtp.c if ports or ttl inappropriate. - Clarify that rtp_recv(), rtp_send_data() and rtp_send_ctrl() take an RTP format timestamp for the current time. * 17 April 2000 v1.2.0 - Add udp_fd() function, to retrieve the underlying file descriptor. - udp_get_host_addr4() will now return NULL on failure, and leave errno set. - Workaround failure to get host IP address when setting the RTP CNAME (we use user@127.0.0.1 as the CNAME in this case). - Fix rtp_send_data() to correctly handle header extensions. This required a change to the API: the extn_len parameter now counts the length on the extension in 32 bit words minus one, and there is an additional extn_type parameter. If you don't use header extensions in your application, set the additional parameter to zero. - Fix reception of packets with RTP header extension. * 16 May 2000 v1.2.1 * 16 June 2000 [rat v4.2.5] v1.2.2 - Fix bug in mbus transmit code which caused messages to have the same sequence number as the preceeding ack. - Remove get_appname() function from util.[ch], since it didn't work in all cases (sometimes argv[0] doesn't contain anything sensible). - Fix RTP header extension code (patch from Jori ) as part of RTP interoperability tests. - FreeBSD 4.1 doesn't support binding to an IPv6 multicast address, must bind to in6addr_any instead (reported by Shirasaki Yasuhiro). - Fix validation of RTCP packets with padding (reported by Vladimir Brauner). - Fix padding octet count in RTCP packets sent with padding (Vladimir Brauner). - Fix RTCP timer reconsideration (Vladimir Brauner). * 22 August 2000 [rat v4.2.8] v1.2.3 - Add prototype for rtp_del_csrc() which will be needed by the mixer in rat. * 8 September 2000 [rat v4.2.9] v1.2.4 - Implement rtp_add_csrc() and rtp_del_csrc(). - ifdef'ed out FreeBSD bug check in test_net_udp.c for Win32. Prevents compilation of test cases otherwise. Reported by Micheal Stovenour . * 1 November 2000 [rat v4.2.10] v1.2.5 - More informative error message when the lock on the mbus configuration file cannot be gained. - rtp_init()/rtp_init_if() now take "const char *" for the address - Fix expiration of our own SSRC from the RTP database, if filtering our packets. - Mark entries in the RTP source database as active senders if we can an SR packet from them. - Cleanup RTP database once per second, rather than once per reporting interval. This is needed to ensure that reverse reconsideration works correctly, and sources are correctly deleted after BYEs are received. - Fix reverse reconsideration of the RTCP interval - Change socket_error to support formatted messages. - Add socket_error messages for gethostbyname failures. - Include lower layer overhead when calculating average RTCP size (patch from Timur Friedman). - Add support for SDES PRIV (the correct formatting of the PRIV item into prefix length, prefix and value is left to the caller). - Change xmalloc to fill allocated buffer with dummy value when DEBUG is defined. Change DEBUG_MEM version to use same dummy value rather than a random value, reduces chances of uninitialized pointers trashing data before crashing. - Add callback types to rtp.h - rtp_callback and rtcp_app_callback. - For consistency rtp_{get,set}opt -> rtp_{get,set}_option. - Remove unnecessary components from qfdes enumeration declarations. - New directories (src, tests, docs, examples). - Fixed Win32 .{dsw,dsp} files for new directory structure. - Documented net_udp.c. - Move strfind to util.[ch] from mbus_addr.[ch]. - Fix CSRC handling (patch from Ivo Sedlacek ) - Fix uninitialized field in SDES PRIV handling (Robert Olson) - Documented debug.[ch], hmac.[ch], md5.[ch], memory.[ch], rtp.[ch]. - Added small rtp example. - Change configure to only select doc for build if gtkdoc installed. * 5 April 2001 [rat v4.2.14] 1.2.6 - Fix so that we no longer send an RTCP BYE if we leave the session before sending any other packets. - Fix initial estimate of average RTCP packet size. - Implement RTCP BYE reconsideration. - Fix RTCP transmission interval. - Fix handling of probationary sources in the RTP code (a source is no longer treated as probationary if we've received RTCP packet from it). * 24 April 2001 [rat v4.2.16] 1.2.7 - Add support for Rijndael encryption to the RTP library, contributed by Robert Olson . - Fix IPv6 support on Linux - Add configuration for Windows 2000 IPv6 stack - Connect/disconnect to socket before/after getsockname call to make it work * 18 May 2001 [rat v4.2.17] 1.2.8 - Created a new socket for use for getsockname - there were too many bugs with disconnecting an IPv6 connected socket. - Fixed include ordering for Win2k. * 25 May 2001 [rat v4.2.18] [nte v2.2] 1.2.9 - Fix complience with draft-ietf-mmusic-mbus-transport-06.txt (patch from Lars Fischer) * 21 June 2001 [rat v4.2.19] 1.2.10 - RTCP APP packets can exactly fill the buffer (Timur Friedman) - Compilation fix for Debian Linux/IA64 (Jesus M. Gonzalez-Barahona) - Fix uninitialised variables in mbus.c (Eric Gerlach) * 24 September 2001 1.2.11 - Fix _xrealloc() in debug mode (Chris Greenhalgh) - Update configure script to better support IPv6 (Suzuki Shinsuke) - Fix count of CSRCs in mixer (Ladan Gharai) - Fixes for MacOS X and Win32 (Bill May) - Add udp_sendv() (Colin Perkins/Bill May) - Explicitly set send/recv buffer sizes to 1Mbyte (Colin Perkins) - Fix sense of RTP_OPT_WEAK_VALIDATION (Colin Perkins) - Make RTP_OPT_WEAK_VALIDATION more aggressive, for use when speed is more important than correctness (Colin Perkins) - Assorted performance tweaks to RTP code (Colin Perkins) - Add RTP_OPT_REUSE_PACKET_BUFS (Colin Perkins) - Fix potential crash in init_rng (Bill May) - Add rtp_send_data_iov() (Bill May) * 15 April 2002 1.2.12 - Compilation fixes for Win32 * 23 July 2002 1.2.13 - Compilation fixes for Solaris8 (Kristian Hasler) * 01 April 2003 1.2.14 - Increase size of mreq structure by 4 because of bug in Win2k MSv6 library - Added msvc build for a non-debug ipv6 win2k release. * 30 April 2003 1.2.15 - Added SAP/SDP support from Ivan Judson - Removed changes to mreq (see 1.2.14) - bug fixed in XP - Added code in mbus_recv function to ignore duplicate reliable messages * 19 June 2003 1.2.16 - Fix compilation with gcc33 (uint8_t value compared against 255). Still to do... - IPv6 code sometimes doesn't get the correct interface address, since it does a gethostbyname() and looks that up, yet that can return the IPv4 hostname only on some machines. - Doesn't do DNS AAAA lookups when given a name rather than an IP address. - Mbus code should check timestamp in received headers, and discard messages if it decreases, as a hinderance to replay attacks. - Mbus code should be more paranoid about handling garbage inputs, we can likely get all sorts of buffer overflows by feeding random data into it. - rtp_recv should split into rtp_select and rtp_recv. Jitter issues otherwise, as pointed out by Orion. - Allow a callback for background processing during mbus_rendezvous_*() - mbus_exit() queues an mbus.bye() message, but that never gets sent. - Handling of SSRC collisions is broken. - When weak RTP validation is enabled, spurious sources can be added to the database (from the CSRC area of a packet?). Reported by Xiaotao Wu - RTP estimate of lower layer overhead is IPv4 specific. uclmmbase-1.2.16.0/Makefile.in0000644000175000017500000000076407276565505014760 0ustar enderender# # Makefile for the common code library project. # This probably requires GNU make. # SUBDIRS=src tests examples @OPTDOC@ all: all-recursive all-recursive: for s in $(SUBDIRS) ; do (cd $$s && $(MAKE)) || exit 1 ; done clean: clean-recursive clean-recursive: for s in $(SUBDIRS) ; do (cd $$s && $(MAKE) clean) ; done distclean: distclean-recursive rm -f Makefile distclean-recursive: for s in $(SUBDIRS) ; do (cd $$s && $(MAKE) distclean) ; done .PHONY: clean clean-recursive distclean uclmmbase-1.2.16.0/README0000640000175000017500000000062410000554360013532 0ustar enderenderUCL Common Code Library Routines common to a number of multimedia tools. The library originates from work on the RAT project: these are portions that are not directly related to an audio tool and potentially useful elsewhere. This library is required to build RAT v3.2.7 or later, and may be needed for other UCL tools. -- Comments and contributions welcome, please email to mm-tools@cs.ucl.ac.uk. uclmmbase-1.2.16.0/VERSION0000640000175000017500000000000707777444502013744 0ustar enderender1.2.16 uclmmbase-1.2.16.0/common.dsw0000644000175000017500000000077206623340777014716 0ustar enderenderMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "common"=.\common.dsp - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### uclmmbase-1.2.16.0/config.guess0000755000175000017500000006411607015101141015201 0ustar enderender#! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc. # # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Written by Per Bothner . # The master version of this file is at the FSF in /home/gd/gnu/lib. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # The plan is that this can be called by configure scripts if you # don't specify an explicit system type (host/target name). # # Only a few systems have been added to this list; please add others # (but try to keep the structure clean). # # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 8/24/94.) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15 # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in alpha:OSF1:*:*) if test $UNAME_RELEASE = "V4.0"; then UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` fi # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. cat <dummy.s .globl main .ent main main: .frame \$30,0,\$26,0 .prologue 0 .long 0x47e03d80 # implver $0 lda \$2,259 .long 0x47e20c21 # amask $2,$1 srl \$1,8,\$2 sll \$2,2,\$2 sll \$0,3,\$0 addl \$1,\$0,\$0 addl \$2,\$0,\$0 ret \$31,(\$26),1 .end main EOF ${CC-cc} dummy.s -o dummy 2>/dev/null if test "$?" = 0 ; then ./dummy case "$?" in 7) UNAME_MACHINE="alpha" ;; 15) UNAME_MACHINE="alphaev5" ;; 14) UNAME_MACHINE="alphaev56" ;; 10) UNAME_MACHINE="alphapca56" ;; 16) UNAME_MACHINE="alphaev6" ;; esac fi rm -f dummy.s dummy echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr [[A-Z]] [[a-z]]` exit 0 ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit 0 ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-cbm-sysv4 exit 0;; amiga:NetBSD:*:*) echo m68k-cbm-netbsd${UNAME_RELEASE} exit 0 ;; amiga:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit 0 ;; arc64:OpenBSD:*:*) echo mips64el-unknown-openbsd${UNAME_RELEASE} exit 0 ;; arc:OpenBSD:*:*) echo mipsel-unknown-openbsd${UNAME_RELEASE} exit 0 ;; hkmips:OpenBSD:*:*) echo mips-unknown-openbsd${UNAME_RELEASE} exit 0 ;; pmax:OpenBSD:*:*) echo mipsel-unknown-openbsd${UNAME_RELEASE} exit 0 ;; sgi:OpenBSD:*:*) echo mips-unknown-openbsd${UNAME_RELEASE} exit 0 ;; wgrisc:OpenBSD:*:*) echo mipsel-unknown-openbsd${UNAME_RELEASE} exit 0 ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit 0;; arm32:NetBSD:*:*) echo arm-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` exit 0 ;; SR2?01:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit 0;; Pyramid*:OSx*:*:*|MIS*:OSx*:*:*|MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit 0 ;; NILE:*:*:dcosx) echo pyramid-pyramid-svr4 exit 0 ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; i86pc:SunOS:5.*:*) echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit 0 ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit 0 ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit 0 ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit 0 ;; atari*:NetBSD:*:*) echo m68k-atari-netbsd${UNAME_RELEASE} exit 0 ;; atari*:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; sun3*:NetBSD:*:*) echo m68k-sun-netbsd${UNAME_RELEASE} exit 0 ;; sun3*:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mac68k:NetBSD:*:*) echo m68k-apple-netbsd${UNAME_RELEASE} exit 0 ;; mac68k:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mvme68k:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; mvme88k:OpenBSD:*:*) echo m88k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit 0 ;; macppc:NetBSD:*:*) echo powerpc-apple-netbsd${UNAME_RELEASE} exit 0 ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit 0 ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit 0 ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit 0 ;; 2020:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit 0 ;; mips:*:*:UMIPS | mips:*:*:RISCos) sed 's/^ //' << EOF >dummy.c int main (argc, argv) int argc; char **argv; { #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF ${CC-cc} dummy.c -o dummy \ && ./dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ && rm dummy.c dummy && exit 0 rm -f dummy.c dummy echo mips-mips-riscos${UNAME_RELEASE} exit 0 ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit 0 ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit 0 ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit 0 ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit 0 ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \ -o ${TARGET_BINARY_INTERFACE}x = x ] ; then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit 0 ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit 0 ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit 0 ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit 0 ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit 0 ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit 0 ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i?86:AIX:*:*) echo i386-ibm-aix exit 0 ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then sed 's/^ //' << EOF >dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0 rm -f dummy.c dummy echo rs6000-ibm-aix3.2.5 elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit 0 ;; *:AIX:*:4) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'` if /usr/sbin/lsattr -EHl ${IBM_CPU_ID} | grep POWER >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=4.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit 0 ;; *:AIX:*:*) echo rs6000-ibm-aix exit 0 ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit 0 ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit 0 ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit 0 ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit 0 ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit 0 ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit 0 ;; 9000/[34678]??:HP-UX:*:*) case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/6?? | 9000/7?? | 9000/80[24] | 9000/8?[13679] | 9000/892 ) sed 's/^ //' << EOF >dummy.c #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (${CC-cc} dummy.c -o dummy 2>/dev/null ) && HP_ARCH=`./dummy` rm -f dummy.c dummy esac HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit 0 ;; 3050*:HI-UX:*:*) sed 's/^ //' << EOF >dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0 rm -f dummy.c dummy echo unknown-hitachi-hiuxwe2 exit 0 ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit 0 ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit 0 ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit 0 ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit 0 ;; i?86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit 0 ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit 0 ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit 0 ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit 0 ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit 0 ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit 0 ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit 0 ;; CRAY*X-MP:*:*:*) echo xmp-cray-unicos exit 0 ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} exit 0 ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ exit 0 ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} exit 0 ;; CRAY-2:*:*:*) echo cray2-cray-unicos exit 0 ;; F300:UNIX_System_V:*:*) FUJITSU_SYS=`uname -p | tr [A-Z] [a-z] | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit 0 ;; F301:UNIX_System_V:*:*) echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'` exit 0 ;; hp3[0-9][05]:NetBSD:*:*) echo m68k-hp-netbsd${UNAME_RELEASE} exit 0 ;; hp300:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit 0 ;; i?86:BSD/386:*:* | *:BSD/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit 0 ;; *:FreeBSD:*:*) echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit 0 ;; *:NetBSD:*:*) echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` exit 0 ;; *:OpenBSD:*:*) echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` exit 0 ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit 0 ;; i*:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit 0 ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit 0 ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit 0 ;; *:GNU:*:*) echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit 0 ;; *:Linux:*:*) # uname on the ARM produces all sorts of strangeness, and we need to # filter it out. case "$UNAME_MACHINE" in arm* | sa110*) UNAME_MACHINE="arm" ;; esac # The BFD linker knows what the default object file format is, so # first see if it will tell us. ld_help_string=`ld --help 2>&1` ld_supported_emulations=`echo $ld_help_string \ | sed -ne '/supported emulations:/!d s/[ ][ ]*/ /g s/.*supported emulations: *// s/ .*// p'` case "$ld_supported_emulations" in i?86linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" ; exit 0 ;; i?86coff) echo "${UNAME_MACHINE}-pc-linux-gnucoff" ; exit 0 ;; sparclinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;; armlinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;; m68klinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;; elf32ppc) echo "powerpc-unknown-linux-gnu" ; exit 0 ;; esac if test "${UNAME_MACHINE}" = "alpha" ; then sed 's/^ //' <dummy.s .globl main .ent main main: .frame \$30,0,\$26,0 .prologue 0 .long 0x47e03d80 # implver $0 lda \$2,259 .long 0x47e20c21 # amask $2,$1 srl \$1,8,\$2 sll \$2,2,\$2 sll \$0,3,\$0 addl \$1,\$0,\$0 addl \$2,\$0,\$0 ret \$31,(\$26),1 .end main EOF LIBC="" ${CC-cc} dummy.s -o dummy 2>/dev/null if test "$?" = 0 ; then ./dummy case "$?" in 7) UNAME_MACHINE="alpha" ;; 15) UNAME_MACHINE="alphaev5" ;; 14) UNAME_MACHINE="alphaev56" ;; 10) UNAME_MACHINE="alphapca56" ;; 16) UNAME_MACHINE="alphaev6" ;; esac objdump --private-headers dummy | \ grep ld.so.1 > /dev/null if test "$?" = 0 ; then LIBC="libc1" fi fi rm -f dummy.s dummy echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0 elif test "${UNAME_MACHINE}" = "mips" ; then cat >dummy.c </dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0 rm -f dummy.c dummy else # Either a pre-BFD a.out linker (linux-gnuoldld) # or one that does not give us useful --help. # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout. # If ld does not provide *any* "supported emulations:" # that means it is gnuoldld. echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:" test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0 case "${UNAME_MACHINE}" in i?86) VENDOR=pc; ;; *) VENDOR=unknown; ;; esac # Determine whether the default compiler is a.out or elf cat >dummy.c < main(argc, argv) int argc; char *argv[]; { #ifdef __ELF__ # ifdef __GLIBC__ # if __GLIBC__ >= 2 printf ("%s-${VENDOR}-linux-gnu\n", argv[1]); # else printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); # endif # else printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); # endif #else printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]); #endif return 0; } EOF ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0 rm -f dummy.c dummy fi ;; # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions # are messed up and put the nodename in both sysname and nodename. i?86:DYNIX/ptx:4*:*) echo i386-sequent-sysv4 exit 0 ;; i?86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit 0 ;; i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*) if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE} fi exit 0 ;; i?86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit 0 ;; i?86:UnixWare:*:*) if /bin/uname -X 2>/dev/null >/dev/null ; then (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 fi echo ${UNAME_MACHINE}-unixware-${UNAME_RELEASE}-${UNAME_VERSION} exit 0 ;; pc:*:*:*) # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i386. echo i386-pc-msdosdjgpp exit 0 ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit 0 ;; paragon:*:*:*) echo i860-intel-osf1 exit 0 ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit 0 ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit 0 ;; M68*:*:R3V[567]*:*) test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && echo i486-ncr-sysv4.3${OS_REL} && exit 0 /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && echo i486-ncr-sysv4 && exit 0 ;; m68*:LynxOS:2.*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit 0 ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit 0 ;; i?86:LynxOS:2.*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit 0 ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit 0 ;; rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit 0 ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit 0 ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit 0 ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit 0 ;; PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit 0 ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit 0 ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit 0 ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit 0 ;; news*:NEWS-OS:*:6*) echo mips-sony-newsos6 exit 0 ;; R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R4000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit 0 ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit 0 ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit 0 ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit 0 ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 cat >dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) #if !defined (ultrix) printf ("vax-dec-bsd\n"); exit (0); #else printf ("vax-dec-ultrix\n"); exit (0); #endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0 rm -f dummy.c dummy # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit 0 ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit 0 ;; c34*) echo c34-convex-bsd exit 0 ;; c38*) echo c38-convex-bsd exit 0 ;; c4*) echo c4-convex-bsd exit 0 ;; esac fi #echo '(Unable to guess system type)' 1>&2 exit 1 uclmmbase-1.2.16.0/config.sub0000755000175000017500000004654607015101142014654 0ustar enderender#! /bin/sh # Configuration validation subroutine script, version 1.1. # Copyright (C) 1991, 92-97, 1998 Free Software Foundation, Inc. # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # This file is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. if [ x$1 = x ] then echo Configuration name missing. 1>&2 echo "Usage: $0 CPU-MFR-OPSYS" 1>&2 echo "or $0 ALIAS" 1>&2 echo where ALIAS is a recognized configuration type. 1>&2 exit 1 fi # First pass through any local machine types. case $1 in *local*) echo $1 exit 0 ;; *) ;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in linux-gnu*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple) os= basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco5) os=sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. tahoe | i860 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \ | arme[lb] | pyramid | mn10200 | mn10300 | tron | a29k \ | 580 | i960 | h8300 | hppa | hppa1.0 | hppa1.1 | hppa2.0 \ | alpha | alphaev5 | alphaev56 | we32k | ns16k | clipper \ | i370 | sh | powerpc | powerpcle | 1750a | dsp16xx | pdp11 \ | mips64 | mipsel | mips64el | mips64orion | mips64orionel \ | mipstx39 | mipstx39el \ | sparc | sparclet | sparclite | sparc64 | v850) basic_machine=$basic_machine-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i[34567]86) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. vax-* | tahoe-* | i[34567]86-* | i860-* | m32r-* | m68k-* | m68000-* \ | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \ | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \ | power-* | none-* | 580-* | cray2-* | h8300-* | i960-* \ | xmp-* | ymp-* | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* \ | alpha-* | alphaev5-* | alphaev56-* | we32k-* | cydra-* \ | ns16k-* | pn-* | np1-* | xps100-* | clipper-* | orion-* \ | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \ | sparc64-* | mips64-* | mipsel-* \ | mips64el-* | mips64orion-* | mips64orionel-* \ | mipstx39-* | mipstx39el-* \ | f301-*) ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-cbm ;; amigaos | amigados) basic_machine=m68k-cbm os=-amigaos ;; amigaunix | amix) basic_machine=m68k-cbm os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | ymp) basic_machine=ymp-cray os=-unicos ;; cray2) basic_machine=cray2-cray os=-unicos ;; [ctj]90-cray) basic_machine=c90-cray os=-unicos ;; crds | unos) basic_machine=m68k-crds ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; i370-ibm* | ibm*) basic_machine=i370-ibm os=-mvs ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? i[34567]86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i[34567]86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i[34567]86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i[34567]86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; miniframe) basic_machine=m68000-convergent ;; mipsel*-linux*) basic_machine=mipsel-unknown os=-linux-gnu ;; mips*-linux*) basic_machine=mips-unknown os=-linux-gnu ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; np1) basic_machine=np1-gould ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pentium | p5 | k5 | nexen) basic_machine=i586-pc ;; pentiumpro | p6 | k6 | 6x86) basic_machine=i686-pc ;; pentiumii | pentium2) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | nexen-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | k6-* | 6x86-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=rs6000-ibm ;; ppc) basic_machine=powerpc-unknown ;; ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; symmetry) basic_machine=i386-sequent os=-dynix ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; tower | tower-32) basic_machine=m68k-ncr ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; xmp) basic_machine=xmp-cray os=-unicos ;; xps | xps100) basic_machine=xps100-honeywell ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. mips) if [ x$os = x-linux-gnu ]; then basic_machine=mips-unknown else basic_machine=mips-mips fi ;; romp) basic_machine=romp-ibm ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sparc) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -uxpv* | -beos*) # Remember, each alternative MUST END IN *, to match a version number. ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -ctix* | -uts*) os=-sysv ;; -ns2 ) os=-nextstep2 ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -xenix) os=-xenix ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in *-acorn) os=-riscix1.2 ;; arm*-semi) os=-aout ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 # This also exists in the configure program, but was not the # default. # os=-sunos4 ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-ibm) os=-aix ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f301-fujitsu) os=-uxpv ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -aix*) vendor=ibm ;; -hpux*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs*) vendor=ibm ;; -ptx*) vendor=sequent ;; -vxsim* | -vxworks*) vendor=wrs ;; -aux*) vendor=apple ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os uclmmbase-1.2.16.0/configure0000751000175000017500000024141007642543242014600 0ustar enderender#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated automatically using autoconf version 2.13 # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. # Defaults: ac_help= ac_default_prefix=/usr/local # Any additions from configure.in: ac_help="$ac_help --enable-profile enable profiling" ac_help="$ac_help --enable-bounds enable bounds checking" ac_help="$ac_help --enable-debug enable debug messages and code" ac_help="$ac_help --enable-debug-mem enable memory debugging code" ac_help="$ac_help --enable-ipv6 enable ipv6" # Initialize some variables set by options. # The variables have the same names as the options, with # dashes changed to underlines. build=NONE cache_file=./config.cache exec_prefix=NONE host=NONE no_create= nonopt=NONE no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= target=NONE verbose= x_includes=NONE x_libraries=NONE bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datadir='${prefix}/share' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' # Initialize some other variables. subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Maximum number of lines to put in a shell here document. ac_max_here_lines=12 ac_prev= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval "$ac_prev=\$ac_option" ac_prev= continue fi case "$ac_option" in -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; *) ac_optarg= ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case "$ac_option" in -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir="$ac_optarg" ;; -build | --build | --buil | --bui | --bu) ac_prev=build ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build="$ac_optarg" ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file="$ac_optarg" ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) datadir="$ac_optarg" ;; -disable-* | --disable-*) ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` eval "enable_${ac_feature}=no" ;; -enable-* | --enable-*) ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "enable_${ac_feature}='$ac_optarg'" ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix="$ac_optarg" ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he) # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat << EOF Usage: configure [options] [host] Options: [defaults in brackets after descriptions] Configuration: --cache-file=FILE cache test results in FILE --help print this message --no-create do not create output files --quiet, --silent do not print \`checking...' messages --version print the version of autoconf that created configure Directory and file names: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [same as prefix] --bindir=DIR user executables in DIR [EPREFIX/bin] --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] --libexecdir=DIR program executables in DIR [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data in DIR [PREFIX/share] --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data in DIR [PREFIX/com] --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] --libdir=DIR object code libraries in DIR [EPREFIX/lib] --includedir=DIR C header files in DIR [PREFIX/include] --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] --infodir=DIR info documentation in DIR [PREFIX/info] --mandir=DIR man documentation in DIR [PREFIX/man] --srcdir=DIR find the sources in DIR [configure dir or ..] --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names EOF cat << EOF Host type: --build=BUILD configure for building on BUILD [BUILD=HOST] --host=HOST configure for HOST [guessed] --target=TARGET configure for TARGET [TARGET=HOST] Features and packages: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --x-includes=DIR X include files are in DIR --x-libraries=DIR X library files are in DIR EOF if test -n "$ac_help"; then echo "--enable and --with options recognized:$ac_help" fi exit 0 ;; -host | --host | --hos | --ho) ac_prev=host ;; -host=* | --host=* | --hos=* | --ho=*) host="$ac_optarg" ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir="$ac_optarg" ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir="$ac_optarg" ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir="$ac_optarg" ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir="$ac_optarg" ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst \ | --locals | --local | --loca | --loc | --lo) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) localstatedir="$ac_optarg" ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir="$ac_optarg" ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir="$ac_optarg" ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix="$ac_optarg" ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix="$ac_optarg" ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix="$ac_optarg" ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name="$ac_optarg" ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir="$ac_optarg" ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir="$ac_optarg" ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site="$ac_optarg" ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir="$ac_optarg" ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir="$ac_optarg" ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target="$ac_optarg" ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers) echo "configure generated by autoconf version 2.13" exit 0 ;; -with-* | --with-*) ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "with_${ac_package}='$ac_optarg'" ;; -without-* | --without-*) ac_package=`echo $ac_option|sed -e 's/-*without-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` eval "with_${ac_package}=no" ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes="$ac_optarg" ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries="$ac_optarg" ;; -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } ;; *) if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then echo "configure: warning: $ac_option: invalid host type" 1>&2 fi if test "x$nonopt" != xNONE; then { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } fi nonopt="$ac_option" ;; esac done if test -n "$ac_prev"; then { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } fi trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 # File descriptor usage: # 0 standard input # 1 file creation # 2 errors and warnings # 3 some systems may open it to /dev/tty # 4 used on the Kubota Titan # 6 checking for... messages and results # 5 compiler messages saved in config.log if test "$silent" = yes; then exec 6>/dev/null else exec 6>&1 fi exec 5>./config.log echo "\ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. " 1>&5 # Strip out --no-create and --no-recursion so they do not pile up. # Also quote any args containing shell metacharacters. ac_configure_args= for ac_arg do case "$ac_arg" in -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) ac_configure_args="$ac_configure_args '$ac_arg'" ;; *) ac_configure_args="$ac_configure_args $ac_arg" ;; esac done # NLS nuisances. # Only set these to C if already set. These must not be set unconditionally # because not all systems understand e.g. LANG=C (notably SCO). # Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! # Non-C LC_CTYPE values break the ctype check. if test "${LANG+set}" = set; then LANG=C; export LANG; fi if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h # AIX cpp loses on an empty file, so make sure it contains at least a newline. echo > confdefs.h # A filename unique to this package, relative to the directory that # configure is in, which we can look for to find out if srcdir is correct. ac_unique_file=src/base64.c # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then its parent. ac_prog=$0 ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. srcdir=$ac_confdir if test ! -r $srcdir/$ac_unique_file; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r $srcdir/$ac_unique_file; then if test "$ac_srcdir_defaulted" = yes; then { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } else { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } fi fi srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` # Prefer explicitly selected file to automatically selected ones. if test -z "$CONFIG_SITE"; then if test "x$prefix" != xNONE; then CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" else CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then echo "loading site script $ac_site_file" . "$ac_site_file" fi done if test -r "$cache_file"; then echo "loading cache $cache_file" . $cache_file else echo "creating cache $cache_file" > $cache_file fi ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross ac_exeext= ac_objext=o if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then ac_n= ac_c=' ' ac_t=' ' else ac_n=-n ac_c= ac_t= fi else ac_n= ac_c='\c' ac_t= fi ac_aux_dir= for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do if test -f $ac_dir/install-sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f $ac_dir/install.sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break fi done if test -z "$ac_aux_dir"; then { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } fi ac_config_guess=$ac_aux_dir/config.guess ac_config_sub=$ac_aux_dir/config.sub ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. # Make sure we can run config.sub. if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } fi echo $ac_n "checking host system type""... $ac_c" 1>&6 echo "configure:562: checking host system type" >&5 host_alias=$host case "$host_alias" in NONE) case $nonopt in NONE) if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } fi ;; *) host_alias=$nonopt ;; esac ;; esac host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$host" 1>&6 # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:586: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CC="gcc" break fi done IFS="$ac_save_ifs" fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:616: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_prog_rejected=no ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" break fi done IFS="$ac_save_ifs" if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# -gt 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift set dummy "$ac_dir/$ac_word" "$@" shift ac_cv_prog_CC="$@" fi fi fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi if test -z "$CC"; then case "`uname -s`" in *win32* | *WIN32*) # Extract the first word of "cl", so it can be a program name with args. set dummy cl; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:667: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CC="cl" break fi done IFS="$ac_save_ifs" fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi ;; esac fi test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 echo "configure:699: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext << EOF #line 710 "configure" #include "confdefs.h" main(){return(0);} EOF if { (eval echo configure:715: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then ac_cv_prog_cc_cross=no else ac_cv_prog_cc_cross=yes fi else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 ac_cv_prog_cc_works=no fi rm -fr conftest* ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 if test $ac_cv_prog_cc_works = no; then { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 echo "configure:741: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 echo "configure:746: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no fi fi echo "$ac_t""$ac_cv_prog_gcc" 1>&6 if test $ac_cv_prog_gcc = yes; then GCC=yes else GCC= fi ac_test_CFLAGS="${CFLAGS+set}" ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 echo "configure:774: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else echo 'void f(){}' > conftest.c if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then ac_cv_prog_cc_g=yes else ac_cv_prog_cc_g=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 if test "$ac_test_CFLAGS" = set; then CFLAGS="$ac_save_CFLAGS" elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 echo "configure:806: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else # This must be in double quotes, not single quotes, because CPP may get # substituted into the Makefile and "${CC-cc}" will confuse make. CPP="${CC-cc} -E" # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:827: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:844: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP="${CC-cc} -nologo -E" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:861: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP=/lib/cpp fi rm -f conftest* fi rm -f conftest* fi rm -f conftest* ac_cv_prog_CPP="$CPP" fi CPP="$ac_cv_prog_CPP" else ac_cv_prog_CPP="$CPP" fi echo "$ac_t""$CPP" 1>&6 # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:888: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_RANLIB="ranlib" break fi done IFS="$ac_save_ifs" test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" fi fi RANLIB="$ac_cv_prog_RANLIB" if test -n "$RANLIB"; then echo "$ac_t""$RANLIB" 1>&6 else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 echo "configure:917: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include #include #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:930: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* ac_cv_header_stdc=yes else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "memchr" >/dev/null 2>&1; then : else rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "free" >/dev/null 2>&1; then : else rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') #define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF if { (eval echo configure:997: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_header_stdc=no fi rm -fr conftest* fi fi fi echo "$ac_t""$ac_cv_header_stdc" 1>&6 if test $ac_cv_header_stdc = yes; then cat >> confdefs.h <<\EOF #define STDC_HEADERS 1 EOF fi echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6 echo "configure:1021: checking for sys/wait.h that is POSIX.1 compatible" >&5 if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include #ifndef WEXITSTATUS #define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) #endif #ifndef WIFEXITED #define WIFEXITED(stat_val) (((stat_val) & 255) == 0) #endif int main() { int s; wait (&s); s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; ; return 0; } EOF if { (eval echo configure:1042: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_header_sys_wait_h=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_header_sys_wait_h=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_header_sys_wait_h" 1>&6 if test $ac_cv_header_sys_wait_h = yes; then cat >> confdefs.h <<\EOF #define HAVE_SYS_WAIT_H 1 EOF fi for ac_hdr in sys/time.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo "configure:1066: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1076: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 fi done if test "$ac_cv_header_sys_time_h" = "yes"; then echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6 echo "configure:1104: checking whether time.h and sys/time.h may both be included" >&5 if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include #include int main() { struct tm *tp; ; return 0; } EOF if { (eval echo configure:1118: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_header_time=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_header_time=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_header_time" 1>&6 if test $ac_cv_header_time = yes; then cat >> confdefs.h <<\EOF #define TIME_WITH_SYS_TIME 1 EOF fi fi echo $ac_n "checking for working const""... $ac_c" 1>&6 echo "configure:1140: checking for working const" >&5 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; } ; return 0; } EOF if { (eval echo configure:1194: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_const=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_c_const=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_c_const" 1>&6 if test $ac_cv_c_const = no; then cat >> confdefs.h <<\EOF #define const EOF fi echo $ac_n "checking for size_t""... $ac_c" 1>&6 echo "configure:1215: checking for size_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS #include #include #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_size_t=yes else rm -rf conftest* ac_cv_type_size_t=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_size_t" 1>&6 if test $ac_cv_type_size_t = no; then cat >> confdefs.h <<\EOF #define size_t unsigned EOF fi for ac_hdr in stropts.h sys/filio.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo "configure:1252: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1262: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 fi done for ac_hdr in stdint.h inttypes.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo "configure:1292: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1302: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 fi done ############################################################################### # Check for standard size types. The defaults are only valid on some # systems so we hope that exists when they're wrong. echo $ac_n "checking for int8_t""... $ac_c" 1>&6 echo "configure:1333: checking for int8_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_int8_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS #include #include #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "(^|[^a-zA-Z_0-9])int8_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_int8_t=yes else rm -rf conftest* ac_cv_type_int8_t=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_int8_t" 1>&6 if test $ac_cv_type_int8_t = no; then cat >> confdefs.h <<\EOF #define int8_t signed char EOF fi echo $ac_n "checking for int16_t""... $ac_c" 1>&6 echo "configure:1366: checking for int16_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_int16_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS #include #include #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "(^|[^a-zA-Z_0-9])int16_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_int16_t=yes else rm -rf conftest* ac_cv_type_int16_t=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_int16_t" 1>&6 if test $ac_cv_type_int16_t = no; then cat >> confdefs.h <<\EOF #define int16_t short EOF fi echo $ac_n "checking for int32_t""... $ac_c" 1>&6 echo "configure:1399: checking for int32_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_int32_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS #include #include #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "(^|[^a-zA-Z_0-9])int32_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_int32_t=yes else rm -rf conftest* ac_cv_type_int32_t=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_int32_t" 1>&6 if test $ac_cv_type_int32_t = no; then cat >> confdefs.h <<\EOF #define int32_t long EOF fi echo $ac_n "checking for int64_t""... $ac_c" 1>&6 echo "configure:1432: checking for int64_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_int64_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS #include #include #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "(^|[^a-zA-Z_0-9])int64_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_int64_t=yes else rm -rf conftest* ac_cv_type_int64_t=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_int64_t" 1>&6 if test $ac_cv_type_int64_t = no; then cat >> confdefs.h <<\EOF #define int64_t long long EOF fi # Some systems have these in , just to be difficult... echo $ac_n "checking for uint8_t in ""... $ac_c" 1>&6 echo "configure:1467: checking for uint8_t in " >&5 if eval "test \"`echo '$''{'ucl_cv_uint8_t_in_stdint_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "uint8_t" >/dev/null 2>&1; then rm -rf conftest* ucl_cv_uint8_t_in_stdint_h=yes else rm -rf conftest* ucl_cv_uint8_t_in_stdint_h=no fi rm -f conftest* fi echo "$ac_t""$ucl_cv_uint8_t_in_stdint_h" 1>&6 if test $ucl_cv_uint8_t_in_stdint_h = "no" then echo $ac_n "checking for uint8_t""... $ac_c" 1>&6 echo "configure:1492: checking for uint8_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_uint8_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS #include #include #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "(^|[^a-zA-Z_0-9])uint8_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_uint8_t=yes else rm -rf conftest* ac_cv_type_uint8_t=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_uint8_t" 1>&6 if test $ac_cv_type_uint8_t = no; then cat >> confdefs.h <<\EOF #define uint8_t unsigned char EOF fi fi echo $ac_n "checking for uint16_t in ""... $ac_c" 1>&6 echo "configure:1527: checking for uint16_t in " >&5 if eval "test \"`echo '$''{'ucl_cv_uint16_t_in_stdint_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "uint16_t" >/dev/null 2>&1; then rm -rf conftest* ucl_cv_uint16_t_in_stdint_h=yes else rm -rf conftest* ucl_cv_uint16_t_in_stdint_h=no fi rm -f conftest* fi echo "$ac_t""$ucl_cv_uint16_t_in_stdint_h" 1>&6 if test $ucl_cv_uint16_t_in_stdint_h = "no" then echo $ac_n "checking for uint16_t""... $ac_c" 1>&6 echo "configure:1552: checking for uint16_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_uint16_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS #include #include #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "(^|[^a-zA-Z_0-9])uint16_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_uint16_t=yes else rm -rf conftest* ac_cv_type_uint16_t=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_uint16_t" 1>&6 if test $ac_cv_type_uint16_t = no; then cat >> confdefs.h <<\EOF #define uint16_t unsigned short EOF fi fi echo $ac_n "checking for uint32_t in ""... $ac_c" 1>&6 echo "configure:1587: checking for uint32_t in " >&5 if eval "test \"`echo '$''{'ucl_cv_uint32_t_in_stdint_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "uint32_t" >/dev/null 2>&1; then rm -rf conftest* ucl_cv_uint32_t_in_stdint_h=yes else rm -rf conftest* ucl_cv_uint32_t_in_stdint_h=no fi rm -f conftest* fi echo "$ac_t""$ucl_cv_uint32_t_in_stdint_h" 1>&6 if test $ucl_cv_uint32_t_in_stdint_h = "no" then echo $ac_n "checking for uint32_t""... $ac_c" 1>&6 echo "configure:1612: checking for uint32_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_uint32_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS #include #include #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "(^|[^a-zA-Z_0-9])uint32_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_uint32_t=yes else rm -rf conftest* ac_cv_type_uint32_t=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_uint32_t" 1>&6 if test $ac_cv_type_uint32_t = no; then cat >> confdefs.h <<\EOF #define uint32_t unsigned int EOF fi fi ############################################################################### # The following two macros cause autoconf to complain. echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6 echo "configure:1649: checking whether byte ordering is bigendian" >&5 if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_cv_c_bigendian=unknown # See if sys/param.h defines the BYTE_ORDER macro. cat > conftest.$ac_ext < #include int main() { #if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN bogus endian macros #endif ; return 0; } EOF if { (eval echo configure:1667: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* # It does; now see whether it defined to BIG_ENDIAN or not. cat > conftest.$ac_ext < #include int main() { #if BYTE_ORDER != BIG_ENDIAN not big endian #endif ; return 0; } EOF if { (eval echo configure:1682: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_bigendian=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_c_bigendian=no fi rm -f conftest* else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -f conftest* if test $ac_cv_c_bigendian = unknown; then if test "$cross_compiling" = yes; then { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_c_bigendian=no else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_c_bigendian=yes fi rm -fr conftest* fi fi fi echo "$ac_t""$ac_cv_c_bigendian" 1>&6 if test $ac_cv_c_bigendian = yes; then cat >> confdefs.h <<\EOF #define WORDS_BIGENDIAN 1 EOF fi echo $ac_n "checking whether char is unsigned""... $ac_c" 1>&6 echo "configure:1739: checking whether char is unsigned" >&5 if eval "test \"`echo '$''{'ac_cv_c_char_unsigned'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$GCC" = yes; then # GCC predefines this symbol on systems where it applies. cat > conftest.$ac_ext <&5 | egrep "yes" >/dev/null 2>&1; then rm -rf conftest* ac_cv_c_char_unsigned=yes else rm -rf conftest* ac_cv_c_char_unsigned=no fi rm -f conftest* else if test "$cross_compiling" = yes; then { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_c_char_unsigned=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_c_char_unsigned=no fi rm -fr conftest* fi fi fi echo "$ac_t""$ac_cv_c_char_unsigned" 1>&6 if test $ac_cv_c_char_unsigned = yes && test "$GCC" != yes; then cat >> confdefs.h <<\EOF #define __CHAR_UNSIGNED__ 1 EOF fi # # Some of the codecs in rat don't with with unsigned characters. # Force the compiler to use signed chars, to be consistent. if test $ac_cv_c_char_unsigned = yes then if test "$GCC" = yes then CFLAGS="$CFLAGS -fsigned-char" else case "$host_os" in # I don't know when "-signed" was added to IRIX CC # so err on the side of using it. irix*) CFLAGS="$CFLAGS -signed" ;; # need e.g. --force-signed-chars=-signed *) { echo "configure: error: I don't know how to force signed chars" 1>&2; exit 1; } ;; esac fi fi # __CHAR_UNSIGNED__ will be defined; hope this is OK. ############################################################################### # The following causes autoconf to complain. ac_safe=`echo "/dev/urandom" | sed 'y%./+-%__p_%'` echo $ac_n "checking for /dev/urandom""... $ac_c" 1>&6 echo "configure:1828: checking for /dev/urandom" >&5 if eval "test \"`echo '$''{'ac_cv_file_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then { echo "configure: error: Cannot check for file existence when cross compiling" 1>&2; exit 1; } else if test -r /dev/urandom; then eval "ac_cv_file_$ac_safe=yes" else eval "ac_cv_file_$ac_safe=no" fi fi fi if eval "test \"`echo '$ac_cv_file_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_DEV_URANDOM 1 EOF else echo "$ac_t""no" 1>&6 fi # If more files than mbus.c use vsnprintf, split it out into # vsnprintf.c and add it to AC_REPLACE_FUNCS # AC_CHECK_FUNC(vsnprintf,,AC_DEFINE(NEED_VSNPRINTF)) for ac_func in vsnprintf do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:1860: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:1888: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <&6 LIBOBJS="$LIBOBJS ${ac_func}.${ac_objext}" fi done ############################################################################### # If inet_aton is actually needed somewhere, split it out into # inet_aton.c and add it to AC_REPLACE_FUNCS # # AC_CHECK_FUNC succeeds on our IRIX 6.2 boxes, but it is not # declared anywhere, use egrep header to check (ugh lame, but works) echo $ac_n "checking for inet_pton in ""... $ac_c" 1>&6 echo "configure:1923: checking for inet_pton in " >&5 if eval "test \"`echo '$''{'ucl_cv_inet_pton_in_inet_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "uint16_t" >/dev/null 2>&1; then rm -rf conftest* ucl_cv_inet_pton_in_inet_h=yes else rm -rf conftest* ucl_cv_inet_pton_in_inet_h=no fi rm -f conftest* fi echo "$ac_t""$ucl_cv_inet_pton_in_inet_h" 1>&6 if test $ucl_cv_inet_pton_in_inet_h = "no" then cat >> confdefs.h <<\EOF #define NEED_INET_PTON 1 EOF LIBOBJS="$LIBOBJS inet_pton.o" fi echo $ac_n "checking for inet_ntop in ""... $ac_c" 1>&6 echo "configure:1954: checking for inet_ntop in " >&5 if eval "test \"`echo '$''{'ucl_cv_inet_ntop_in_inet_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "uint16_t" >/dev/null 2>&1; then rm -rf conftest* ucl_cv_inet_ntop_in_inet_h=yes else rm -rf conftest* ucl_cv_inet_ntop_in_inet_h=no fi rm -f conftest* fi echo "$ac_t""$ucl_cv_inet_ntop_in_inet_h" 1>&6 if test $ucl_cv_inet_ntop_in_inet_h = "no" then cat >> confdefs.h <<\EOF #define NEED_INET_NTOP 1 EOF LIBOBJS="$LIBOBJS inet_ntop.o" else cat >> confdefs.h <<\EOF #define HAVE_INET_NTOP 1 EOF fi echo $ac_n "checking for library containing socket""... $ac_c" 1>&6 echo "configure:1994: checking for library containing socket" >&5 if eval "test \"`echo '$''{'ac_cv_search_socket'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_func_search_save_LIBS="$LIBS" ac_cv_search_socket="no" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_search_socket="none required" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -f conftest* test "$ac_cv_search_socket" = "no" && for i in socket; do LIBS="-l$i $ac_func_search_save_LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_search_socket="-l$i" break else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -f conftest* done LIBS="$ac_func_search_save_LIBS" fi echo "$ac_t""$ac_cv_search_socket" 1>&6 if test "$ac_cv_search_socket" != "no"; then test "$ac_cv_search_socket" = "none required" || LIBS="$ac_cv_search_socket $LIBS" else : fi echo $ac_n "checking for library containing inet_addr""... $ac_c" 1>&6 echo "configure:2056: checking for library containing inet_addr" >&5 if eval "test \"`echo '$''{'ac_cv_search_inet_addr'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_func_search_save_LIBS="$LIBS" ac_cv_search_inet_addr="no" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_search_inet_addr="none required" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -f conftest* test "$ac_cv_search_inet_addr" = "no" && for i in nsl; do LIBS="-l$i $ac_func_search_save_LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_search_inet_addr="-l$i" break else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -f conftest* done LIBS="$ac_func_search_save_LIBS" fi echo "$ac_t""$ac_cv_search_inet_addr" 1>&6 if test "$ac_cv_search_inet_addr" != "no"; then test "$ac_cv_search_inet_addr" = "none required" || LIBS="$ac_cv_search_inet_addr $LIBS" else : fi ############################################################################### # -profile # Check whether --enable-profile or --disable-profile was given. if test "${enable_profile+set}" = set; then enableval="$enable_profile" if test $enableval = yes then if test "$GCC" = yes then CFLAGS="$CFLAGS -pg" else { echo "configure: error: Don't know how to enable profiling for $CC" 1>&2; exit 1; } fi fi fi # -bounds # add -fbounds-checking to CFLAGS # add -lcheck to LIBS # Check whether --enable-bounds or --disable-bounds was given. if test "${enable_bounds+set}" = set; then enableval="$enable_bounds" if test $enableval = yes then if test "$GCC" = yes then CFLAGS="$CFLAGS -fbounds-checking" LIBS="$LIBS -lcheck" else { echo "configure: error: Don't know how to enable profiling for $CC" 1>&2; exit 1; } fi fi fi # -DDEBUG # -DDEBUG_MEM # -DNDEBUG # Check whether --enable-debug or --disable-debug was given. if test "${enable_debug+set}" = set; then enableval="$enable_debug" if test $enableval = yes then cat >> confdefs.h <<\EOF #define DEBUG 1 EOF fi fi # Check whether --enable-debug-mem or --disable-debug-mem was given. if test "${enable_debug_mem+set}" = set; then enableval="$enable_debug_mem" if test $enableval = yes then cat >> confdefs.h <<\EOF #define DEBUG_MEM 1 EOF fi fi ############################################################################### # IPv6 related configuration options (using tcpdump's configure.in) echo $ac_n "checking whether to enable IPv6""... $ac_c" 1>&6 echo "configure:2184: checking whether to enable IPv6" >&5 # Check whether --enable-ipv6 or --disable-ipv6 was given. if test "${enable_ipv6+set}" = set; then enableval="$enable_ipv6" case "$enableval" in yes) echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_IPv6 1 EOF ipv6=yes ;; *) echo "$ac_t""no" 1>&6 ipv6=no ;; esac else echo "$ac_t""no" 1>&6 ipv6=no fi ipv6type=unknown ipv6lib=none ipv6trylibc=no # IPv6 Stack Type Detector if test "$ipv6" = "yes"; then echo $ac_n "checking ipv6 stack type""... $ac_c" 1>&6 echo "configure:2214: checking ipv6 stack type" >&5 for i in inria kame linux-glibc linux-libinet6 toshiba v6d zeta; do case $i in inria) cat > conftest.$ac_ext < #ifdef IPV6_INRIA_VERSION yes #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "yes" >/dev/null 2>&1; then rm -rf conftest* ipv6type=$i; CFLAGS="-DINET6 $CFLAGS" fi rm -f conftest* ;; kame) cat > conftest.$ac_ext < #ifdef __KAME__ yes #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "yes" >/dev/null 2>&1; then rm -rf conftest* ipv6type=$i; ipv6lib=inet6; if test -x /usr/local/v6/lib; then ipv6libdir=/usr/local/v6/lib; else ipv6type=freebsd/netbsd/openbsd ipv6libdir=/usr/lib; fi; ipv6trylibc=yes; CFLAGS="-DINET6 $CFLAGS" fi rm -f conftest* ;; linux-glibc) cat > conftest.$ac_ext < #if defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1 yes #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "yes" >/dev/null 2>&1; then rm -rf conftest* ipv6type=$i; CFLAGS="-DINET6 $CFLAGS" fi rm -f conftest* ;; linux-libinet6) if test -d /usr/inet6 -o -f /usr/include/netinet/ip6.h; then ipv6type=$i ipv6lib=inet6 ipv6libdir=/usr/inet6/lib ipv6trylibc=yes; CFLAGS="-DINET6 -I/usr/inet6/include $CFLAGS" fi ;; toshiba) cat > conftest.$ac_ext < #ifdef _TOSHIBA_INET6 yes #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "yes" >/dev/null 2>&1; then rm -rf conftest* ipv6type=$i; ipv6lib=inet6; ipv6libdir=/usr/local/v6/lib; CFLAGS="-DINET6 $CFLAGS" fi rm -f conftest* ;; v6d) cat > conftest.$ac_ext < #ifdef __V6D__ yes #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "yes" >/dev/null 2>&1; then rm -rf conftest* ipv6type=$i; ipv6lib=v6; ipv6libdir=/usr/local/v6/lib; CFLAGS="-I/usr/local/v6/include $CFLAGS" fi rm -f conftest* ;; zeta) cat > conftest.$ac_ext < #ifdef _ZETA_MINAMI_INET6 yes #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "yes" >/dev/null 2>&1; then rm -rf conftest* ipv6type=$i; ipv6lib=inet6; ipv6libdir=/usr/local/v6/lib; CFLAGS="-DINET6 $CFLAGS" fi rm -f conftest* ;; esac if test "$ipv6type" != "unknown"; then break fi done echo "$ac_t""$ipv6type" 1>&6 fi if test "$ipv6" = "yes" -a "$ipv6lib" != "none"; then if test -d $ipv6libdir -a -f $ipv6libdir/lib$ipv6lib.a; then LIBS="-L$ipv6libdir -l$ipv6lib $LIBS" echo "You have $ipv6lib library, using it" else if test "$ipv6trylibc" = "yes"; then echo "You do not have $ipv6lib library, using libc" else echo 'Fatal: no $ipv6lib library found. cannot continue.' echo "You need to fetch lib$ipv6lib.a from appropriate" echo 'ipv6 kit and compile beforehand.' exit 1 fi fi fi # Test below are IPv6 specific. Their result has no bearing if HAVE_IPv6 is # not defined. They are kept outside IPv6 enable check to keep code readable. echo $ac_n "checking for getipnodebyname in ""... $ac_c" 1>&6 echo "configure:2382: checking for getipnodebyname in " >&5 if eval "test \"`echo '$''{'ucl_cv_getipnodebyname_in_netdb_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "getipnodebyname" >/dev/null 2>&1; then rm -rf conftest* ucl_cv_getipnodebyname_in_netdb_h=yes else rm -rf conftest* ucl_cv_getipnodebyname_in_netdb_h=no fi rm -f conftest* fi echo "$ac_t""$ucl_cv_getipnodebyname_in_netdb_h" 1>&6 if test $ucl_cv_getipnodebyname_in_netdb_h then cat >> confdefs.h <<\EOF #define HAVE_GETIPNODEBYNAME 1 EOF fi echo $ac_n "checking for struct addrinfo in ""... $ac_c" 1>&6 echo "configure:2413: checking for struct addrinfo in " >&5 if eval "test \"`echo '$''{'ucl_cv_st_addrinfo_in_netdb_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "addrinfo" >/dev/null 2>&1; then rm -rf conftest* ucl_cv_st_addrinfo_in_netdb_h=yes else rm -rf conftest* ucl_cv_st_addrinfo_in_netdb_h=no fi rm -f conftest* fi echo "$ac_t""$ucl_cv_st_addrinfo_in_netdb_h" 1>&6 if test $ucl_cv_st_addrinfo_in_netdb_h then cat >> confdefs.h <<\EOF #define HAVE_ST_ADDRINFO 1 EOF fi echo $ac_n "checking for sin6_len in struct sockaddr_in6""... $ac_c" 1>&6 echo "configure:2444: checking for sin6_len in struct sockaddr_in6" >&5 if eval "test \"`echo '$''{'ucl_cv_sin6_len'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { struct sockaddr_in6 s_in; s_in.sin6_len = 0; ; return 0; } EOF if { (eval echo configure:2461: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ucl_cv_sin6_len=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ucl_cv_sin6_len=no fi rm -f conftest* fi echo "$ac_t""$ucl_cv_sin6_len" 1>&6 if test $ucl_cv_sin6_len = yes then cat >> confdefs.h <<\EOF #define HAVE_SIN6_LEN 1 EOF fi echo $ac_n "checking for msg_control in struct msghdr""... $ac_c" 1>&6 echo "configure:2484: checking for msg_control in struct msghdr" >&5 if eval "test \"`echo '$''{'ucl_cv_control'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include int main() { struct msghdr msg; msg.msg_control = 0; ; return 0; } EOF if { (eval echo configure:2502: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ucl_cv_control=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ucl_cv_control=no fi rm -f conftest* fi echo "$ac_t""$ucl_cv_control" 1>&6 if test $ucl_cv_control = yes then cat >> confdefs.h <<\EOF #define HAVE_MSGHDR_MSGCTRL 1 EOF fi ############################################################################### # Check whether gtk-doc is installed # Extract the first word of "gtkdoc-scan", so it can be a program name with args. set dummy gtkdoc-scan; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:2530: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_GTKDOC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$GTKDOC"; then ac_cv_prog_GTKDOC="$GTKDOC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_GTKDOC="yes" break fi done IFS="$ac_save_ifs" test -z "$ac_cv_prog_GTKDOC" && ac_cv_prog_GTKDOC="no" fi fi GTKDOC="$ac_cv_prog_GTKDOC" if test -n "$GTKDOC"; then echo "$ac_t""$GTKDOC" 1>&6 else echo "$ac_t""no" 1>&6 fi if test "$GTKDOC" = yes then OPTDOC=doc else OPTDOC= fi ############################################################################### # GCC-specific warning flags if test "$GCC" = yes then CFLAGS="$CFLAGS -W -Wall -Wwrite-strings -Wbad-function-cast -Wmissing-prototypes -Wcast-qual -Wmissing-declarations -Werror" fi ############################################################################### # Done, create the output files.... trap '' 1 2 15 cat > confcache <<\EOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs. It is not useful on other systems. # If it contains results you don't want to keep, you may remove or edit it. # # By default, configure uses ./config.cache as the cache file, # creating it if it does not exist already. You can give configure # the --cache-file=FILE option to use a different cache file; that is # what configure does when it calls configure scripts in # subdirectories, so they share the cache. # Giving --cache-file=/dev/null disables caching, for debugging configure. # config.status only pays attention to the cache file if you give it the # --recheck option to rerun configure. # EOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, don't put newlines in cache variables' values. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. (set) 2>&1 | case `(ac_space=' '; set | grep ac_space) 2>&1` in *ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote substitution # turns \\\\ into \\, and sed turns \\ into \). sed -n \ -e "s/'/'\\\\''/g" \ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" ;; *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' ;; esac >> confcache if cmp -s $cache_file confcache; then : else if test -w $cache_file; then echo "updating cache $cache_file" cat confcache > $cache_file else echo "not updating unwritable cache $cache_file" fi fi rm -f confcache trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Any assignment to VPATH causes Sun make to only execute # the first set of double-colon rules, so remove it if not needed. # If there is a colon in the path, we need to keep it. if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' fi trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 DEFS=-DHAVE_CONFIG_H # Without the "./", some shells look in PATH for config.status. : ${CONFIG_STATUS=./config.status} echo creating $CONFIG_STATUS rm -f $CONFIG_STATUS cat > $CONFIG_STATUS </dev/null | sed 1q`: # # $0 $ac_configure_args # # Compiler output produced by configure, useful for debugging # configure, is in ./config.log if it exists. ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" for ac_option do case "\$ac_option" in -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; -version | --version | --versio | --versi | --vers | --ver | --ve | --v) echo "$CONFIG_STATUS generated by autoconf version 2.13" exit 0 ;; -help | --help | --hel | --he | --h) echo "\$ac_cs_usage"; exit 0 ;; *) echo "\$ac_cs_usage"; exit 1 ;; esac done ac_given_srcdir=$srcdir trap 'rm -fr `echo "Makefile doc/Makefile examples/Makefile examples/rtp/Makefile src/Makefile tests/Makefile src/uclconf.h:src/config.h.in" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 EOF cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF $ac_vpsub $extrasub s%@SHELL@%$SHELL%g s%@CFLAGS@%$CFLAGS%g s%@CPPFLAGS@%$CPPFLAGS%g s%@CXXFLAGS@%$CXXFLAGS%g s%@FFLAGS@%$FFLAGS%g s%@DEFS@%$DEFS%g s%@LDFLAGS@%$LDFLAGS%g s%@LIBS@%$LIBS%g s%@exec_prefix@%$exec_prefix%g s%@prefix@%$prefix%g s%@program_transform_name@%$program_transform_name%g s%@bindir@%$bindir%g s%@sbindir@%$sbindir%g s%@libexecdir@%$libexecdir%g s%@datadir@%$datadir%g s%@sysconfdir@%$sysconfdir%g s%@sharedstatedir@%$sharedstatedir%g s%@localstatedir@%$localstatedir%g s%@libdir@%$libdir%g s%@includedir@%$includedir%g s%@oldincludedir@%$oldincludedir%g s%@infodir@%$infodir%g s%@mandir@%$mandir%g s%@host@%$host%g s%@host_alias@%$host_alias%g s%@host_cpu@%$host_cpu%g s%@host_vendor@%$host_vendor%g s%@host_os@%$host_os%g s%@CC@%$CC%g s%@CPP@%$CPP%g s%@RANLIB@%$RANLIB%g s%@LIBOBJS@%$LIBOBJS%g s%@GTKDOC@%$GTKDOC%g s%@OPTDOC@%$OPTDOC%g CEOF EOF cat >> $CONFIG_STATUS <<\EOF # Split the substitutions into bite-sized pieces for seds with # small command number limits, like on Digital OSF/1 and HP-UX. ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. ac_file=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_cmds # Line after last line for current file. ac_more_lines=: ac_sed_cmds="" while $ac_more_lines; do if test $ac_beg -gt 1; then sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file else sed "${ac_end}q" conftest.subs > conftest.s$ac_file fi if test ! -s conftest.s$ac_file; then ac_more_lines=false rm -f conftest.s$ac_file else if test -z "$ac_sed_cmds"; then ac_sed_cmds="sed -f conftest.s$ac_file" else ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" fi ac_file=`expr $ac_file + 1` ac_beg=$ac_end ac_end=`expr $ac_end + $ac_max_sed_cmds` fi done if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then # The file is in a subdirectory. test ! -d "$ac_dir" && mkdir "$ac_dir" ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" # A "../" for each directory in $ac_dir_suffix. ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` else ac_dir_suffix= ac_dots= fi case "$ac_given_srcdir" in .) srcdir=. if test -z "$ac_dots"; then top_srcdir=. else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; *) # Relative path. srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" top_srcdir="$ac_dots$ac_given_srcdir" ;; esac echo creating "$ac_file" rm -f "$ac_file" configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." case "$ac_file" in *Makefile*) ac_comsub="1i\\ # $configure_input" ;; *) ac_comsub= ;; esac ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` sed -e "$ac_comsub s%@configure_input@%$configure_input%g s%@srcdir@%$srcdir%g s%@top_srcdir@%$top_srcdir%g " $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file fi; done rm -f conftest.s* # These sed commands are passed to sed as "A NAME B NAME C VALUE D", where # NAME is the cpp macro being defined and VALUE is the value it is being given. # # ac_d sets the value in "#define NAME VALUE" lines. ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' ac_dC='\3' ac_dD='%g' # ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_uB='\([ ]\)%\1#\2define\3' ac_uC=' ' ac_uD='\4%g' # ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_eB='$%\1#\2define\3' ac_eC=' ' ac_eD='%g' if test "${CONFIG_HEADERS+set}" != set; then EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF fi for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac echo creating $ac_file rm -f conftest.frag conftest.in conftest.out ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` cat $ac_file_inputs > conftest.in EOF # Transform confdefs.h into a sed script conftest.vals that substitutes # the proper values into config.h.in to produce config.h. And first: # Protect against being on the right side of a sed subst in config.status. # Protect against being in an unquoted here document in config.status. rm -f conftest.vals cat > conftest.hdr <<\EOF s/[\\&%]/\\&/g s%[\\$`]%\\&%g s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp s%ac_d%ac_u%gp s%ac_u%ac_e%gp EOF sed -n -f conftest.hdr confdefs.h > conftest.vals rm -f conftest.hdr # This sed command replaces #undef with comments. This is necessary, for # example, in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. cat >> conftest.vals <<\EOF s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% EOF # Break up conftest.vals because some shells have a limit on # the size of here documents, and old seds have small limits too. rm -f conftest.tail while : do ac_lines=`grep -c . conftest.vals` # grep -c gives empty output for an empty file on some AIX systems. if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi # Write a limited-size here document to conftest.frag. echo ' cat > conftest.frag <> $CONFIG_STATUS sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS echo 'CEOF sed -f conftest.frag conftest.in > conftest.out rm -f conftest.in mv conftest.out conftest.in ' >> $CONFIG_STATUS sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail rm -f conftest.vals mv conftest.tail conftest.vals done rm -f conftest.vals cat >> $CONFIG_STATUS <<\EOF rm -f conftest.frag conftest.h echo "/* $ac_file. Generated automatically by configure. */" > conftest.h cat conftest.in >> conftest.h rm -f conftest.in if cmp -s $ac_file conftest.h 2>/dev/null; then echo "$ac_file is unchanged" rm -f conftest.h else # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then # The file is in a subdirectory. test ! -d "$ac_dir" && mkdir "$ac_dir" fi rm -f $ac_file mv conftest.h $ac_file fi fi; done EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF exit 0 EOF chmod +x $CONFIG_STATUS rm -fr confdefs* $ac_clean_files test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 uclmmbase-1.2.16.0/configure.in0000644000175000017500000002332707642541560015214 0ustar enderenderdnl Process this file with autoconf to produce a configure script. AC_INIT(src/base64.c) AC_CANONICAL_HOST AC_PROG_CC AC_PROG_CPP AC_PROG_RANLIB AC_HEADER_STDC AC_HEADER_SYS_WAIT AC_CHECK_HEADERS(sys/time.h) if test "$ac_cv_header_sys_time_h" = "yes"; then AC_HEADER_TIME fi AC_C_CONST AC_TYPE_SIZE_T AC_CHECK_HEADERS(stropts.h sys/filio.h) AC_CHECK_HEADERS(stdint.h inttypes.h) ############################################################################### # Check for standard size types. The defaults are only valid on some # systems so we hope that exists when they're wrong. AC_CHECK_TYPE(int8_t, signed char) AC_CHECK_TYPE(int16_t, short) AC_CHECK_TYPE(int32_t, long) AC_CHECK_TYPE(int64_t, long long) # Some systems have these in , just to be difficult... AC_CACHE_CHECK(for uint8_t in , ucl_cv_uint8_t_in_stdint_h, AC_EGREP_HEADER(uint8_t, stdint.h, ucl_cv_uint8_t_in_stdint_h=yes, ucl_cv_uint8_t_in_stdint_h=no)) if test $ucl_cv_uint8_t_in_stdint_h = "no" then AC_CHECK_TYPE(uint8_t, unsigned char) fi AC_CACHE_CHECK(for uint16_t in , ucl_cv_uint16_t_in_stdint_h, AC_EGREP_HEADER(uint16_t, stdint.h, ucl_cv_uint16_t_in_stdint_h=yes, ucl_cv_uint16_t_in_stdint_h=no)) if test $ucl_cv_uint16_t_in_stdint_h = "no" then AC_CHECK_TYPE(uint16_t, unsigned short) fi AC_CACHE_CHECK(for uint32_t in , ucl_cv_uint32_t_in_stdint_h, AC_EGREP_HEADER(uint32_t, stdint.h, ucl_cv_uint32_t_in_stdint_h=yes, ucl_cv_uint32_t_in_stdint_h=no)) if test $ucl_cv_uint32_t_in_stdint_h = "no" then AC_CHECK_TYPE(uint32_t, unsigned int) fi ############################################################################### # The following two macros cause autoconf to complain. AC_C_BIGENDIAN AC_C_CHAR_UNSIGNED # # Some of the codecs in rat don't with with unsigned characters. # Force the compiler to use signed chars, to be consistent. if test $ac_cv_c_char_unsigned = yes then if test "$GCC" = yes then CFLAGS="$CFLAGS -fsigned-char" else case "$host_os" in # I don't know when "-signed" was added to IRIX CC # so err on the side of using it. irix*) CFLAGS="$CFLAGS -signed" ;; # need e.g. --force-signed-chars=-signed *) AC_MSG_ERROR([I don't know how to force signed chars]) ;; esac fi fi # __CHAR_UNSIGNED__ will be defined; hope this is OK. ############################################################################### # The following causes autoconf to complain. AC_CHECK_FILE(/dev/urandom,AC_DEFINE(HAVE_DEV_URANDOM)) # If more files than mbus.c use vsnprintf, split it out into # vsnprintf.c and add it to AC_REPLACE_FUNCS # AC_CHECK_FUNC(vsnprintf,,AC_DEFINE(NEED_VSNPRINTF)) AC_REPLACE_FUNCS(vsnprintf) ############################################################################### # If inet_aton is actually needed somewhere, split it out into # inet_aton.c and add it to AC_REPLACE_FUNCS # # AC_CHECK_FUNC succeeds on our IRIX 6.2 boxes, but it is not # declared anywhere, use egrep header to check (ugh lame, but works) AC_CACHE_CHECK(for inet_pton in , ucl_cv_inet_pton_in_inet_h, AC_EGREP_HEADER(uint16_t, stdint.h, ucl_cv_inet_pton_in_inet_h=yes, ucl_cv_inet_pton_in_inet_h=no)) if test $ucl_cv_inet_pton_in_inet_h = "no" then AC_DEFINE(NEED_INET_PTON) LIBOBJS="$LIBOBJS inet_pton.o" fi AC_CACHE_CHECK(for inet_ntop in , ucl_cv_inet_ntop_in_inet_h, AC_EGREP_HEADER(uint16_t, stdint.h, ucl_cv_inet_ntop_in_inet_h=yes, ucl_cv_inet_ntop_in_inet_h=no)) if test $ucl_cv_inet_ntop_in_inet_h = "no" then AC_DEFINE(NEED_INET_NTOP) LIBOBJS="$LIBOBJS inet_ntop.o" else AC_DEFINE(HAVE_INET_NTOP) fi AC_SUBST(LIBOBJS) dnl AC_REPLACE_FUNCS(inet_pton inet_ntop) AC_SEARCH_LIBS(socket, socket) AC_SEARCH_LIBS(inet_addr, nsl) ############################################################################### # -profile AC_ARG_ENABLE(profile, [ --enable-profile enable profiling], [if test $enableval = yes then if test "$GCC" = yes then CFLAGS="$CFLAGS -pg" else AC_ERROR([Don't know how to enable profiling for $CC]) fi fi]) # -bounds # add -fbounds-checking to CFLAGS # add -lcheck to LIBS AC_ARG_ENABLE(bounds, [ --enable-bounds enable bounds checking], [if test $enableval = yes then if test "$GCC" = yes then CFLAGS="$CFLAGS -fbounds-checking" LIBS="$LIBS -lcheck" else AC_ERROR([Don't know how to enable profiling for $CC]) fi fi]) # -DDEBUG # -DDEBUG_MEM # -DNDEBUG AC_ARG_ENABLE(debug, [ --enable-debug enable debug messages and code], [if test $enableval = yes then AC_DEFINE(DEBUG) fi]) AC_ARG_ENABLE(debug-mem, [ --enable-debug-mem enable memory debugging code], [if test $enableval = yes then AC_DEFINE(DEBUG_MEM) fi]) ############################################################################### # IPv6 related configuration options (using tcpdump's configure.in) AC_MSG_CHECKING([whether to enable IPv6]) AC_ARG_ENABLE(ipv6, [ --enable-ipv6 enable ipv6], [ case "$enableval" in yes) AC_MSG_RESULT(yes) AC_DEFINE(HAVE_IPv6) ipv6=yes ;; *) AC_MSG_RESULT(no) ipv6=no ;; esac ], [ AC_MSG_RESULT(no) ipv6=no ]) ipv6type=unknown ipv6lib=none ipv6trylibc=no # IPv6 Stack Type Detector if test "$ipv6" = "yes"; then AC_MSG_CHECKING([ipv6 stack type]) for i in inria kame linux-glibc linux-libinet6 toshiba v6d zeta; do case $i in inria) dnl http://www.kame.net/ AC_EGREP_CPP(yes, [dnl #include #ifdef IPV6_INRIA_VERSION yes #endif], [ipv6type=$i; CFLAGS="-DINET6 $CFLAGS"]) ;; kame) dnl http://www.kame.net/ AC_EGREP_CPP(yes, [dnl #include #ifdef __KAME__ yes #endif], [ipv6type=$i; ipv6lib=inet6; if test -x /usr/local/v6/lib; then ipv6libdir=/usr/local/v6/lib; else ipv6type=freebsd/netbsd/openbsd ipv6libdir=/usr/lib; fi; ipv6trylibc=yes; CFLAGS="-DINET6 $CFLAGS"]) ;; linux-glibc) dnl http://www.v6.linux.or.jp/ AC_EGREP_CPP(yes, [dnl #include #if defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1 yes #endif], [ipv6type=$i; CFLAGS="-DINET6 $CFLAGS"]) ;; linux-libinet6) dnl http://www.v6.linux.or.jp/ if test -d /usr/inet6 -o -f /usr/include/netinet/ip6.h; then ipv6type=$i ipv6lib=inet6 ipv6libdir=/usr/inet6/lib ipv6trylibc=yes; CFLAGS="-DINET6 -I/usr/inet6/include $CFLAGS" fi ;; toshiba) AC_EGREP_CPP(yes, [dnl #include #ifdef _TOSHIBA_INET6 yes #endif], [ipv6type=$i; ipv6lib=inet6; ipv6libdir=/usr/local/v6/lib; CFLAGS="-DINET6 $CFLAGS"]) ;; v6d) AC_EGREP_CPP(yes, [dnl #include #ifdef __V6D__ yes #endif], [ipv6type=$i; ipv6lib=v6; ipv6libdir=/usr/local/v6/lib; CFLAGS="-I/usr/local/v6/include $CFLAGS"]) ;; zeta) AC_EGREP_CPP(yes, [dnl #include #ifdef _ZETA_MINAMI_INET6 yes #endif], [ipv6type=$i; ipv6lib=inet6; ipv6libdir=/usr/local/v6/lib; CFLAGS="-DINET6 $CFLAGS"]) ;; esac if test "$ipv6type" != "unknown"; then break fi done AC_MSG_RESULT($ipv6type) fi if test "$ipv6" = "yes" -a "$ipv6lib" != "none"; then if test -d $ipv6libdir -a -f $ipv6libdir/lib$ipv6lib.a; then LIBS="-L$ipv6libdir -l$ipv6lib $LIBS" echo "You have $ipv6lib library, using it" else if test "$ipv6trylibc" = "yes"; then echo "You do not have $ipv6lib library, using libc" else echo 'Fatal: no $ipv6lib library found. cannot continue.' echo "You need to fetch lib$ipv6lib.a from appropriate" echo 'ipv6 kit and compile beforehand.' exit 1 fi fi fi # Test below are IPv6 specific. Their result has no bearing if HAVE_IPv6 is # not defined. They are kept outside IPv6 enable check to keep code readable. AC_CACHE_CHECK(for getipnodebyname in , ucl_cv_getipnodebyname_in_netdb_h, AC_EGREP_HEADER(getipnodebyname, netdb.h, ucl_cv_getipnodebyname_in_netdb_h=yes, ucl_cv_getipnodebyname_in_netdb_h=no)) if test $ucl_cv_getipnodebyname_in_netdb_h then AC_DEFINE(HAVE_GETIPNODEBYNAME) fi AC_CACHE_CHECK(for struct addrinfo in , ucl_cv_st_addrinfo_in_netdb_h, AC_EGREP_HEADER(addrinfo, netdb.h, ucl_cv_st_addrinfo_in_netdb_h=yes, ucl_cv_st_addrinfo_in_netdb_h=no)) if test $ucl_cv_st_addrinfo_in_netdb_h then AC_DEFINE(HAVE_ST_ADDRINFO) fi AC_CACHE_CHECK(for sin6_len in struct sockaddr_in6, ucl_cv_sin6_len, [AC_TRY_COMPILE([ #include ],[ struct sockaddr_in6 s_in; s_in.sin6_len = 0; ], ucl_cv_sin6_len=yes, ucl_cv_sin6_len=no )]) if test $ucl_cv_sin6_len = yes then AC_DEFINE(HAVE_SIN6_LEN) fi AC_CACHE_CHECK(for msg_control in struct msghdr, ucl_cv_control, [AC_TRY_COMPILE([ #include #include ],[ struct msghdr msg; msg.msg_control = 0; ], ucl_cv_control=yes, ucl_cv_control=no )]) if test $ucl_cv_control = yes then AC_DEFINE(HAVE_MSGHDR_MSGCTRL) fi ############################################################################### # Check whether gtk-doc is installed AC_CHECK_PROG(GTKDOC, gtkdoc-scan, yes, no, $PATH) if test "$GTKDOC" = yes then OPTDOC=doc else OPTDOC= fi AC_SUBST(OPTDOC) ############################################################################### # GCC-specific warning flags if test "$GCC" = yes then CFLAGS="$CFLAGS -W -Wall -Wwrite-strings -Wbad-function-cast -Wmissing-prototypes -Wcast-qual -Wmissing-declarations -Werror" fi ############################################################################### # Done, create the output files.... AC_CONFIG_HEADER(src/uclconf.h:src/config.h.in) AC_OUTPUT(Makefile doc/Makefile examples/Makefile examples/rtp/Makefile src/Makefile tests/Makefile) uclmmbase-1.2.16.0/install-sh0000644000175000017500000001272007015101145014660 0ustar enderender#!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5 (mit/util/scripts/install.sh). # # Copyright 1991 by the Massachusetts Institute of Technology # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that # the above copyright notice appear in all copies and that both that # copyright notice and this permission notice appear in supporting # documentation, and that the name of M.I.T. not be used in advertising or # publicity pertaining to distribution of the software without specific, # written prior permission. M.I.T. makes no representations about the # suitability of this software for any purpose. It is provided "as is" # without express or implied warranty. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 uclmmbase-1.2.16.0/examples/0000755000175000017500000000000010374736110014503 5ustar enderenderuclmmbase-1.2.16.0/examples/rtp/0000755000175000017500000000000010374736110015310 5ustar enderenderuclmmbase-1.2.16.0/examples/rtp/Makefile.in0000644000175000017500000000107707262621544017370 0ustar enderender# # Makefile for the RTP example. # This probably requires GNU make. # # Location of includes and library CSRC = ../../src # Library name LNAME = uclmmbase DEFS = @DEFS@ CFLAGS = @CFLAGS@ $(DEFS) -I$(CSRC) LIBS = @LIBS@ -L$(CSRC) -l$(LNAME) CC = @CC@ TARGET = rtpdemo OBJS = rtpdemo.o SRCS = $(OBJS:%.o=%.c) all: $(TARGET) rtpdemo: $(OBJS) $(CSRC)/lib$(LNAME).a $(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) .c.o: $(CC) $(CFLAGS) $(INC) -c $< $(CSRC)/lib$(LNAME).a: cd $(CSRC) && $(MAKE) clean: -rm -f $(OBJS) $(TARGET) distclean: clean -rm -f Makefileuclmmbase-1.2.16.0/examples/rtp/rtpdemo.c0000644000175000017500000001253707466775431017157 0ustar enderender/* * rtpdemo: A simple rtp application that sends and receives data. * * (C) 2000-2001 University College London. */ #include #include #include #include #include #include #include #include "uclconf.h" #include "config_unix.h" #include "config_win32.h" #include "debug.h" #include "memory.h" #include "rtp.h" static void usage() { printf("Usage: rtpdemo [switches] address port\n"); printf("Valid switches are:\n"); printf(" -f\t\tFilter local packets out of receive stream.\n"); printf(" -l\t\tListen and do not transmit data.\n"); exit(-1); } /* ------------------------------------------------------------------------- */ /* RTP callback related */ static void sdes_print(struct rtp *session, uint32_t ssrc, rtcp_sdes_type stype) { const char *sdes_type_names[] = { "end", "cname", "name", "email", "telephone", "location", "tool", "note", "priv" }; const uint8_t n = sizeof(sdes_type_names) / sizeof(sdes_type_names[0]); if (stype > n) { /* Theoretically impossible */ printf("boo! invalud sdes field %d\n", stype); return; } printf("SSRC 0x%08x reported SDES type %s - ", ssrc, sdes_type_names[stype]); if (stype == RTCP_SDES_PRIV) { /* Requires extra-handling, not important for example */ printf("don't know how to display.\n"); } else { printf("%s\n", rtp_get_sdes(session, ssrc, stype)); } } static void packet_print(struct rtp *session, rtp_packet *p) { printf("Received data (payload %d timestamp %06d size %d) ", p->pt, p->ts, p->data_len); if (p->ssrc == rtp_my_ssrc(session)) { /* Unless filtering is enabled we are likely to see out packets if sending to a multicast group. */ printf("that I just sent.\n"); } else { printf("from SSRC 0x%08x\n", p->ssrc); } } static void rtp_event_handler(struct rtp *session, rtp_event *e) { rtp_packet *p; rtcp_sdes_item *r; switch(e->type) { case RX_RTP: p = (rtp_packet*)e->data; packet_print(session, p); xfree(p); /* xfree() is mandatory to release RTP packet data */ break; case RX_SDES: r = (rtcp_sdes_item*)e->data; sdes_print(session, e->ssrc, r->type); break; case RX_BYE: break; case SOURCE_CREATED: printf("New source created, SSRC = 0x%08x\n", e->ssrc); break; case SOURCE_DELETED: printf("Source deleted, SSRC = 0x%08x\n", e->ssrc); break; case RX_SR: case RX_RR: case RX_RR_EMPTY: case RX_RTCP_START: case RX_RTCP_FINISH: case RR_TIMEOUT: case RX_APP: break; } fflush(stdout); } /* ------------------------------------------------------------------------- */ /* Send and receive loop. Sender use 20ms audio mulaw packets */ #define MULAW_BYTES 4 * 160 #define MULAW_PAYLOAD 0 #define MULAW_MS 4 * 20 #define MAX_ROUNDS 100 static void rxtx_loop(struct rtp* session, int send_enable) { struct timeval timeout; uint32_t rtp_ts, round; uint8_t mulaw_buffer[MULAW_BYTES]; if (send_enable) { printf("Sending and listening to "); } else { printf("Listening to "); } printf("%s port %d (local SSRC = 0x%08x)\n", rtp_get_addr(session), rtp_get_rx_port(session), rtp_my_ssrc(session)); round = 0; for(round = 0; round < MAX_ROUNDS; round++) { rtp_ts = round * MULAW_MS; /* Send control packets */ rtp_send_ctrl(session, rtp_ts, NULL); /* Send data packets */ if (send_enable) { rtp_send_data(session, rtp_ts, MULAW_PAYLOAD, 0, 0, 0, (char*)mulaw_buffer, MULAW_BYTES, 0, 0, 0); } /* Receive control and data packets */ timeout.tv_sec = 0; timeout.tv_usec = 0; rtp_recv(session, &timeout, rtp_ts); /* State maintenance */ rtp_update(session); usleep(MULAW_MS * 1000); xmemchk(); } } /* ------------------------------------------------------------------------- */ /* Main loop: parses command line and initializes RTP session */ int main(int argc, const char *argv[]) { const char *address = NULL; struct rtp *session = NULL; uint16_t port = 0; int32_t ac, filter_me = 0, send_enable = 1; ac = 1; while (ac < argc && argv[ac][0] == '-') { switch(tolower(argv[ac][1])) { case 'f': filter_me = 1; break; case 'l': send_enable = 0; break; } ac++; } if (argc - ac != 2) { usage(); } address = argv[ac]; port = atoi(argv[ac + 1]); session = rtp_init(address, /* Host/Group IP address */ port, /* receive port */ port, /* transmit port */ 16, /* time-to-live */ 64000, /* B/W estimate */ rtp_event_handler, /* RTP event callback */ NULL); /* App. specific data */ if (session) { const char *username = "Malcovich Malcovitch"; const char *telephone = "1-800-RTP-DEMO"; const char *toolname = "RTPdemo"; uint32_t my_ssrc = rtp_my_ssrc(session); /* Set local participant info */ rtp_set_sdes(session, my_ssrc, RTCP_SDES_NAME, username, strlen(username)); rtp_set_sdes(session, my_ssrc, RTCP_SDES_PHONE, telephone, strlen(telephone)); rtp_set_sdes(session, my_ssrc, RTCP_SDES_TOOL, toolname, strlen(toolname)); /* Filter out local packets if requested */ rtp_set_option(session, RTP_OPT_FILTER_MY_PACKETS, filter_me); /* Run main loop */ rxtx_loop(session, send_enable); /* Say bye-bye */ rtp_send_bye(session); rtp_done(session); } else { printf("Could not initialize session for %s port %d\n", address, port); } return 0; } uclmmbase-1.2.16.0/examples/sap/0000755000175000017500000000000010374735701015273 5ustar enderenderuclmmbase-1.2.16.0/examples/sap/Makefile0000644000175000017500000000136407665120470016737 0ustar enderender# Generated automatically from Makefile.in by configure. # # Makefile for the SAP example. # This probably requires GNU make. # # Location of includes and library CSRC = ../../src # Library name LNAME = uclmmbase DEFS = -DHAVE_CONFIG_H CFLAGS = -g -O2 -W -Wall -Wwrite-strings -Wbad-function-cast -Wmissing-prototypes -Wcast-qual -Wmissing-declarations -Werror $(DEFS) -I$(CSRC) LIBS = -lnsl -lsocket -L$(CSRC) -l$(LNAME) CC = gcc TARGET = sapdemo OBJS = sapdemo.o SRCS = $(OBJS:%.o=%.c) all: $(TARGET) sapdemo: $(OBJS) $(CSRC)/lib$(LNAME).a $(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) .c.o: $(CC) $(CFLAGS) $(INC) -c $< $(CSRC)/lib$(LNAME).a: cd $(CSRC) && $(MAKE) clean: -rm -f $(OBJS) $(TARGET) distclean: clean -rm -f Makefile uclmmbase-1.2.16.0/examples/sap/Makefile.in0000644000175000017500000000107707665113605017347 0ustar enderender# # Makefile for the SAP example. # This probably requires GNU make. # # Location of includes and library CSRC = ../../src # Library name LNAME = uclmmbase DEFS = @DEFS@ CFLAGS = @CFLAGS@ $(DEFS) -I$(CSRC) LIBS = @LIBS@ -L$(CSRC) -l$(LNAME) CC = @CC@ TARGET = sapdemo OBJS = sapdemo.o SRCS = $(OBJS:%.o=%.c) all: $(TARGET) sapdemo: $(OBJS) $(CSRC)/lib$(LNAME).a $(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) .c.o: $(CC) $(CFLAGS) $(INC) -c $< $(CSRC)/lib$(LNAME).a: cd $(CSRC) && $(MAKE) clean: -rm -f $(OBJS) $(TARGET) distclean: clean -rm -f Makefileuclmmbase-1.2.16.0/examples/sap/sapdemo.c0000644000175000017500000000114507665113605017072 0ustar enderender#include #include #include #include #include #include #include #include "uclconf.h" #include "config_unix.h" #include "config_win32.h" #include "debug.h" #include "memory.h" #include "sap.h" static void sap_handler(sap_packet *packet) { print_sap_packet(packet); } int main() { struct sap *session = NULL; struct timeval timeout; session = sap_init("224.2.127.254", 9875, 127, sap_handler); timeout.tv_sec = 0; timeout.tv_usec = 0; while(1) sap_recv(session, &timeout); sap_done(session); return 0; } uclmmbase-1.2.16.0/examples/Makefile.in0000644000175000017500000000073207276565507016573 0ustar enderender# # Makefile for the common code library project. # This probably requires GNU make. # SUBDIRS=rtp all: all-recursive all-recursive: for s in $(SUBDIRS) ; do (cd $$s && $(MAKE)) || exit 1; done clean: clean-recursive clean-recursive: for s in $(SUBDIRS) ; do (cd $$s && $(MAKE) clean); done distclean: distclean-recursive rm -f Makefile distclean-recursive: for s in $(SUBDIRS) ; do (cd $$s && $(MAKE) distclean) ; done .PHONY: clean clean-recursive distclean uclmmbase-1.2.16.0/examples/sdp/0000755000175000017500000000000010374735701015276 5ustar enderenderuclmmbase-1.2.16.0/examples/sdp/Makefile0000644000175000017500000000135707665120472016746 0ustar enderender# Generated automatically from Makefile.in by configure. # # Makefile for the SDP example. # This probably requires GNU make. # # Location of includes and library CSRC = ../../src # Library name LNAME = uclmmbase DEFS = -DHAVE_CONFIG_H CFLAGS = -g -W -Wall -Wwrite-strings -Wbad-function-cast -Wmissing-prototypes -Wcast-qual -Wmissing-declarations -Werror $(DEFS) -I$(CSRC) LIBS = -lnsl -lsocket -L$(CSRC) -l$(LNAME) CC = gcc TARGET = sdpdemo OBJS = sdpdemo.o SRCS = $(OBJS:%.o=%.c) all: $(TARGET) sdpdemo: $(OBJS) $(CSRC)/lib$(LNAME).a $(CC) $(CFLAGS) -o $@ $(@).o $(LIBS) .c.o: $(CC) $(CFLAGS) $(INC) -c $< $(CSRC)/lib$(LNAME).a: cd $(CSRC) && $(MAKE) clean: -rm -f $(OBJS) $(TARGET) distclean: clean -rm -f Makefile uclmmbase-1.2.16.0/examples/sdp/Makefile.in0000644000175000017500000000107607665114417017353 0ustar enderender# # Makefile for the SDP example. # This probably requires GNU make. # # Location of includes and library CSRC = ../../src # Library name LNAME = uclmmbase DEFS = @DEFS@ CFLAGS = @CFLAGS@ $(DEFS) -I$(CSRC) LIBS = @LIBS@ -L$(CSRC) -l$(LNAME) CC = @CC@ TARGET = sdpdemo OBJS = sdpdemo.o SRCS = $(OBJS:%.o=%.c) all: $(TARGET) sdpdemo: $(OBJS) $(CSRC)/lib$(LNAME).a $(CC) $(CFLAGS) -o $@ $(@).o $(LIBS) .c.o: $(CC) $(CFLAGS) $(INC) -c $< $(CSRC)/lib$(LNAME).a: cd $(CSRC) && $(MAKE) clean: -rm -f $(OBJS) $(TARGET) distclean: clean -rm -f Makefileuclmmbase-1.2.16.0/examples/sdp/sdpdemo.c0000644000175000017500000000227707665114417017111 0ustar enderender/* * sdpdemo: A simple sdp application that recieves SAP/SDP data. * * (c) 2002 Argonne National Laboratory/University of Chicago */ #include #include #include #include #include #include #include #include "uclconf.h" #include "config_unix.h" #include "config_win32.h" #include "debug.h" #include "memory.h" #include "sap.h" #include "sdp.h" static void sap_handler(sap_packet *packet) { sdp *session = NULL; char *new_payload = NULL; print_sap_packet(packet); session = sdp_parse(packet->payload); printf("Original Packet: \n++++\n%s++++\n", session->original); sdp_print(session); new_payload = sdp_make(session); if(strcmp(packet->payload, new_payload) != 0) printf("The two sdp payloads are different!\n"); xfree(new_payload); sdp_free(session); /* This is causing a seg fault, and a memory leak */ /* xfree(packet); */ } int main() { struct sap *session = NULL; struct timeval timeout; session = sap_init("224.2.127.254", 9875, 127, sap_handler); timeout.tv_sec = 0; timeout.tv_usec = 0; while(1) sap_recv(session, &timeout); sap_done(session); return 0; } uclmmbase-1.2.16.0/tests/0000755000175000017500000000000010374736110014027 5ustar enderenderuclmmbase-1.2.16.0/tests/Makefile.in0000644000175000017500000000137307252203535016101 0ustar enderender# # Makefile for the common code library project. # This probably requires GNU make. # COMMONLIB=uclmmbase COMMONSRC=../src COMMONTGT = $(COMMONSRC)/lib$(COMMONLIB).a DEFS = @DEFS@ CFLAGS = -I$(COMMONSRC) @CFLAGS@ $(DEFS) LIBS = -L../src @LIBS@ CC = @CC@ OBJS = test_base64.o test_des.o test_md5.o test_net_udp.o \ test_memory.o test_mbus_parser.o test_mbus_addr.o \ test.o SRCS = $(OBJS:%.o=%.c) all: test-libcommon test-libcommon: $(OBJS) $(COMMONTGT) $(CC) $(OBJS) $(CFLAGS) $(COMMONTGT) $(LIBS) -o test-libcommon .c.o: $(CC) $(CFLAGS) $(INC) -c $< clean: -rm -f $(OBJS) tags test-libcommon distclean: clean -rm -f Makefile etags: etags *.[ch] ctags: ctags *.[ch] depend: $(SRCS) makedepend $(DEFS) $(INC) $(SRCS) uclmmbase-1.2.16.0/tests/test.c0000640000175000017500000000542407051621152015150 0ustar enderender/* * FILE: test.c * AUTHORS: Colin Perkins * * Copyright (c) 1999-2000 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Science * Department at University College London * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ #include "config_unix.h" #include "config_win32.h" #include "debug.h" #include "version.h" #include "test_base64.h" #include "test_des.h" #include "test_md5.h" #include "test_memory.h" #include "test_net_udp.h" #include "test_mbus_parser.h" #include "test_mbus_addr.h" #ifdef WIN32 #define WS_VERSION_ONE MAKEWORD(1,1) #define WS_VERSION_TWO MAKEWORD(2,2) #endif int main(int argc, char *argv[]) { #ifdef WIN32 WSADATA WSAdata; if (WSAStartup(WS_VERSION_TWO, &WSAdata) != 0 && WSAStartup(WS_VERSION_ONE, &WSAdata) != 0) { printf("Windows Socket initialization failed.\n"); return 1; } debug_msg("WSAStartup OK: %sz\nStatus:%s\n", WSAdata.szDescription, WSAdata.szSystemStatus); #endif UNUSED(argc); UNUSED(argv); printf("Testing common multimedia library %s\n", CCL_VERSION); test_base64(); test_des(); test_md5(); test_memory(); test_net_udp(); test_mbus_parser(); test_mbus_addr(); #ifdef WIN32 Sleep(2000); WSACleanup(); #endif return 0; } uclmmbase-1.2.16.0/tests/test_base64.c0000640000175000017500000000517707051621153016322 0ustar enderender/* * FILE: test_base64.c * AUTHORS: Colin Perkins * * Copyright (c) 1999-2000 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Science * Department at University College London * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ #include "config_unix.h" #include "config_win32.h" #include "debug.h" #include "base64.h" #include "test_base64.h" void test_base64(void) { /* The string "Hello, world" should encode as "SGVsbG8sIHdvcmxk" */ const char *input = "Hello, world"; char output[100]; char decode[100]; int i; for (i = 0; i < 100; i++) { output[i] = '\0'; } printf("Base64 encode.......................... "); fflush(stdout); i = base64encode(input, strlen(input), output, 100); if ((i != 16) || (strncmp(output, "SGVsbG8sIHdvcmxk", i) != 0)) { printf("fail\n"); return; } printf("pass\n"); printf("Base64 decode.......................... "); fflush(stdout); i = base64decode(output, i, decode, 100); if ((i != 12) || (strncmp(decode, "Hello, world", i) != 0)) { printf("fail\n"); return; } printf("pass\n"); } uclmmbase-1.2.16.0/tests/test_base64.h0000640000175000017500000000354107034372541016325 0ustar enderender/* * FILE: test_base64.h * AUTHORS: Colin Perkins * * Copyright (c) 1999-2000 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Science * Department at University College London * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ void test_base64(void); uclmmbase-1.2.16.0/tests/test_des.c0000640000175000017500000002366607034513401016011 0ustar enderender/* * FILE: test_des.c * AUTHORS: Colin Perkins * * The test vectors and outline structure of this are taken from Eric * Young's destest.c from libdes, version 3.00 (7 October 1993). * * Copyright (c) 1993 Eric Young * All rights reserved. * * Copyright (c) 1999-2000 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Science * Department at University College London * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ #include "config_unix.h" #include "config_win32.h" #include "debug.h" #include "memory.h" #include "qfDES.h" #include "test_des.h" #define NUM_TESTS 36 static unsigned char key_data[NUM_TESTS][8]={ {0x12,0x34,0x57,0x79,0x9b,0xbc,0xdf,0xf1}, {0x0e,0x32,0x92,0x32,0xea,0x6d,0x0d,0x72}, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11}, {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11}, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, {0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10}, {0x7C,0xA1,0x10,0x45,0x4A,0x1A,0x6E,0x57}, {0x01,0x31,0xD9,0x61,0x9D,0xC1,0x37,0x6E}, {0x07,0xA1,0x13,0x3E,0x4A,0x0B,0x26,0x86}, {0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E}, {0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6}, {0x01,0x13,0xB9,0x70,0xFD,0x34,0xF2,0xCE}, {0x01,0x70,0xF1,0x75,0x46,0x8F,0xB5,0xE6}, {0x43,0x29,0x7F,0xAD,0x38,0xE3,0x73,0xFE}, {0x07,0xA7,0x13,0x70,0x45,0xDA,0x2A,0x16}, {0x04,0x68,0x91,0x04,0xC2,0xFD,0x3B,0x2F}, {0x37,0xD0,0x6B,0xB5,0x16,0xCB,0x75,0x46}, {0x1F,0x08,0x26,0x0D,0x1A,0xC2,0x46,0x5E}, {0x58,0x40,0x23,0x64,0x1A,0xBA,0x61,0x76}, {0x02,0x58,0x16,0x16,0x46,0x29,0xB0,0x07}, {0x49,0x79,0x3E,0xBC,0x79,0xB3,0x25,0x8F}, {0x4F,0xB0,0x5E,0x15,0x15,0xAB,0x73,0xA7}, {0x49,0xE9,0x5D,0x6D,0x4C,0xA2,0x29,0xBF}, {0x01,0x83,0x10,0xDC,0x40,0x9B,0x26,0xD6}, {0x1C,0x58,0x7F,0x1C,0x13,0x92,0x4F,0xEF}, {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, {0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E}, {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE}, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, {0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10}}; static unsigned char plain_data[NUM_TESTS][8]={ {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}, {0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87}, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11}, {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11}, {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, {0x01,0xA1,0xD6,0xD0,0x39,0x77,0x67,0x42}, {0x5C,0xD5,0x4C,0xA8,0x3D,0xEF,0x57,0xDA}, {0x02,0x48,0xD4,0x38,0x06,0xF6,0x71,0x72}, {0x51,0x45,0x4B,0x58,0x2D,0xDF,0x44,0x0A}, {0x42,0xFD,0x44,0x30,0x59,0x57,0x7F,0xA2}, {0x05,0x9B,0x5E,0x08,0x51,0xCF,0x14,0x3A}, {0x07,0x56,0xD8,0xE0,0x77,0x47,0x61,0xD2}, {0x76,0x25,0x14,0xB8,0x29,0xBF,0x48,0x6A}, {0x3B,0xDD,0x11,0x90,0x49,0x37,0x28,0x02}, {0x26,0x95,0x5F,0x68,0x35,0xAF,0x60,0x9A}, {0x16,0x4D,0x5E,0x40,0x4F,0x27,0x52,0x32}, {0x6B,0x05,0x6E,0x18,0x75,0x9F,0x5C,0xCA}, {0x00,0x4B,0xD6,0xEF,0x09,0x17,0x60,0x62}, {0x48,0x0D,0x39,0x00,0x6E,0xE7,0x62,0xF2}, {0x43,0x75,0x40,0xC8,0x69,0x8F,0x3C,0xFA}, {0x07,0x2D,0x43,0xA0,0x77,0x07,0x52,0x92}, {0x02,0xFE,0x55,0x77,0x81,0x17,0xF1,0x2A}, {0x1D,0x9D,0x5C,0x50,0x18,0xF7,0x28,0xC2}, {0x30,0x55,0x32,0x28,0x6D,0x6F,0x29,0x5A}, {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}}; static unsigned char crypt_data[NUM_TESTS][8]={ {0x85,0xe8,0x13,0x54,0x0f,0x0a,0xb4,0x05}, {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, {0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7}, {0x73,0x59,0xB2,0x16,0x3E,0x4E,0xDC,0x58}, {0x95,0x8E,0x6E,0x62,0x7A,0x05,0x55,0x7B}, {0xF4,0x03,0x79,0xAB,0x9E,0x0E,0xC5,0x33}, {0x17,0x66,0x8D,0xFC,0x72,0x92,0x53,0x2D}, {0x8A,0x5A,0xE1,0xF8,0x1A,0xB8,0xF2,0xDD}, {0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7}, {0xED,0x39,0xD9,0x50,0xFA,0x74,0xBC,0xC4}, {0x69,0x0F,0x5B,0x0D,0x9A,0x26,0x93,0x9B}, {0x7A,0x38,0x9D,0x10,0x35,0x4B,0xD2,0x71}, {0x86,0x8E,0xBB,0x51,0xCA,0xB4,0x59,0x9A}, {0x71,0x78,0x87,0x6E,0x01,0xF1,0x9B,0x2A}, {0xAF,0x37,0xFB,0x42,0x1F,0x8C,0x40,0x95}, {0x86,0xA5,0x60,0xF1,0x0E,0xC6,0xD8,0x5B}, {0x0C,0xD3,0xDA,0x02,0x00,0x21,0xDC,0x09}, {0xEA,0x67,0x6B,0x2C,0xB7,0xDB,0x2B,0x7A}, {0xDF,0xD6,0x4A,0x81,0x5C,0xAF,0x1A,0x0F}, {0x5C,0x51,0x3C,0x9C,0x48,0x86,0xC0,0x88}, {0x0A,0x2A,0xEE,0xAE,0x3F,0xF4,0xAB,0x77}, {0xEF,0x1B,0xF0,0x3E,0x5D,0xFA,0x57,0x5A}, {0x88,0xBF,0x0D,0xB6,0xD7,0x0D,0xEE,0x56}, {0xA1,0xF9,0x91,0x55,0x41,0x02,0x0B,0x56}, {0x6F,0xBF,0x1C,0xAF,0xCF,0xFD,0x05,0x56}, {0x2F,0x22,0xE4,0x9B,0xAB,0x7C,0xA1,0xAC}, {0x5A,0x6B,0x61,0x2C,0xC2,0x6C,0xCE,0x4A}, {0x5F,0x4C,0x03,0x8E,0xD1,0x2B,0x2E,0x41}, {0x63,0xFA,0xC0,0xD0,0x34,0xD9,0xF7,0x93}, {0x61,0x7B,0x3A,0x0C,0xE8,0xF0,0x71,0x00}, {0xDB,0x95,0x86,0x05,0xF8,0xC8,0xC6,0x06}, {0xED,0xBF,0xD1,0xC6,0x6C,0x29,0xCC,0xC7}, {0x35,0x55,0x50,0xB2,0x15,0x0E,0x24,0x51}, {0xCA,0xAA,0xAF,0x4D,0xEA,0xF1,0xDB,0xAE}, {0xD5,0xD4,0x4F,0xF7,0x20,0x68,0x3D,0x0D}, {0x2A,0x2B,0xB0,0x08,0xDF,0x97,0xC2,0xF2}}; static unsigned char cbc_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; static unsigned char cbc_iv[8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10}; static unsigned char cbc_data[32]="7654321 Now is the time for "; static unsigned char cbc_ok[32]={ 0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4, 0xac,0xd8,0xae,0xfd,0xdf,0xd8,0xa1,0xeb, 0x46,0x8e,0x91,0x15,0x78,0x88,0xba,0x68, 0x1d,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4}; #ifdef NDEF static unsigned char pcbc_ok[32]={ 0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4, 0x6d,0xec,0xb4,0x70,0xa0,0xe5,0x6b,0x15, 0xae,0xa6,0xbf,0x61,0xed,0x7d,0x9c,0x9f, 0xf7,0x17,0x46,0x3b,0x8a,0xb3,0xcc,0x88}; static unsigned char cksum_ok[8]={ 0x1d,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4}; static unsigned char cfb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; static unsigned char cfb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef}; static unsigned char cfb_buf1[24],cfb_buf2[24],cfb_tmp[8]; static unsigned char cfb_plain[24]={ 0x4e,0x6f,0x77,0x20,0x69,0x73, 0x20,0x74,0x68,0x65,0x20,0x74, 0x69,0x6d,0x65,0x20,0x66,0x6f, 0x72,0x20,0x61,0x6c,0x6c,0x20}; static unsigned char cfb_cipher[24]= { 0xf3,0x1f,0xda,0x07,0x01,0x14, 0x62,0xee,0x18,0x7f,0x43,0xd8, 0x0a,0x7c,0xd9,0xb5,0xb0,0xd2, 0x90,0xda,0x6e,0x5b,0x9a,0x87}; static unsigned char ofb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; static unsigned char ofb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef}; static unsigned char ofb_plain[24]={ 0x4e,0x6f,0x77,0x20,0x69,0x73, 0x20,0x74,0x68,0x65,0x20,0x74, 0x69,0x6d,0x65,0x20,0x66,0x6f, 0x72,0x20,0x61,0x6c,0x6c,0x20}; static unsigned char ofb_buf1[24],ofb_buf2[24],ofb_tmp[8]; static unsigned char ofb_cipher[24]={ 0xf3,0x09,0x62,0x49,0xc7,0xf4,0x6e,0x51, 0x35,0xf2,0x4a,0x24,0x2e,0xeb,0x3d,0x3f, 0x3d,0x6d,0x5b,0xe3,0x25,0x5a,0xf8,0xc3}; #endif void test_des(void) { int i, j; unsigned char key[8], plain[8], crypt[8], buffer[8]; unsigned char cbc_buffer[32], cbc_iv_buf[8]; printf("DES ECB................................ "); fflush(stdout); for (i = 0; i < NUM_TESTS; i++) { for (j = 0; j < 8; j++) { key[j] = key_data[i][j]; plain[j] = plain_data[i][j]; crypt[j] = crypt_data[i][j]; } memcpy(buffer, crypt, 8); qfDES_ECB_d(key, buffer, 8); if (memcmp(buffer, plain, 8) != 0) { printf("fail\n"); goto abort_ecb; } memcpy(buffer, plain, 8); qfDES_ECB_e(key, buffer, 8); if (memcmp(buffer, crypt, 8) != 0) { printf("fail\n"); goto abort_ecb; } qfDES_ECB_d(key, buffer, 8); if (memcmp(buffer, plain, 8) != 0) { printf("fail\n"); goto abort_ecb; } } printf("pass\n"); abort_ecb: printf("DES CBC................................ "); fflush(stdout); memcpy(cbc_buffer, cbc_data, 32); memcpy(cbc_iv_buf, cbc_iv, 8); qfDES_CBC_e(cbc_key, cbc_buffer, 32, cbc_iv_buf); if (memcmp(cbc_buffer, cbc_ok, 32) != 0) { printf("fail\n"); return; } memcpy(cbc_iv_buf, cbc_iv, 8); qfDES_CBC_d(cbc_key, cbc_buffer, 32, cbc_iv_buf); if (memcmp(cbc_buffer, cbc_data, 32) != 0) { printf("fail\n"); return; } printf("pass\n"); } uclmmbase-1.2.16.0/tests/test_des.h0000640000175000017500000000353307034372542016016 0ustar enderender/* * FILE: test_des.h * AUTHORS: Colin Perkins * * Copyright (c) 1999-2000 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Science * Department at University College London * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ void test_des(void); uclmmbase-1.2.16.0/tests/test_mbus_addr.c0000640000175000017500000000743507054107130017172 0ustar enderender/* * FILE: test_mbus_addr.c * AUTHORS: Colin Perkins * * Copyright (c) 2000 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Science * Department at University College London * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ #include "config_unix.h" #include "config_win32.h" #include "debug.h" #include "mbus_addr.h" #include "test_mbus_addr.h" int strfind(const char *haystack, const char *needle_start, const char *needle_end); void test_mbus_addr(void) { const char haystack[] = "The quick brown fox jumped over the lazy dog"; const char needle_1[] = "fox"; const char needle_2[] = "fat fox jumping"; const char needle_3[] = "The"; const char needle_4[] = "dog"; const char a1[] = "()"; const char a2[] = "( one two three)"; const char a3[] = " ( four five six)"; const char a4[] = "six four"; const char a5[] = " three one two"; const char a6[] = ""; printf("Mbus addr (strfind).................... "); fflush(stdout); if (!strfind(haystack, needle_1, needle_1 + strlen(needle_1) - 1)) { printf("fail (1)\n"); goto match; } if (strfind(haystack, needle_2, needle_2 + strlen(needle_2) - 1)) { printf("fail (2)\n"); goto match; } if (!strfind(haystack, needle_3, needle_3 + strlen(needle_1) - 1)) { printf("fail (3)\n"); goto match; } if (!strfind(haystack, needle_4, needle_4 + strlen(needle_1) - 1)) { printf("fail (4)\n"); goto match; } if (!strfind(haystack, needle_2 + 4, needle_2 + 7)) { printf("fail (5)\n"); goto match; } printf("pass\n"); match: printf("Mbus addr (match)...................... "); fflush(stdout); if (!mbus_addr_match(a2, a1)) { printf("fail (1)\n"); goto identical; } if (mbus_addr_match(a2, a3)) { printf("fail (2)\n"); goto identical; } if (!mbus_addr_match(a3, a4)) { printf("fail (3)\n"); goto identical; } if (!mbus_addr_match(a3, a6)) { printf("fail (4)\n"); goto identical; } if (mbus_addr_match(a6, a3)) { printf("fail (5)\n"); goto identical; } printf("pass\n"); identical: printf("Mbus addr (identical).................. "); fflush(stdout); if (!mbus_addr_identical(a2, a5)) { printf("fail (1)\n"); return; } if (mbus_addr_identical(a4, a3)) { printf("fail (2)\n"); return; } printf("pass\n"); } uclmmbase-1.2.16.0/tests/test_mbus_addr.h0000640000175000017500000000354207051621153017175 0ustar enderender/* * FILE: test_mbus_addr.h * AUTHORS: Colin Perkins * * Copyright (c) 2000 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Science * Department at University College London * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ void test_mbus_addr(void); uclmmbase-1.2.16.0/tests/test_mbus_parser.c0000640000175000017500000001003307054107130017540 0ustar enderender/* * FILE: test_mbus_parser.c * AUTHORS: Colin Perkins * * Copyright (c) 2000 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Science * Department at University College London * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ #include "config_unix.h" #include "config_win32.h" #include "debug.h" #include "memory.h" #include "mbus_parser.h" #include "test_mbus_parser.h" static void test_encdec(void) { char *res; const char *str1d = "Hello, world!"; const char *str1e = "\"Hello,\\ world!\""; const char *str2d = "Test \"quoted\" text"; const char *str2e = "\"Test\\ \\\"quoted\\\"\\ text\""; printf("Mbus parser (string encode/decode)..... "); fflush(stdout); res = mbus_encode_str(str1d); if (strcmp(res, str1e) != 0) { printf("fail (%s != %s)\n", res, str1e); goto fail; } xfree(res); res = mbus_encode_str(str2d); if (strcmp(res, str2e) != 0) { printf("fail (%s != %s)\n", res, str2e); goto fail; } res = xstrdup(str1e); mbus_decode_str(res); if (strcmp(res, str1d) != 0) { printf("fail (%s != %s)\n", res, str1d); goto fail; } xfree(res); res = xstrdup(str2e); mbus_decode_str(res); if (strcmp(res, str2d) != 0) { printf("fail (%s != %s)\n", res, str2d); goto fail; } printf("pass\n"); fail: xfree(res); } static void test_parsing(void) { struct mbus_parser *p; char *str1 = xstrdup("1234 567.89 Symbol \"String\" (a b c) ()"); int i; double d; char *s; printf("Mbus parser (parsing).................. "); fflush(stdout); p = mbus_parse_init(str1); if (!mbus_parse_int(p, &i)) { printf("fail (1)\n"); goto done; } if (i != 1234) { printf("fail (2)\n"); goto done; } if (!mbus_parse_flt(p, &d)) { printf("fail (3)\n"); goto done; } if (d != 567.89) { printf("fail (4)\n"); goto done; } if (!mbus_parse_sym(p, &s)) { printf("fail (5)\n"); goto done; } if (strcmp(s, "Symbol") != 0) { printf("fail (6)\n"); goto done; } if (!mbus_parse_str(p, &s)) { printf("fail (7)\n"); goto done; } if (strcmp(s, "\"String\"") != 0) { printf("fail (8)\n"); goto done; } if (!mbus_parse_lst(p, &s)) { printf("fail (9)\n"); goto done; } if (strcmp(s, "a b c") != 0) { printf("fail (10)\n"); goto done; } if (!mbus_parse_lst(p, &s)) { printf("fail (11)\n"); goto done; } if (strcmp(s, "") != 0) { printf("fail (12)\n"); goto done; } printf("pass\n"); done: mbus_parse_done(p); } void test_mbus_parser(void) { test_encdec(); test_parsing(); } uclmmbase-1.2.16.0/tests/test_mbus_parser.h0000640000175000017500000000354607051621154017564 0ustar enderender/* * FILE: test_mbus_parser.h * AUTHORS: Colin Perkins * * Copyright (c) 2000 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Science * Department at University College London * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ void test_mbus_parser(void); uclmmbase-1.2.16.0/tests/test_md5.c0000640000175000017500000000510007034513401015702 0ustar enderender/* * FILE: test_md5.c * AUTHORS: Colin Perkins * * Copyright (c) 1999-2000 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Science * Department at University College London * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ #include "config_unix.h" #include "config_win32.h" #include "debug.h" #include "memory.h" #include "md5.h" #include "test_md5.h" static int do_test(int len) { unsigned char *input; unsigned char output[16]; int i; MD5_CTX context; input = (unsigned char *) xmalloc(len+1); for (i = 0; i < len; i++) { input[i] = lrand48() % 255; } input[len] = '\0'; MD5Init(&context); MD5Update(&context, input, len); MD5Final(output, &context); xfree(input); return TRUE; } void test_md5(void) { int i, l; printf("MD5.................................... "); fflush(stdout); for (i = 0; i < 10000; i++) { l = lrand48() % 1024; if (do_test(l) == FALSE) { printf("fail\n"); abort(); } } printf("pass\n"); } uclmmbase-1.2.16.0/tests/test_md5.h0000640000175000017500000000353307034372542015730 0ustar enderender/* * FILE: test_md5.h * AUTHORS: Colin Perkins * * Copyright (c) 1999-2000 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Science * Department at University College London * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ void test_md5(void); uclmmbase-1.2.16.0/tests/test_memory.c0000640000175000017500000001105607055462312016543 0ustar enderender/* * FILE: test_memory.c * AUTHORS: Orion Hodson * * Copyright (c) 1999-2000 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Science * Department at University College London * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ #include "config_unix.h" #include "config_win32.h" #include "debug.h" #include "drand48.h" #include "memory.h" #include "util.h" #include "test_memory.h" #ifdef DEBUG_MEM static size_t sz[] = {17, 32, 64, 81, 1024, 4096}; static void fill_block(char *y, uint32_t ylen) { uint32_t i, xlen; double *x; xlen = ylen / sizeof(double); x = (double*)y; for(i = 0; i < xlen; i++) { x[i] = 0; } } static void do_test() { static char *b[37]; static uint32_t s[37]; uint32_t i, idx, nslots, nszs, r; uint32_t allocations; memset(b, 0, sizeof(b)); memset(s, 0, sizeof(s)); nszs = sizeof(sz)/sizeof(sz[0]); nslots = sizeof(b)/sizeof(b[0]); /* test xmalloc */ for (allocations = 10; allocations < 1000000; allocations *= 10) { for (i = 0; i < allocations; i++) { idx = drand48(); idx = idx % nslots; if (b[idx] != NULL) { xfree(b[idx]); } r = drand48(); b[idx] = (void*)xmalloc(sz[r % nszs]); fill_block(b[idx], sz[r % nszs]); } for(idx = 0; idx < nslots; idx++) { xmemchk(); if (b[idx] != NULL) { xfree(b[idx]); b[idx] = NULL; } xmemchk(); } } /* test block alloc */ for (allocations = 10; allocations < 1000000; allocations *= 10) { for (i = 0; i < allocations; i++) { idx = drand48(); idx = idx % nslots; if (b[idx] != NULL) { block_free(b[idx], s[idx]); } r = drand48(); s[idx] = sz[r % nszs]; b[idx] = (void*)block_alloc(s[idx]); fill_block(b[idx], s[idx]); } for(idx = 0; idx < nslots; idx++) { xmemchk(); if (b[idx] != NULL) { block_free(b[idx], s[idx]); b[idx] = NULL; } xmemchk(); } } } void test_memory(void) { printf("Memory................................. "); fflush(stdout); do_test(); printf("pass\n"); } #else void test_memory(void) { return; } #endif /* DEBUG_MEM */ uclmmbase-1.2.16.0/tests/test_memory.h0000640000175000017500000000354007051317516016550 0ustar enderender/* * FILE: test_memory.h * AUTHORS: Orion Hodson * * Copyright (c) 1999-2000 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Science * Department at University College London * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ void test_memory(void); uclmmbase-1.2.16.0/tests/test_net_udp.c0000640000175000017500000003051507176526030016674 0ustar enderender/* * FILE: test_net_udp.c * AUTHORS: Colin Perkins * * Copyright (c) 2000 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Science * Department at University College London * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ #include "config_unix.h" #include "config_win32.h" #include "debug.h" #include "net_udp.h" #include "test_net_udp.h" #define BUFSIZE 1024 static void randomize(char buf[], int buflen) { int i; for (i = 0; i < buflen; i++) { buf[i] = (lrand48() && 0xff00) >> 8; } } void test_net_udp(void) { struct timeval timeout; socket_udp *s1, *s2; char buf1[BUFSIZE], buf2[BUFSIZE]; const char *hname; int rc, i; #ifndef WIN32 /* "BSD" bug test that appears in this function uses fork and * exec, that are not present on WIN32. Since the original * bug has not been seen on Win32 it's probably not worth * converting to use CreateProcess() */ int status_parent, status_child; #endif /* WIN32 */ srand48(time(NULL)); /**********************************************************************/ /* The first test is to loopback a packet to ourselves... */ printf("UDP/IP networking (IPv4 loopback)...... "); fflush(stdout); s1 = udp_init("127.0.0.1", 5000, 5000, 1); if (s1 == NULL) { printf("fail: cannot initialize socket\n"); return; } randomize(buf1, BUFSIZE); randomize(buf2, BUFSIZE); if (udp_send(s1, buf1, BUFSIZE) < 0) { perror("fail"); goto abort_loopback; } timeout.tv_sec = 1; timeout.tv_usec = 0; udp_fd_zero(); udp_fd_set(s1); rc = udp_select(&timeout); if (rc < 0) { perror("fail"); goto abort_loopback; } if (rc == 0) { printf("fail: no data waiting\n"); goto abort_loopback; } if (!udp_fd_isset(s1)) { printf("fail: no data on file descriptor\n"); goto abort_loopback; } if (udp_recv(s1, buf2, BUFSIZE) < 0) { perror("fail"); goto abort_loopback; } if (memcmp(buf1, buf2, BUFSIZE) != 0) { printf("fail: buffer corrupt\n"); goto abort_loopback; } printf("pass\n"); abort_loopback: hname = udp_host_addr(s1); /* we need this for the unicast test... */ udp_exit(s1); /**********************************************************************/ /* Now we send a packet to ourselves via our real network address... */ printf("UDP/IP networking (IPv4 unicast)....... "); fflush(stdout); s1 = udp_init(hname, 5000, 5001, 1); if (s1 == NULL) { printf("fail: cannot initialize socket\n"); return; } s2 = udp_init(hname, 5001, 5000, 1); if (s2 == NULL) { printf("fail: cannot initialize socket\n"); return; } randomize(buf1, BUFSIZE); randomize(buf2, BUFSIZE); if (udp_send(s1, buf1, BUFSIZE) < 0) { perror("fail"); goto abort_unicast; } timeout.tv_sec = 1; timeout.tv_usec = 0; udp_fd_zero(); udp_fd_set(s1); udp_fd_set(s2); rc = udp_select(&timeout); if (rc < 0) { perror("fail"); goto abort_unicast; } if (rc == 0) { printf("fail: no data waiting (no route to %s?)\n", hname); goto abort_unicast; } if (!udp_fd_isset(s2)) { printf("fail: no data on file descriptor\n"); goto abort_unicast; } if (udp_recv(s2, buf2, BUFSIZE) < 0) { perror("fail"); goto abort_unicast; } if (memcmp(buf1, buf2, BUFSIZE) != 0) { printf("fail: buffer corrupt\n"); goto abort_unicast; } printf("pass\n"); abort_unicast: udp_exit(s1); udp_exit(s2); /**********************************************************************/ /* Loopback a packet to ourselves via multicast... */ printf("UDP/IP networking (IPv4 multicast)..... "); fflush(stdout); s1 = udp_init("224.2.0.1", 5000, 5000, 1); if (s1 == NULL) { printf("fail: cannot initialize socket\n"); return; } randomize(buf1, BUFSIZE); randomize(buf2, BUFSIZE); if (udp_send(s1, buf1, BUFSIZE) < 0) { perror("fail"); goto abort_multicast; } timeout.tv_sec = 1; timeout.tv_usec = 0; udp_fd_zero(); udp_fd_set(s1); rc = udp_select(&timeout); if (rc < 0) { perror("fail"); goto abort_multicast; } if (rc == 0) { printf("fail: no data waiting (no multicast loopback route?)\n"); goto abort_multicast; } if (!udp_fd_isset(s1)) { printf("fail: no data on file descriptor\n"); goto abort_multicast; } if (udp_recv(s1, buf2, BUFSIZE) < 0) { perror("fail"); goto abort_multicast; } if (memcmp(buf1, buf2, BUFSIZE) != 0) { printf("fail: buffer corrupt\n"); goto abort_multicast; } printf("pass\n"); abort_multicast: udp_exit(s1); /**********************************************************************/ /* Loopback a packet to ourselves via multicast, checking lengths... */ printf("UDP/IP networking (IPv4 length check).. "); fflush(stdout); s1 = udp_init("224.2.0.1", 5000, 5000, 1); if (s1 == NULL) { printf("fail: cannot initialize socket\n"); return; } for (i = 1; i < BUFSIZE; i++) { randomize(buf1, i); randomize(buf2, i); if (udp_send(s1, buf1, i) < 0) { perror("fail"); goto abort_length; } timeout.tv_sec = 1; timeout.tv_usec = 0; udp_fd_zero(); udp_fd_set(s1); rc = udp_select(&timeout); if (rc < 0) { perror("fail"); goto abort_length; } if (rc == 0) { printf("fail: no data waiting (no multicast loopback route?)\n"); goto abort_length; } if (!udp_fd_isset(s1)) { printf("fail: no data on file descriptor\n"); goto abort_length; } if (udp_recv(s1, buf2, BUFSIZE) != i) { perror("fail"); goto abort_length; } if (memcmp(buf1, buf2, i) != 0) { printf("fail: buffer corrupt\n"); goto abort_length; } } printf("pass\n"); abort_length: udp_exit(s1); #ifdef HAVE_IPv6 /**********************************************************************/ /* The first test is to loopback a packet to ourselves... */ printf("UDP/IP networking (IPv6 loopback)...... "); fflush(stdout); s1 = udp_init("::1", 5000, 5000, 1); if (s1 == NULL) { printf("fail: cannot initialize socket\n"); return; } randomize(buf1, BUFSIZE); randomize(buf2, BUFSIZE); if (udp_send(s1, buf1, BUFSIZE) < 0) { perror("fail"); goto abort_loopback_ipv6; } timeout.tv_sec = 1; timeout.tv_usec = 0; udp_fd_zero(); udp_fd_set(s1); rc = udp_select(&timeout); if (rc < 0) { perror("fail"); goto abort_loopback_ipv6; } if (rc == 0) { printf("fail: no data waiting\n"); goto abort_loopback_ipv6; } if (!udp_fd_isset(s1)) { printf("fail: no data on file descriptor\n"); goto abort_loopback_ipv6; } if (udp_recv(s1, buf2, BUFSIZE) < 0) { perror("fail"); goto abort_loopback_ipv6; } if (memcmp(buf1, buf2, BUFSIZE) != 0) { printf("fail: buffer corrupt\n"); goto abort_loopback_ipv6; } printf("pass\n"); abort_loopback_ipv6: udp_exit(s1); /**********************************************************************/ /* Loopback a packet to ourselves via multicast. The address is the */ /* SAP address, but we use a different port. */ printf("UDP/IP networking (IPv6 multicast)..... "); fflush(stdout); s1 = udp_init("ff01::2:7ffe", 5000, 5000, 1); if (s1 == NULL) { printf("fail: cannot initialize socket\n"); return; } randomize(buf1, BUFSIZE); randomize(buf2, BUFSIZE); if (udp_send(s1, buf1, BUFSIZE) < 0) { perror("fail"); goto abort_multicast_ipv6; } timeout.tv_sec = 1; timeout.tv_usec = 0; udp_fd_zero(); udp_fd_set(s1); rc = udp_select(&timeout); if (rc < 0) { perror("fail"); goto abort_multicast_ipv6; } if (rc == 0) { printf("fail: no data waiting (no multicast loopback route?)\n"); goto abort_multicast_ipv6; } if (!udp_fd_isset(s1)) { printf("fail: no data on file descriptor\n"); goto abort_multicast_ipv6; } if (udp_recv(s1, buf2, BUFSIZE) < 0) { perror("fail"); goto abort_multicast_ipv6; } if (memcmp(buf1, buf2, BUFSIZE) != 0) { printf("fail: buffer corrupt\n"); goto abort_multicast_ipv6; } hname = udp_host_addr(s1); /* we need this for the unicast test... */ printf("pass\n"); abort_multicast_ipv6: udp_exit(s1); #else printf("UDP/IP networking (IPv6 loopback)...... disabled\n"); printf("UDP/IP networking (IPv6 unicast)....... disabled\n"); printf("UDP/IP networking (IPv6 multicast)..... disabled\n"); #endif /**********************************************************************/ #ifdef WIN32 printf("UDP/IP networking (FreeBSD bug)........ disabled\n"); #else printf("UDP/IP networking (FreeBSD bug)........ "); fflush(stdout); status_parent = 0; randomize(buf1, 64); s1 = udp_init("224.2.0.1", 5000, 5000, 1); if (s1 == NULL) { printf("fail (parent): cannot initialize socket\n"); return; } rc = fork(); if (rc == -1) { printf("fail: cannot fork\n"); goto abort_bsd; } else if (rc == 0) { /* child */ s2 = udp_init("224.2.0.1", 5000, 5000, 1); if (s2 == NULL) { printf("fail (child): cannot initialize socket\n"); exit(0); } if (udp_send(s2, buf1, 64) < 0) { perror("fail (child)"); exit(0); } timeout.tv_sec = 10; timeout.tv_usec = 0; udp_fd_zero(); udp_fd_set(s2); rc = udp_select(&timeout); if (rc < 0) { perror("fail (child)"); exit(0); } if (rc == 0) { printf("fail (child): no data waiting (no multicast loopback route?)\n"); exit(0); } if (!udp_fd_isset(s2)) { printf("fail (child): no data on file descriptor\n"); exit(0); } rc = udp_recv(s2, buf2, BUFSIZE); if (rc < 0) { perror("fail (child)"); exit(0); } if (rc != 64) { printf("fail (child): read size incorrect (%d != %d)\n", rc, 64); exit(0); } if (memcmp(buf1, buf2, 64) != 0) { printf("fail (child): buffer corrupt\n"); exit(0); } udp_exit(s2); exit(1); } else { /* parent */ timeout.tv_sec = 10; timeout.tv_usec = 0; udp_fd_zero(); udp_fd_set(s1); rc = udp_select(&timeout); if (rc < 0) { perror("fail (parent)"); goto abort_bsd; } if (rc == 0) { printf("fail (parent): no data waiting (no multicast loopback route?)\n"); goto abort_bsd; } if (!udp_fd_isset(s1)) { printf("fail (parent): no data on file descriptor\n"); goto abort_bsd; } rc = udp_recv(s1, buf2, BUFSIZE); if (rc < 0) { perror("fail (parent)"); goto abort_bsd; } if (rc != 64) { printf("fail (parent): read size incorrect (%d != %d)\n", rc, 64); goto abort_bsd; } if (memcmp(buf1, buf2, 64) != 0) { printf("fail (parent): buffer corrupt\n"); goto abort_bsd; } status_parent = 1; } abort_bsd: wait(&status_child); if (status_parent && status_child) { printf("pass\n"); } udp_exit(s1); #endif /* WIN32 */ return; } uclmmbase-1.2.16.0/tests/test_net_udp.h0000640000175000017500000000353607034513402016674 0ustar enderender/* * FILE: test_net_udp.h * AUTHORS: Colin Perkins * * Copyright (c) 2000 University College London * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, is permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * 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 the Computer Science * Department at University College London * 4. Neither the name of the University nor of the Department may be used * to endorse or promote products derived from this software without * specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * 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 OF * SUCH DAMAGE. */ void test_net_udp(void); uclmmbase-1.2.16.0/tests/testcommon.dsp0000644000175000017500000001357107042077431016740 0ustar enderender# Microsoft Developer Studio Project File - Name="testcommon" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Console Application" 0x0103 CFG=testcommon - Win32 Debug IPv6 !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "testcommon.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "testcommon.mak" CFG="testcommon - Win32 Debug IPv6" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "testcommon - Win32 Release" (based on "Win32 (x86) Console Application") !MESSAGE "testcommon - Win32 Debug" (based on "Win32 (x86) Console Application") !MESSAGE "testcommon - Win32 Debug IPv6" (based on "Win32 (x86) Console Application") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "testcommon - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c # ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 !ELSEIF "$(CFG)" == "testcommon - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "testcommon___Win32_Debug" # PROP BASE Intermediate_Dir "testcommon___Win32_Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c # ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "DEBUG" /YX /FD /GZ /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept # ADD LINK32 uclmm.lib winmm.lib wsock32.lib Ws2_32.lib kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"\src\common\Debug" !ELSEIF "$(CFG)" == "testcommon - Win32 Debug IPv6" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug IPv6" # PROP BASE Intermediate_Dir "Debug IPv6" # PROP BASE Ignore_Export_Lib 0 # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug_IPv6" # PROP Intermediate_Dir "Debug_IPv6" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c # ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "\DDK\inc" /I "..\ipv6kit\inc" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "HAVE_IPv6" /D "DEBUG" /YX /FD /GZ /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 uclmm.lib winmm.lib wsock32.lib Ws2_32.lib kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /debug /machine:I386 /out:"Debug/testcommon.exe" /pdbtype:sept /libpath:"\src\common\Debug" # ADD LINK32 uclmm.lib winmm.lib wsock32.lib Ws2_32.lib kernel32.lib user32.lib advapi32.lib wship6.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"\src\common\Debug_IPv6" /libpath:"\src\IPv6Kit\lib" !ENDIF # Begin Target # Name "testcommon - Win32 Release" # Name "testcommon - Win32 Debug" # Name "testcommon - Win32 Debug IPv6" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=.\test.c # End Source File # Begin Source File SOURCE=.\test_base64.c # End Source File # Begin Source File SOURCE=.\test_des.c # End Source File # Begin Source File SOURCE=.\test_md5.c # End Source File # Begin Source File SOURCE=.\test_net_udp.c # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File SOURCE=.\test_base64.h # End Source File # Begin Source File SOURCE=.\test_des.h # End Source File # Begin Source File SOURCE=.\test_md5.h # End Source File # Begin Source File SOURCE=.\test_net_udp.h # End Source File # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # End Target # End Project