问题
I wrote a c program that listen to 443 port and receives ssl packets :
#include <errno.h>
#include <ctype.h>
#include <limits.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/stat.h>
#include <stdio.h>
#define MAX_SIZE 10000
struct ssl_header {
uint8_t type;
uint16_t version;
uint16_t length;
};
struct handshake {
struct ssl_header hdr;
uint8_t type;
unsigned int length[3];
unsigned int ssl_version[2];
char random[32];
};
void *message_processing(int sockfd){
char *buff = calloc(MAX_SIZE + 1, sizeof (char));
struct handshake *pkt;
pkt = calloc (1, sizeof (struct handshake));
while (1) {
int len_of_read_data = read( sockfd, buff, MAX_SIZE);
if (len_of_read_data > 0) {
memcpy(pkt, buff, sizeof (struct handshake) );
FILE* file = fopen("logfile", "a");
fprintf (file, "*********************************\n");
fprintf (file, "type1 : %u\n", pkt->hdr.type );
fprintf(file, "version1 : %u\n", pkt->hdr.version);
fprintf(file, "len1 : %u\n", pkt->hdr.length);
fprintf(file, "type2 : %u\n", pkt->type);
fprintf(file, "len2 : %u%u%u\n", pkt->length[0],pkt->length[1], pkt->length[2] );
fprintf(file, "version2 : %u.%u\n", pkt->ssl_version[0], pkt->ssl_version[1]);
fprintf(file, "random : %s\n", pkt->random);
fclose(file);
}
}
}
int main () {
struct sockaddr_in serv_addr;
int sock_descriptor = socket(AF_INET, SOCK_STREAM, 0);
int trueval = 1;
setsockopt(sock_descriptor, SOL_SOCKET, SO_REUSEPORT | SO_REUSEADDR, (char *)&trueval, sizeof(trueval));
bzero((char *) &serv_addr, sizeof (serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(443);
bind(sock_descriptor, (struct sockaddr *) &serv_addr, sizeof (serv_addr));
listen(sock_descriptor, 50);
while (1) {
struct sockaddr_in cli_addr;
socklen_t clilen;
clilen = sizeof(cli_addr);
int client_socket = accept(sock_descriptor, (struct sockaddr *) &cli_addr, &clilen);
message_processing(client_socket);
pthread_t pid;
pthread_create(&pid, NULL, (void *) message_processing, &client_socket);
pthread_join(pid, NULL);
}
}
I create structures from this link : http://blog.fourthbit.com/2014/12/23/traffic-analysis-of-an-ssl-slash-tls-session/
when i run the program and connect to it using curl -I https://127.0.0.1:443 --insecure, it receives some data . the problem is when i print that data in logfile file , i get these value that all are incorrect except type1 :
*********************************
type1 : 22
version1 : 513
len1 : 256
type2 : 0
len2 : 31543142363974688046409855404
version2 : 4270624758.750651113
random : �&,�X�I�Y��|}
i'm new in c and specially in struct and i'm not sure the problem is occurred when i create the structs or when i try to print fields. can anybody help to figure out the problem.
回答1:
You have a problem with wrong data types and with padding of your structures.
From your link, the TLS header contains:
- 1 byte type
- 2 bytes version
- 2 bytes length
Your attempt to map this to a structure has some flaw:
struct ssl_header {
uint8_t type;
uint16_t version;
uint16_t length;
};
For most architectures, a uint8_t
has no specific alignment requirements while uint16_t
is probably aligned on a 2byte boundary.
This is achieved by inserting invisible padding bytes.
While the header is 5 bytes, your struct contains 6 bytes or even more.
You might try to address this by using packed structs.
The second problem is you are using wrong types in your arrays.
The protocol definition contains a length field of 3 bytes and a version field of 2 bytes. In total these are 5 bytes.
Your struct looks like this:
unsigned int length[3];
unsigned int ssl_version[2];
This means you have 5 integers meaning 10, 20 or even 40 bytes in total.
Additionally you will have padding bytes also in this structure.
The layout of your structures is far off of the protocol definition.
You should not try to read a buffer directly into a memory location that is interpreted as a struct. Instead you should read and handle each field separately. Then you can properly handly endianess, integer fields of any length and don't need to take care about padding in your structs.
来源:https://stackoverflow.com/questions/59629415/problem-in-create-packet-using-struct-in-c