Skip to content

Instantly share code, notes, and snippets.

@joshfinley
Created February 7, 2020 21:40
Show Gist options
  • Save joshfinley/1bd3b37aab46d68f23c1131d4b4a972b to your computer and use it in GitHub Desktop.
Save joshfinley/1bd3b37aab46d68f23c1131d4b4a972b to your computer and use it in GitHub Desktop.
cdp-frame.c
#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