mirror of
https://code.semirocket.science/wrapsix
synced 2024-11-10 08:10:59 +02:00
Completed the implementation of NDP
This commit is contained in:
parent
322eeabefb
commit
39ba6988c0
@ -2,7 +2,7 @@ CC = gcc
|
||||
CFLAGS = -Wall -O0
|
||||
LDFLAGS = -L/usr/lib -lpcap
|
||||
|
||||
all: wrapper.o process.o translate_ip.o connections.o checksum.o
|
||||
all: wrapper.o process.o translate_ip.o connections.o checksum.o if.o
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) *.o -o wrapper
|
||||
|
||||
wrapper.o: wrapper.c wrapper.h
|
||||
@ -20,5 +20,8 @@ connections.o: connections.c wrapper.h
|
||||
checksum.o: checksum.c
|
||||
$(CC) $(CFLAGS) -c checksum.c -o checksum.o
|
||||
|
||||
if.o: if.c wrapper.h
|
||||
$(CC) $(CFLAGS) -c if.c -o if.o
|
||||
|
||||
clean:
|
||||
rm -f wrapper *.o
|
||||
|
@ -1,4 +1,6 @@
|
||||
#include <unistd.h>
|
||||
#include <net/if.h> /* ifreq */
|
||||
#include <netinet/if_ether.h> /* ETH_P_IP, ETH_P_ALL */
|
||||
#include <netpacket/packet.h> /* sockaddr_ll, PACKET_OTHERHOST */
|
||||
|
||||
#include "wrapper.h"
|
||||
|
||||
@ -21,3 +23,47 @@ void send_there(struct in_addr ip4_addr, unsigned char ttl, unsigned int type, u
|
||||
|
||||
close(sock);
|
||||
}
|
||||
|
||||
void send_ndp(struct ip6_hdr *ip, unsigned char *packet, int packet_size)
|
||||
{
|
||||
struct sockaddr_ll socket_address; /* target address */
|
||||
struct ifreq ifr; /* interface */
|
||||
|
||||
int sock;
|
||||
|
||||
/* prepare data for RAW socket */
|
||||
socket_address.sll_family = PF_PACKET; /* RAW communication */
|
||||
socket_address.sll_protocol = htons(ETH_P_IP); /* protocol above the ethernet layer */
|
||||
socket_address.sll_ifindex = get_dev_index(dev); /* set index of the network device */
|
||||
socket_address.sll_pkttype = PACKET_OTHERHOST; /* target host is another host */
|
||||
|
||||
/* initialize with zeros */
|
||||
memset(&ifr, 0, sizeof(struct ifreq));
|
||||
|
||||
/* set device */
|
||||
strncpy(ifr.ifr_name, dev, strlen(dev));
|
||||
|
||||
/* initialize raw socket */
|
||||
if ((sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) == -1) {
|
||||
fprintf(stderr, "Couldn't open RAW socket.\n");
|
||||
perror("socket()");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* bind the socket to the interface */
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(struct ifreq)) == -1){
|
||||
fprintf(stderr, "Couldn't bind the socket to the interface.\n");
|
||||
perror("setsockopt()");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* send the NDP packet */
|
||||
if (sendto(sock, packet, packet_size, 0, (struct sockaddr *) &socket_address, sizeof(struct sockaddr_ll)) != packet_size) {
|
||||
fprintf(stderr, " Error: Couldn't send NDP packet.\n");
|
||||
perror("sendto()");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* close the socket */
|
||||
close(sock);
|
||||
}
|
||||
|
57
wrapper/if.c
Normal file
57
wrapper/if.c
Normal file
@ -0,0 +1,57 @@
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/if.h>
|
||||
|
||||
#include "wrapper.h"
|
||||
|
||||
/*
|
||||
* Return the MAC (ie, ethernet hardware) address
|
||||
*/
|
||||
int get_mac_addr(const char *dev, struct s_mac_addr *addr)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
int s, ret;
|
||||
|
||||
if ((s = socket(PF_INET, SOCK_DGRAM, 0)) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&ifr, 0x00, sizeof(ifr));
|
||||
strcpy(ifr.ifr_name, dev);
|
||||
|
||||
if (ioctl(s, SIOCGIFHWADDR, &ifr) == 0) {
|
||||
memcpy(addr, &ifr.ifr_hwaddr.sa_data, sizeof(struct s_mac_addr));
|
||||
ret = 0;
|
||||
}
|
||||
else {
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
close(s);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return device index
|
||||
*/
|
||||
int get_dev_index(const char *dev)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
int s;
|
||||
|
||||
memset(&ifr, 0x00, sizeof(ifr));
|
||||
|
||||
if ((s = socket(PF_INET, SOCK_DGRAM, 0)) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
strncpy((char *) ifr.ifr_name, dev, IFNAMSIZ);
|
||||
if ((ioctl(s, SIOCGIFINDEX, &ifr)) == -1) {
|
||||
printf("Error getting Interface index !\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
close(s);
|
||||
|
||||
return ifr.ifr_ifindex;
|
||||
}
|
@ -1,13 +1,14 @@
|
||||
#include "wrapper.h"
|
||||
#include "translate_ip.h"
|
||||
|
||||
struct in6_addr ip6addr_wrapsix;
|
||||
|
||||
void process_packet6(u_char *args, const struct pcap_pkthdr *header, const u_char *packet)
|
||||
{
|
||||
const struct s_ethernet *ethernet; /* the ethernet header */
|
||||
const struct s_ip6 *ip; /* the IP header */
|
||||
const unsigned char *payload; /* packet payload */
|
||||
|
||||
struct in6_addr ip6addr_wrapsix;
|
||||
struct in6_addr ip6addr_ndp_multicast;
|
||||
|
||||
/* define ethernet header */
|
||||
@ -19,6 +20,13 @@ void process_packet6(u_char *args, const struct pcap_pkthdr *header, const u_cha
|
||||
/* define/compute IP payload offset */
|
||||
payload = packet + SIZE_ETHERNET + SIZE_IP6;
|
||||
|
||||
/* DEBUG: print source and destination IP addresses */
|
||||
char ip6addr[INET6_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET6, &ip->ip_src, ip6addr, sizeof(ip6addr));
|
||||
printf("\n From: %s\n", ip6addr);
|
||||
inet_ntop(AF_INET6, &ip->ip_dest, ip6addr, sizeof(ip6addr));
|
||||
printf(" To: %s\n", ip6addr);
|
||||
|
||||
/* check if this packet is ours - partially hardcoded for now */
|
||||
inet_pton(AF_INET6, "fc00:1::", &ip6addr_wrapsix);
|
||||
inet_pton(AF_INET6, "ff02::1:ff00:0", &ip6addr_ndp_multicast);
|
||||
@ -29,13 +37,6 @@ void process_packet6(u_char *args, const struct pcap_pkthdr *header, const u_cha
|
||||
return;
|
||||
}
|
||||
|
||||
/* DEBUG: print source and destination IP addresses */
|
||||
char ip6addr[INET6_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET6, &ip->ip_src, ip6addr, sizeof(ip6addr));
|
||||
printf("\n From: %s\n", ip6addr);
|
||||
inet_ntop(AF_INET6, &ip->ip_dest, ip6addr, sizeof(ip6addr));
|
||||
printf(" To: %s\n", ip6addr);
|
||||
|
||||
/* determine protocol */
|
||||
switch (ip->next_header) {
|
||||
case IPPROTO_TCP:
|
||||
@ -47,7 +48,7 @@ void process_packet6(u_char *args, const struct pcap_pkthdr *header, const u_cha
|
||||
break;
|
||||
case IPPROTO_ICMPV6:
|
||||
printf(" Protocol: ICMPv6\n");
|
||||
process_icmp6((struct s_ip6 *) ip, payload);
|
||||
process_icmp6((const struct s_ethernet *) ethernet, (struct s_ip6 *) ip, payload);
|
||||
break;
|
||||
default:
|
||||
printf(" Protocol: unknown\n");
|
||||
@ -56,39 +57,30 @@ void process_packet6(u_char *args, const struct pcap_pkthdr *header, const u_cha
|
||||
return;
|
||||
}
|
||||
|
||||
void process_icmp6(const struct s_ip6 *ip, const unsigned char *payload)
|
||||
void process_icmp6(const struct s_ethernet *eth, struct s_ip6 *ip, const unsigned char *payload)
|
||||
{
|
||||
struct s_icmp *icmp;
|
||||
struct in_addr ip4_addr;
|
||||
|
||||
const unsigned char *icmp_data;
|
||||
unsigned char *icmp_data;
|
||||
unsigned char *icmp_packet;
|
||||
|
||||
int packet_size;
|
||||
int packet_size = htons(ip->len);
|
||||
|
||||
/* define ICMP header */
|
||||
icmp = (struct s_icmp *) (payload);
|
||||
/* define/compute ICMP data offset */
|
||||
icmp_data = (unsigned char *) (payload + sizeof(struct s_icmp));
|
||||
/* the checksum has to be zeros before we have data for its computation */
|
||||
icmp->checksum = 0;
|
||||
|
||||
/* create one big ICMP packet */
|
||||
packet_size = htons(ip->len);
|
||||
icmp_packet = (unsigned char *) malloc(packet_size);
|
||||
|
||||
if (icmp_packet == NULL) {
|
||||
fprintf(stderr, "Fatal error! Lack of free memory!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* decide what type of ICMP we have */
|
||||
switch (icmp->type) {
|
||||
/* NDP */
|
||||
case ICMP6_NDP_NS:
|
||||
printf(" ICMP: [NDP] Neighbor Solicitation\n");
|
||||
|
||||
process_ndp(eth, ip, icmp_data);
|
||||
|
||||
return;
|
||||
break;
|
||||
/* ping */
|
||||
case ICMP6_ECHO_REQUEST:
|
||||
printf(" ICMP: Echo Request\n");
|
||||
@ -113,10 +105,20 @@ void process_icmp6(const struct s_ip6 *ip, const unsigned char *payload)
|
||||
break;
|
||||
}
|
||||
|
||||
/* create one big ICMP packet */
|
||||
icmp_packet = (unsigned char *) malloc(packet_size);
|
||||
|
||||
if (icmp_packet == NULL) {
|
||||
fprintf(stderr, "Fatal error! Lack of free memory!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* the checksum has to be zeros before we have data for its computation */
|
||||
icmp->checksum = 0;
|
||||
|
||||
/* copy data into the packet */
|
||||
memcpy(icmp_packet, icmp, sizeof(struct s_icmp));
|
||||
memcpy(icmp_packet + sizeof(struct s_icmp), icmp_data,
|
||||
packet_size - sizeof(struct s_icmp));
|
||||
memcpy(icmp_packet + sizeof(struct s_icmp), icmp_data, packet_size - sizeof(struct s_icmp));
|
||||
|
||||
/* compute the checksum */
|
||||
icmp->checksum = checksum(icmp_packet, packet_size);
|
||||
@ -134,6 +136,101 @@ void process_icmp6(const struct s_ip6 *ip, const unsigned char *payload)
|
||||
/* free allocated memory */
|
||||
free(icmp_packet);
|
||||
icmp_packet = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void process_ndp(const struct s_ethernet *eth_hdr, struct s_ip6 *ip_hdr, unsigned char *icmp_data)
|
||||
{
|
||||
unsigned char *packet;
|
||||
struct s_ethernet *eth;
|
||||
struct ip6_hdr *ip;
|
||||
struct s_icmp *icmp;
|
||||
struct s_icmp_ndp_ns *ndp_ns;
|
||||
struct s_icmp_ndp_na *ndp_na;
|
||||
|
||||
unsigned char *buf_ip6_pseudo;
|
||||
struct s_ip6_pseudo *ip6_pseudo;
|
||||
|
||||
int packet_size;
|
||||
|
||||
/* get the NDP data */
|
||||
ndp_ns = (struct s_icmp_ndp_ns *) icmp_data;
|
||||
|
||||
/* check if the requested address is ours */
|
||||
if (memcmp(&ip6addr_wrapsix, &ndp_ns->target, 12) != 0) {
|
||||
printf("==> This NDP is not ours! <==\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* allocate memory for the packet */
|
||||
packet_size = SIZE_ETHERNET + SIZE_IP6 + sizeof(struct s_icmp) + sizeof(struct s_icmp_ndp_na);
|
||||
packet = (unsigned char *) malloc(packet_size);
|
||||
|
||||
if (packet == NULL) {
|
||||
fprintf(stderr, "Fatal error! Lack of free memory!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* parse the packet into structures */
|
||||
eth = (struct s_ethernet *) packet;
|
||||
ip = (struct ip6_hdr *) (packet + SIZE_ETHERNET);
|
||||
icmp = (struct s_icmp *) (packet + SIZE_ETHERNET + SIZE_IP6);
|
||||
ndp_na = (struct s_icmp_ndp_na *) (packet + SIZE_ETHERNET + SIZE_IP6 + sizeof(struct s_icmp));
|
||||
|
||||
/* assemble the ethernet header */
|
||||
memcpy(ð->src, mac, sizeof(struct s_mac_addr));
|
||||
eth->dest = eth_hdr->src;
|
||||
eth->type = eth_hdr->type;
|
||||
|
||||
/* assemble the IPv6 header */
|
||||
ip->ip6_src = ndp_ns->target;
|
||||
ip->ip6_dst = ip_hdr->ip_src;
|
||||
ip->ip6_flow = 0;
|
||||
ip->ip6_vfc = 0x60;
|
||||
ip->ip6_plen = htons(sizeof(struct s_icmp) + sizeof(struct s_icmp_ndp_na));
|
||||
ip->ip6_nxt = IPPROTO_ICMPV6;
|
||||
ip->ip6_hlim = 255;
|
||||
|
||||
/* assemble the ICMP header */
|
||||
icmp->type = ICMP6_NDP_NA;
|
||||
icmp->code = 0;
|
||||
icmp->checksum = 0;
|
||||
|
||||
/* assemble the NDP */
|
||||
//ndp_na->flags |= INNAF_S;
|
||||
//ndp_na->flags |= INNAF_O;
|
||||
ndp_na->zeros = 0;
|
||||
ndp_na->flags = 0x60;
|
||||
ndp_na->target = ndp_ns->target;
|
||||
ndp_na->o_type = 2;
|
||||
ndp_na->o_len = 1;
|
||||
memcpy(&ndp_na->o_tlla, mac, sizeof(struct s_mac_addr));
|
||||
|
||||
/* compute the ICMP checksum */
|
||||
buf_ip6_pseudo = (unsigned char *) malloc(sizeof(struct s_ip6_pseudo) + htons(ip->ip6_plen));
|
||||
|
||||
if (buf_ip6_pseudo == NULL) {
|
||||
fprintf(stderr, "Fatal error! Lack of free memory!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ip6_pseudo = (struct s_ip6_pseudo *) buf_ip6_pseudo;
|
||||
|
||||
ip6_pseudo->ip_src = ip->ip6_src;
|
||||
ip6_pseudo->ip_dest = ip->ip6_dst;
|
||||
ip6_pseudo->len = ip->ip6_plen;
|
||||
ip6_pseudo->zeros = 0x0;
|
||||
ip6_pseudo->next_header = ip->ip6_nxt;
|
||||
|
||||
memcpy(buf_ip6_pseudo + sizeof(struct s_ip6_pseudo), icmp, htons(ip->ip6_plen));
|
||||
|
||||
icmp->checksum = checksum(buf_ip6_pseudo, sizeof(struct s_ip6_pseudo) + htons(ip->ip6_plen));
|
||||
|
||||
/* send the packet */
|
||||
send_ndp(ip, packet, packet_size);
|
||||
|
||||
/* free allocated memory */
|
||||
free(packet);
|
||||
free(buf_ip6_pseudo);
|
||||
packet = NULL;
|
||||
buf_ip6_pseudo = NULL;
|
||||
}
|
||||
|
@ -1,33 +1,28 @@
|
||||
#include "wrapper.h"
|
||||
|
||||
struct s_mac_addr *mac; /* MAC address of the device */
|
||||
char *dev; /* capture device name */
|
||||
int dev_index; /* capture device index */
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
char *dev = NULL; /* capture device name */
|
||||
char errbuf[PCAP_ERRBUF_SIZE]; /* error buffer */
|
||||
pcap_t *handle; /* packet capture handle */
|
||||
|
||||
//char filter_exp[] = "ip6"; /* filter expression */
|
||||
char filter_exp[] = "icmp6"; /* filter expression */
|
||||
struct bpf_program fp; /* compiled filter program (expression) */
|
||||
bpf_u_int32 mask; /* subnet mask */
|
||||
bpf_u_int32 net; /* ip */
|
||||
int num_packets = 0; /* number of packets to capture */
|
||||
int num_packets = 0; /* number of packets to capture; 0 = infinite */
|
||||
|
||||
/* find a capture device */
|
||||
dev = NULL;
|
||||
dev = pcap_lookupdev(errbuf);
|
||||
if (dev == NULL) {
|
||||
fprintf(stderr, "Couldn't find default device: %s\n", errbuf);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* get network number and mask associated with capture device */
|
||||
if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) {
|
||||
fprintf(stderr, "Couldn't get netmask for device %s: %s\n", dev, errbuf);
|
||||
net = 0;
|
||||
mask = 0;
|
||||
}
|
||||
|
||||
/* print capture info */
|
||||
printf("Device: %s\n", dev);
|
||||
printf("Number of packets: %d\n", num_packets);
|
||||
@ -46,17 +41,25 @@ int main(int argc, char **argv)
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* obtain MAC address of the device */
|
||||
mac = (struct s_mac_addr *) malloc(sizeof(struct s_mac_addr));
|
||||
if (get_mac_addr(dev, mac) != 0) {
|
||||
fprintf(stderr, "Couldn't get device MAC address\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* get index of the device */
|
||||
dev_index = get_dev_index(dev);
|
||||
|
||||
/* compile the filter expression */
|
||||
if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) {
|
||||
fprintf(stderr, "Couldn't parse filter %s: %s\n",
|
||||
filter_exp, pcap_geterr(handle));
|
||||
if (pcap_compile(handle, &fp, filter_exp, 0, 0) == -1) {
|
||||
fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* apply the compiled filter */
|
||||
if (pcap_setfilter(handle, &fp) == -1) {
|
||||
fprintf(stderr, "Couldn't install filter %s: %s\n",
|
||||
filter_exp, pcap_geterr(handle));
|
||||
fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(handle));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
@ -5,12 +5,14 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/ip6.h> /* ip6_hdr */
|
||||
|
||||
/* Default snap length (maximum bytes per packet to capture) */
|
||||
#define SNAP_LEN BUFSIZ
|
||||
@ -18,22 +20,29 @@
|
||||
/* Ethernet headers are always exactly 14 bytes */
|
||||
#define SIZE_ETHERNET 14
|
||||
|
||||
/* Ethernet addresses are 6 bytes */
|
||||
#define ETHER_ADDR_LEN 6
|
||||
|
||||
/* IPv6 headers are always exactly 40 bytes */
|
||||
#define SIZE_IP6 40
|
||||
|
||||
/* Ethernet header */
|
||||
struct s_ethernet {
|
||||
u_char ether_dhost[ETHER_ADDR_LEN]; /* destination host address */
|
||||
u_char ether_shost[ETHER_ADDR_LEN]; /* source host address */
|
||||
u_short ether_type; /* IP/ARP/RARP/... */
|
||||
/* MAC address structure */
|
||||
struct s_mac_addr {
|
||||
unsigned char a;
|
||||
unsigned char b;
|
||||
unsigned char c;
|
||||
unsigned char d;
|
||||
unsigned char e;
|
||||
unsigned char f;
|
||||
};
|
||||
|
||||
/* IPv4 header */
|
||||
/* Ethernet header structure */
|
||||
struct s_ethernet {
|
||||
struct s_mac_addr dest; /* 48 b; destination host (MAC) address */
|
||||
struct s_mac_addr src; /* 48 b; source host (MAC) address */
|
||||
unsigned short type; /* 16 b; IP/ARP/RARP/... */
|
||||
};
|
||||
|
||||
/* IPv6 header */
|
||||
/* IPv4 header structure */
|
||||
|
||||
/* IPv6 header structure */
|
||||
struct s_ip6 {
|
||||
unsigned char ver; /* 8 b; version */
|
||||
unsigned char traffic_class; /* 8 b; traffic class */
|
||||
@ -45,6 +54,17 @@ struct s_ip6 {
|
||||
struct in6_addr ip_dest; /* 128 b; destination address */
|
||||
};
|
||||
|
||||
/* pseudo IPv6 header for checksum */
|
||||
struct s_ip6_pseudo {
|
||||
//unsigned short ip_src[8];
|
||||
//unsigned short ip_dest[8];
|
||||
struct in6_addr ip_src; /* 128 b; source address */
|
||||
struct in6_addr ip_dest; /* 128 b; destination address */
|
||||
unsigned short len; /* 16 b; payload length */
|
||||
unsigned int zeros:24; /* 24 b; reserved */
|
||||
unsigned char next_header; /* 8 b; next header */
|
||||
};
|
||||
|
||||
/* TCP structure - only needed fields! */
|
||||
struct s_tcp {
|
||||
unsigned short port_src; /* 16 b; source port */
|
||||
@ -69,15 +89,31 @@ struct s_icmp_ping {
|
||||
unsigned short seq; /* 16 b; sequence value for ECHO REPLY */
|
||||
};
|
||||
|
||||
/* ICMPv6 - NDP option structure */
|
||||
struct s_icmp_ndp_option {
|
||||
unsigned char type; /* 8 b; type of the option */
|
||||
unsigned char len; /* 8 b; length of the option (including this header!) */
|
||||
};
|
||||
|
||||
/* ICMPv6 - NDP NS structure */
|
||||
struct s_icmp_ndp_ns {
|
||||
unsigned int zeros; /* 32 b; reserved section */
|
||||
struct in6_addr target; /* 128 b; target IP address */
|
||||
};
|
||||
struct s_icmp_ndp_option {
|
||||
unsigned char type; /* 8 b; type of the option */
|
||||
unsigned char len; /* 8 b; length of the option (including this header!) */
|
||||
|
||||
/* ICMPv6 - NDP NA structure */
|
||||
struct s_icmp_ndp_na {
|
||||
unsigned char flags; /* 8 b; 3 flags */
|
||||
unsigned int zeros:24; /* 24 b; reserved section */
|
||||
struct in6_addr target; /* 128 b; target IP address */
|
||||
unsigned char o_type; /* 8 b; option - type */
|
||||
unsigned char o_len; /* 8 b; option - length */
|
||||
struct s_mac_addr o_tlla; /* 48 b; option - target link-layer address */
|
||||
};
|
||||
/* INNAF = ICMPv6 NDP NA Flag */
|
||||
#define INNAF_R 0x80 /* router flag */
|
||||
#define INNAF_S 0x40 /* solicited flag */
|
||||
#define INNAF_O 0x20 /* override flag */
|
||||
|
||||
/* ICMP types */
|
||||
#define ICMP4_ECHO_REQUEST 0x8
|
||||
@ -93,11 +129,21 @@ struct s_icmp_ndp_option {
|
||||
#define ICMP6_NDP_RM 0x89
|
||||
|
||||
/* Prototypes */
|
||||
int get_mac_addr(const char *dev, struct s_mac_addr *addr);
|
||||
int get_dev_index(const char *dev);
|
||||
|
||||
void process_packet6(u_char *args, const struct pcap_pkthdr *header, const u_char *packet);
|
||||
void process_icmp6(const struct s_ip6 *ip, const unsigned char *payload);
|
||||
void process_icmp6(const struct s_ethernet *eth, struct s_ip6 *ip, const unsigned char *payload);
|
||||
void process_ndp(const struct s_ethernet *eth_hdr, struct s_ip6 *ip_hdr, unsigned char *icmp_data);
|
||||
|
||||
void send_there(struct in_addr ip4_addr, unsigned char ttl, unsigned int type, unsigned char *payload, unsigned int paylen);
|
||||
void send_ndp(struct ip6_hdr *ip, unsigned char *packet, int packet_size);
|
||||
|
||||
unsigned short checksum(const void *_buf, int len);
|
||||
|
||||
/* Variables */
|
||||
extern struct s_mac_addr *mac; /* MAC address of the device */
|
||||
extern char *dev; /* capture device name */
|
||||
extern int dev_index; /* capture device index */
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user