feature: start to implement responses

This commit is contained in:
0x35c 2025-05-22 17:08:26 +02:00
parent 1361cd9f9c
commit 84d5960900
10 changed files with 224 additions and 23 deletions

11
include/host.h Normal file
View File

@ -0,0 +1,11 @@
#pragma once
#include <limits.h>
#include <linux/if.h>
#include <netinet/in.h>
struct host {
char name[HOST_NAME_MAX];
char ip[INET_ADDRSTRLEN];
char interface[IFNAMSIZ];
};

View File

@ -1,3 +1,5 @@
#pragma once
char *get_interface_name(void);
#include "host.h"
int get_interface_name(struct host *host);

23
include/response.h Normal file
View File

@ -0,0 +1,23 @@
#pragma once
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <stdint.h>
#include "scan.h"
typedef enum {
OPEN,
CLOSE,
FILTERED,
UNFILTERED,
} e_state;
struct response {
uint16_t port;
e_state state;
char *service;
};
void tcp_response(struct tcphdr *tcp, const struct scan *data);
void udp_response(struct udphdr *udp, const struct scan *data);

View File

@ -2,6 +2,9 @@
#include <stdint.h>
#include "host.h"
#include "response.h"
typedef enum {
SCAN_SYN,
SCAN_NULL,
@ -12,5 +15,13 @@ typedef enum {
SCAN_TCP,
} e_scantype;
int routine(const char *ip_addr, e_scantype type, uint16_t min_port,
uint16_t max_port);
struct scan {
const struct host *host;
const char *dest_addr;
uint16_t port_start;
uint16_t port;
e_scantype type;
struct response *response;
};
int scan(const struct scan *data);

18
include/thread.h Normal file
View File

@ -0,0 +1,18 @@
#pragma once
#include <stdint.h>
#include "host.h"
#include "response.h"
#include "scan.h"
struct thread {
uint16_t port_start;
uint16_t port_end;
char *dest_addr;
e_scantype type;
struct host host;
struct response *responses;
};
void *routine(void *p_data);

View File

@ -1,24 +1,29 @@
#include <pcap.h>
#include <string.h>
char *get_interface_name(void)
#include "host.h"
int get_interface_name(struct host *host)
{
pcap_if_t *alldevs;
char errbuf[PCAP_ERRBUF_SIZE];
if (pcap_findalldevs(&alldevs, errbuf) == -1) {
dprintf(2, "Error finding devices: %s\n", errbuf);
return NULL;
return -1;
}
for (pcap_if_t *it = alldevs; it != NULL; it = it->next) {
if (!(it->flags & PCAP_IF_LOOPBACK)) {
char *name = strdup(it->name);
struct sockaddr_in *tmp =
(struct sockaddr_in *)it->addresses->addr;
strcpy(host->interface, it->name);
strcpy(host->ip, inet_ntoa(tmp->sin_addr));
pcap_freealldevs(alldevs);
return name;
return 0;
}
}
dprintf(2, "No non-loopback interface found.\n");
return NULL;
return -1;
}

View File

@ -5,8 +5,10 @@
#include <stdlib.h>
#include "dns.h"
#include "interface.h"
#include "print.h"
#include "scan.h"
#include "thread.h"
int main(int ac, char **av)
{
@ -26,7 +28,16 @@ int main(int ac, char **av)
av[1]);
return 1;
}
if (routine(ip_addr, SCAN_SYN, 1, 1024) < 0) {
struct response responses[1024];
struct thread *single_thread = malloc(sizeof(struct thread));
if (get_interface_name(&single_thread->host) < 0)
return 1;
single_thread->port_start = 1;
single_thread->port_end = 1024;
single_thread->responses = responses;
if (routine(single_thread) == NULL) {
dprintf(2, "ft_nmap: failed to scan ports\n");
return 1;
}

29
src/response.c Normal file
View File

@ -0,0 +1,29 @@
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <stdio.h>
#include "response.h"
#include "scan.h"
void hdr_response(struct tcphdr *hdr, const struct scan *data)
{
if (data->type == SCAN_SYN) {
if (hdr->ack == 1 && hdr->syn == 1)
data->response->state = OPEN;
else if (hdr->ack == 1 && hdr->rst == 1)
data->response->state = CLOSE;
} else if (data->type == SCAN_ACK && hdr->rst == 1)
data->response->state = UNFILTERED;
else if (data->type == SCAN_NULL && hdr->rst == 1)
data->response->state = CLOSE;
else if (data->type == SCAN_FIN && hdr->rst == 1)
data->response->state = CLOSE;
else if (data->type == SCAN_XMAS && hdr->rst == 1)
data->response->state = CLOSE;
}
void udp_response(struct udphdr *hdr, const struct scan *data)
{
(void)hdr;
data->response->state = OPEN;
}

View File

@ -1,25 +1,89 @@
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <pcap.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/socket.h>
#include "error.h"
#include "interface.h"
#include "scan.h"
#include "thread.h"
int routine(const char *ip_addr, e_scantype type, uint16_t min_port,
uint16_t max_port)
static void dispatch_callback(u_char *user, const struct pcap_pkthdr *h,
const u_char *bytes)
{
int sockfd =
socket(AF_INET, type == SCAN_UDP ? SOCK_DGRAM : SOCK_STREAM, 0);
if (sockfd < 0)
return err("Failed to create socket");
const struct scan *data = (struct scan *)user;
const struct iphdr *iphdr =
(struct iphdr *)(bytes + sizeof(struct ether_header));
char *default_if = get_interface_name();
printf("%s\n", default_if);
if ((data->type == SCAN_UDP && iphdr->protocol != IPPROTO_UDP) ||
(data->type != SCAN_UDP && iphdr->protocol != IPPROTO_TCP)) {
dprintf(2, "ft_nmap: received packet from a different protocol "
"request\n");
return;
}
(void)ip_addr;
for (int port = min_port; port <= max_port; port++) {
// scan(ip_addr, type, port);
if (iphdr->protocol == IPPROTO_TCP &&
h->caplen >= sizeof(struct ether_header) + sizeof(struct iphdr) +
sizeof(struct tcphdr)) {
;
}
if (iphdr->protocol == IPPROTO_UDP &&
h->caplen >= sizeof(struct ether_header) + sizeof(struct iphdr) +
sizeof(struct udphdr)) {
;
}
}
int scan(const struct scan *data)
{
int sockfd = socket(
AF_INET, data->type == SCAN_UDP ? SOCK_DGRAM : SOCK_STREAM, 0);
if (sockfd < 0) {
dprintf(2, "ft_nmap: failed to create socket");
return -1;
}
char errbuf[PCAP_ERRBUF_SIZE];
bpf_u_int32 net, mask;
if (pcap_lookupnet(data->host->interface, &net, &mask, errbuf) < 0) {
dprintf(2, "ft_nmap: failed to lookup net/mask\n");
return -1;
}
pcap_t *handle =
pcap_open_live(data->host->interface, BUFSIZ, 0, 1000, errbuf);
if (handle == NULL) {
dprintf(2, "ft_nmap: failed to open device capture\n");
return -1;
}
struct bpf_program fp;
char pcap_expr[BUFSIZ];
sprintf(pcap_expr, "src host %s and src port %d and dst host %s",
data->dest_addr, data->port, data->host->ip);
if (pcap_compile(handle, &fp, pcap_expr, 0, mask) < 0) {
dprintf(2, "ft_nmap: failed to lookup net/mask\n");
pcap_close(handle);
return -1;
}
if (pcap_setfilter(handle, &fp) < 0) {
dprintf(2, "ft_nmap: failed to set the filter\n");
pcap_close(handle);
return -1;
}
pcap_freecode(&fp);
// send packets
// TODO test with another cnt value
if (pcap_dispatch(handle, 10, dispatch_callback, (u_char *)data)) {
;
}
return 0;

27
src/thread.c Normal file
View File

@ -0,0 +1,27 @@
#include <netinet/in.h>
#include <stdint.h>
#include <stdio.h>
#include "scan.h"
#include "thread.h"
void *routine(void *p_data)
{
struct thread *thread_data = (struct thread *)p_data;
struct scan scan_data = {
.dest_addr = thread_data->dest_addr,
.host = &thread_data->host,
.port_start = thread_data->port_start,
.type = thread_data->type,
};
for (uint16_t port = thread_data->port_start;
port <= thread_data->port_end; port++) {
scan_data.port = port;
scan_data.response =
&thread_data->responses[thread_data->port_start - port];
scan(&scan_data);
}
return p_data;
}