Created
February 7, 2020 21:40
-
-
Save joshfinley/1bd3b37aab46d68f23c1131d4b4a972b to your computer and use it in GitHub Desktop.
cdp-frame.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <errno.h> | |
#include <string.h> | |
#include <arpa/inet.h> | |
#include <net/ethernet.h> | |
#include <net/if.h> | |
#include <netinet/if_ether.h> | |
#include <netpacket/packet.h> | |
#include <sys/ioctl.h> | |
#include <sys/socket.h> | |
#include <stdio.h> | |
union ethframe | |
{ | |
struct | |
{ | |
struct ethhdr header; | |
unsigned char data[ETH_DATA_LEN]; | |
} field; | |
unsigned char buffer[ETH_FRAME_LEN]; | |
}; | |
int main() | |
{ | |
char *iface = "eth0"; | |
// CDP Broadcast address | |
unsigned char dest[] = { | |
0x01, 0x00, 0x0c, 0xcc, 0xcc, 0xcc | |
}; | |
// Logical-Link Control Fields | |
unsigned char logical_link_control[] = { | |
0xaa, // DSAP | |
0xaa, // SSAP | |
0x03, // Control field | |
0x00, // Organization Code | |
0x00, // ... | |
0x0c, // | |
0x20, // PID | |
0x00, // ... | |
}; | |
unsigned char data[] = ""; | |
unsigned short data_len = strlen(data); | |
// Create the socket | |
int s; | |
if ((s = socket(AF_PACKET, SOCK_RAW, htons(logical_link_control))) < 0) { | |
printf("Error: could not open socket\n"); | |
return -1; | |
} | |
// Get the interface index | |
struct ifreq buffer; | |
int ifindex; | |
memset(&buffer, 0x00, sizeof(buffer)); | |
strncpy(buffer.ifr_name, iface, IFNAMSIZ); | |
if (ioctl(s, SIOCGIFINDEX, &buffer) < 0) { | |
printf("Error: could not get interface index\n"); | |
close(s); | |
return -1; | |
} | |
ifindex = buffer.ifr_ifindex; | |
printf("%d\n", ifindex); | |
// Get the source mac address | |
unsigned char source[ETH_ALEN]; | |
if (ioctl(s, SIOCGIFHWADDR, &buffer) < 0) { | |
printf("Error: could not get interface address\n"); | |
close(s); | |
return -1; | |
} | |
memcpy((void*)source, (void*)(buffer.ifr_hwaddr.sa_data), | |
ETH_ALEN); | |
// Create the Ethernet frame | |
union ethframe frame; | |
// Set frame source and destination MAC addresses | |
memcpy(frame.field.header.h_dest, dest, ETH_ALEN); | |
memcpy(frame.field.header.h_source, source, ETH_ALEN); | |
// Set the frame protocol | |
frame.field.header.h_proto = htons(logical_link_control); | |
// Set the frame payload | |
memcpy(frame.field.data, data, data_len); | |
// Fill in the sockaddr_ll | |
unsigned int frame_len = data_len + ETH_HLEN; | |
struct sockaddr_ll saddrll; | |
memset((void *) &saddrll, 0, sizeof(saddrll)); | |
saddrll.sll_family = PF_PACKET; | |
saddrll.sll_ifindex = ifindex; | |
saddrll.sll_halen = ETH_ALEN; | |
memcpy((void *) (saddrll.sll_addr), (void *) dest, ETH_ALEN); | |
// Send the packet | |
sendto( | |
s, | |
frame.buffer, | |
frame_len, | |
0, | |
(struct sockaddr *)&saddrll, | |
sizeof(saddrll)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment