summaryrefslogtreecommitdiff
path: root/reverse-engineering/dosbox_snif/utils.c
blob: 355e858cb753094cbf46ce327ea2dd3dd04bc55a (plain)
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
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include "utils.h"

/* socket() */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
/* getaddrinfo() */
#include <sys/types.h>
#include <netdb.h>
/* inet_ntop() */
#include <arpa/inet.h>
#define GET_SOCK_IN_ADDR(sa) (((struct sockaddr*)sa)->sa_family == AF_INET)?(void *)&(((struct sockaddr_in*)sa)->sin_addr):(void *)&(((struct sockaddr_in6*)sa)->sin6_addr)

#include <string.h> /* memset(), strncmp() */
#include <stdio.h> /* perror(), fprintf(), snprintf(), sscanf() */
#include <stdlib.h> /* malloc(), free() */
#include <unistd.h> /* close() */
#include <errno.h> /* EAGAIN... */


int tcp_client_init(char host[], char port[], int *sockfd) {
	int rv, flag=1;
	char s[INET6_ADDRSTRLEN];
	struct addrinfo hints, *servinfo, *p;
	memset(&hints,0,sizeof(struct addrinfo));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;	

	if ((rv = getaddrinfo(host, port, &hints, &servinfo)) != 0) {
		fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
		return 1;
	}


	// loop through all the results and connect to the first we can
	for(p = servinfo; p != NULL; p = p->ai_next) {
		if ((*sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
			//perror("client: socket");
			continue;
		}

		if ( setsockopt(*sockfd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(flag)) != 0 ) {
			perror("client: setsockopt TCP_NODELAY");
		}

		if (connect(*sockfd, p->ai_addr, p->ai_addrlen) == -1) {
			close(*sockfd);
			//perror("client: connect");
			continue;
		}

		break;
	}

	freeaddrinfo(servinfo);

	if (p == NULL) {
		fprintf(stderr, "client: failed to connect\n");
		return 2;
	}

	inet_ntop(p->ai_family, GET_SOCK_IN_ADDR(p->ai_addr), s, sizeof s);
	printf("client: connecting to %s\n", s);

	return 0;
}

void flatten(char *seg_off) {
	unsigned int seg=0, off=0, flat;
	sscanf(seg_off, "%4x", &seg);
	sscanf(seg_off+5, "%4x", &off);
	flat= (seg<<4) + off;
	snprintf(seg_off, 9, "%x", flat);
}


int hexascii2bin(char src[], void *dst, int maxlen) {
	int i;
	unsigned char offset;
	for (i=0; i<maxlen*2; i++) {
		//if ( src[i] == '\0') return i;
		if ( src[i] >= '0' && src[i] <= '9' ) offset='0';
		else if ( src[i] >= 'a' && src[i] <= 'f' ) offset='a' - 10;
		else if ( src[i] >= 'A' && src[i] <= 'F' ) offset='A' - 10;
		else break;

		if ( i % 2 == 0 ) {
			((unsigned char *)dst)[i/2] = (src[i]-offset) << 4;
		} else {
			((unsigned char *)dst)[i/2] += (src[i]-offset);
		}
	}
	return i/2;
}

// Indicate the position of the bit that is on
// If multiple bits activated, returns -2
// If no bits activated, return -1
int bit_position(uint16_t flags) {
	int i, pos;
	pos=-1; // Not found yet
	for (i=0;i<16;i++) {
		if ( (flags >> i) & 0x0001 ) {
			if ( pos == -1 ) {
				pos=i;
			} else {
				return -2;
			}
		}
	}
	return pos;
}

inline int imin(int a, int b) {
	if ( a < b ) return a;
	return b;
}