feature: send packets (reponse not working tho)

This commit is contained in:
0x35c 2025-05-26 12:18:06 +02:00
parent 9378251248
commit 1ffb554a32
7 changed files with 150 additions and 5 deletions

1
.gitignore vendored
View File

@ -2,3 +2,4 @@ obj
ft_nmap ft_nmap
.cache .cache
compile_commands.json compile_commands.json
tags

16
include/packet.h Normal file
View File

@ -0,0 +1,16 @@
#pragma once
#include <stdint.h>
#include "scan.h"
struct pshdr {
uint32_t src_addr;
uint32_t dst_addr;
uint8_t placeholder;
uint8_t protocol;
uint16_t tcp_length;
};
int send_packets(const struct scan *data, int sockfd);
unsigned short checksum(void *data, int len);

13
src/checksum.c Normal file
View File

@ -0,0 +1,13 @@
#include <stddef.h>
unsigned short checksum(void *data, int len)
{
unsigned short *cpy = data;
unsigned int sum = 0;
for (int i = 0; i < len; i += 2)
sum += *cpy++;
sum = (sum >> 16) + (sum & 0xFFFF);
sum += (sum >> 16);
return ~sum;
}

View File

@ -34,9 +34,11 @@ int main(int ac, char **av)
struct thread *single_thread = malloc(sizeof(struct thread)); struct thread *single_thread = malloc(sizeof(struct thread));
if (get_interface_name(&single_thread->host) < 0) if (get_interface_name(&single_thread->host) < 0)
return 1; return 1;
single_thread->port_start = 1; single_thread->dest_addr = ip_addr;
single_thread->port_start = 21;
single_thread->port_end = 1024; single_thread->port_end = 1024;
single_thread->responses = responses; single_thread->responses = responses;
single_thread->type = SCAN_SYN;
if (routine(single_thread) == NULL) { if (routine(single_thread) == NULL) {
dprintf(2, "ft_nmap: failed to scan ports\n"); dprintf(2, "ft_nmap: failed to scan ports\n");
return 1; return 1;

108
src/packet.c Normal file
View File

@ -0,0 +1,108 @@
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "packet.h"
#include "scan.h"
void create_udp_packet(struct udphdr *udphdr, const struct scan *data)
{
udphdr->source = htons(1234);
udphdr->dest = htons(data->port);
udphdr->len = sizeof(struct udphdr);
udphdr->check = 0;
udphdr->check = checksum(udphdr, sizeof(struct udphdr));
}
int create_tcp_packet(struct tcphdr *tcphdr, const struct scan *data)
{
tcphdr->source = htons(1234);
tcphdr->dest = htons(data->port);
tcphdr->seq = 0;
tcphdr->ack_seq = 0;
tcphdr->doff = sizeof(struct tcphdr) / sizeof(int);
tcphdr->fin = data->type == SCAN_XMAS || data->type == SCAN_FIN;
tcphdr->syn = data->type == SCAN_SYN;
tcphdr->rst = 0;
tcphdr->psh = data->type == SCAN_XMAS;
tcphdr->ack = data->type == SCAN_ACK;
tcphdr->urg = data->type == SCAN_XMAS;
tcphdr->window = htons(5840);
tcphdr->check = 0;
tcphdr->urg_ptr = 0;
struct pshdr pshdr;
pshdr.src_addr = inet_addr(data->host->ip);
pshdr.dst_addr = inet_addr(data->dest_addr);
pshdr.placeholder = 0;
pshdr.protocol = IPPROTO_TCP;
pshdr.tcp_length = htons(sizeof(struct tcphdr));
size_t pseudogram_size = sizeof(struct pshdr) + sizeof(struct tcphdr);
void *pseudogram = malloc(pseudogram_size);
if (!pseudogram)
return -1;
memcpy(pseudogram, &pshdr, sizeof(pshdr));
memcpy(pseudogram + sizeof(pshdr), tcphdr, sizeof(struct tcphdr));
tcphdr->check = checksum(pseudogram, pseudogram_size);
free(pseudogram);
return 0;
}
static void *create_packet(const struct scan *data, size_t packet_size)
{
const bool isudp = data->type == SCAN_UDP;
void *packet = malloc(packet_size);
if (!packet) {
dprintf(2,
"ft_nmap: allocation failed during packet creation\n");
return NULL;
}
struct iphdr *iphdr = packet;
iphdr->ihl = sizeof(struct iphdr) / sizeof(int);
iphdr->version = 4;
iphdr->tos = 0;
iphdr->tot_len = packet_size;
iphdr->id = htons(54321);
iphdr->frag_off = 0;
iphdr->ttl = 48;
iphdr->protocol = isudp ? IPPROTO_UDP : IPPROTO_TCP;
iphdr->check = 0;
iphdr->saddr = inet_addr(data->host->ip);
iphdr->daddr = inet_addr(data->dest_addr);
iphdr->check = checksum(packet, packet_size);
// this is starnakin stuff
switch ((int)isudp) {
case true:
create_udp_packet(packet + sizeof(struct iphdr), data);
break;
default:
create_tcp_packet(packet + sizeof(struct iphdr), data);
}
return packet;
}
int send_packets(const struct scan *data, int sockfd)
{
struct sockaddr_in conn_addr;
size_t packet_size = sizeof(struct iphdr) +
(data->type == SCAN_UDP ? sizeof(struct udphdr)
: sizeof(struct tcphdr));
void *packet = create_packet(data, packet_size);
sendto(sockfd, packet, packet_size, 0, (struct sockaddr *)&conn_addr,
sizeof(struct sockaddr_in));
free(packet);
return 0;
}

View File

@ -8,6 +8,7 @@
#include <stdio.h> #include <stdio.h>
#include <sys/socket.h> #include <sys/socket.h>
#include "packet.h"
#include "response.h" #include "response.h"
#include "scan.h" #include "scan.h"
@ -18,6 +19,8 @@ static void dispatch_callback(u_char *user, const struct pcap_pkthdr *h,
const struct iphdr *iphdr = const struct iphdr *iphdr =
(struct iphdr *)(bytes + sizeof(struct ether_header)); (struct iphdr *)(bytes + sizeof(struct ether_header));
printf("uwu\n");
if (iphdr->protocol == IPPROTO_TCP && if (iphdr->protocol == IPPROTO_TCP &&
h->caplen >= sizeof(struct ether_header) + sizeof(struct iphdr) + h->caplen >= sizeof(struct ether_header) + sizeof(struct iphdr) +
sizeof(struct tcphdr)) { sizeof(struct tcphdr)) {
@ -43,8 +46,8 @@ static void dispatch_callback(u_char *user, const struct pcap_pkthdr *h,
int scan(const struct scan *data) int scan(const struct scan *data)
{ {
int sockfd = socket( int sockfd = socket(AF_INET, SOCK_RAW,
AF_INET, data->type == SCAN_UDP ? SOCK_DGRAM : SOCK_STREAM, 0); data->type == SCAN_UDP ? IPPROTO_UDP : IPPROTO_TCP);
if (sockfd < 0) { if (sockfd < 0) {
dprintf(2, "ft_nmap: failed to create socket"); dprintf(2, "ft_nmap: failed to create socket");
return -1; return -1;
@ -71,7 +74,7 @@ int scan(const struct scan *data)
data->dest_addr, data->port, data->host->ip); data->dest_addr, data->port, data->host->ip);
if (pcap_compile(handle, &fp, pcap_expr, 0, mask) < 0) { if (pcap_compile(handle, &fp, pcap_expr, 0, mask) < 0) {
dprintf(2, "ft_nmap: failed to lookup net/mask\n"); dprintf(2, "ft_nmap: failed to compile pcap expression\n");
pcap_close(handle); pcap_close(handle);
return -1; return -1;
} }
@ -84,7 +87,7 @@ int scan(const struct scan *data)
pcap_freecode(&fp); pcap_freecode(&fp);
// send packets send_packets(data, sockfd);
// TODO test with another cnt value // TODO test with another cnt value
if (pcap_dispatch(handle, 10, dispatch_callback, (u_char *)data)) { if (pcap_dispatch(handle, 10, dispatch_callback, (u_char *)data)) {

View File

@ -21,6 +21,8 @@ void *routine(void *p_data)
scan_data.response = scan_data.response =
&thread_data->responses[thread_data->port_start - port]; &thread_data->responses[thread_data->port_start - port];
scan(&scan_data); scan(&scan_data);
printf("state of port %d: %d\n", port,
scan_data.response->state);
} }
return p_data; return p_data;