Use Pf_packet and Sock_raw to send yourself a defined type Ethernet packet

Source: Internet
Author: User
Tags htons

This article describes the use of Pf_packet and Sock_raw to send themselves a defined type Ethernet packet, using the Wireshare capture packet to get to the packet and pave the line for adding a network protocol to the Linux kernel.

First on the code:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>//close ()
#include <string.h>//strcpy, memset (), and memcpy ()
#include <netdb.h>//struct ADDRINFO
#include <sys/types.h>//needed for sockets (), uint8_t, uint16_t, uint32_t
#include <sys/socket.h>//needed for socket ()
#include <netinet/in.h>//ipproto_icmp, Inet_addrstrlen
#include <netinet/ip.h>//struct IP and Ip_maxpacket (which is 65535)
#include <netinet/ip_icmp.h>//struct ICMP, Icmp_echo
#include <arpa/inet.h>//Inet_pton () and Inet_ntop ()
#include <sys/ioctl.h>//macro IOCTL is defined
#include <bits/ioctls.h>//Defines values for argument "request" of the IOCTL.
#include <net/if.h>//struct IFREQ
#include <linux/if_ether.h>//eth_p_ip = 0x0800, Eth_p_ipv6 = 0X86DD
#include <linux/if_packet.h>//struct SOCKADDR_LL (see Mans 7 packet)
#include <net/ethernet.h>

#include <errno.h>//errno, perror ()
#define Eth_p_dean 0x8874//self-defined Ethernet protocol type

int main (int argc, char **argv)
{
int i, datalen,frame_length, SD, bytes;
Char *interface= "eth1";;
uint8_t Data[ip_maxpacket];
uint8_t Src_mac[6];
uint8_t dst_mac[6];;
uint8_t Ether_frame[ip_maxpacket];
struct SOCKADDR_LL device;
struct Ifreq IFR;

Submit request for a socket descriptor-to-look up interface.
if (SD = socket (Pf_packet, Sock_raw, htons (Eth_p_all))) < 0) {//The socket was created for the first time to obtain local NIC information
Perror ("socket () failed to get socket descriptor for using IOCTL ()");
Exit (Exit_failure);
}

Use the IOCTL () to look up interface name and get their MAC address.
memset (&AMP;IFR, 0, sizeof (IFR));
snprintf (ifr.ifr_name, sizeof (Ifr.ifr_name), "%s", interface);
if (IOCTL (SD, SIOCGIFHWADDR, &AMP;IFR) < 0) {
Perror ("IOCTL () failed to get source MAC address");
return (exit_failure);
}
Close (SD);

Copy source MAC address.
memcpy (Src_mac, Ifr.ifr_hwaddr.sa_data, 6);

Report source MAC address to stdout.
printf ("MAC address for interface%s is", interface);
for (i=0; i<5; i++) {
printf ("%02x:", Src_mac[i]);
}
printf ("%02x\n", src_mac[5]);

Find interface index from Interface name and store index in
struct SOCKADDR_LL device, which is used as an argument of SendTo ().
memset (&device, 0, sizeof (device));
if ((Device.sll_ifindex = If_nametoindex (interface)) = = 0) {
Perror ("If_nametoindex () failed to obtain interface index");
Exit (Exit_failure);
}
printf ("Index for interface%s is%i\n", interface, Device.sll_ifindex);

Set destination MAC address:you need to fill these out
Dst_mac[0] = 0x10;//set destination NIC address
DST_MAC[1] = 0x78;
DST_MAC[2] = 0xd2;
DST_MAC[3] = 0xc6;
DST_MAC[4] = 0x2f;
DST_MAC[5] = 0x89;

Fill out Sockaddr_ll.
device.sll_family = Af_packet;
memcpy (Device.sll_addr, Src_mac, 6);
Device.sll_halen = htons (6);

Send the data, the length can be arbitrary, but when the packet caught see the minimum data length of 46, which is the Ethernet protocol provisionsEthernet frame Data domain portion minimum of 46 bytes, insufficient self-active 0 processing
Datalen = 12;
Data[0] = ' h ';
DATA[1] = ' e ';
DATA[2] = ' l ';
DATA[3] = ' l ';
Data[4] = ' o ';
DATA[5] = ";
DATA[6] = ' W ';
Data[7] = ' o ';
DATA[8] = ' R ';
DATA[9] = ' l ';
DATA[10] = ' d ';
DATA[11] = '! ';

Fill out Ethernet frame header.
Frame_length = 6 + 6 + 2 + datalen;
Destination and Source MAC addresses
memcpy (Ether_frame, Dst_mac, 6);
memcpy (Ether_frame + 6, Src_mac, 6);

ETHER_FRAME[12] = eth_p_dean/256;
ETHER_FRAME[13] = eth_p_dean% 256;

Data
memcpy (Ether_frame +, data, datalen);

Submit request for a raw socket descriptor.
if (SD = socket (Pf_packet, Sock_raw, htons (Eth_p_all))) < 0) {//Create a true-send socket
Perror ("socket () failed");
Exit (Exit_failure);
}
Send Ethernet frame to socket.
if (bytes = sendto (SD, Ether_frame, Frame_length, 0, (struct sockaddr *) &device, sizeof (device))) <= 0) {
Perror ("SendTo () failed");
Exit (Exit_failure);
}
printf ("Send Num=%d,read num=%d\n", frame_length,bytes);
Close socket Descriptor.
Close (SD);


return (exit_success);
}

Grab bag Get:

watermark/2/text/ahr0cdovl2jsb2cuy3nkbi5uzxqvzgvhbl9nzha=/font/5a6l5l2t/fontsize/400/fill/i0jbqkfcma==/ Dissolve/70/gravity/southeast ">


In the next chapter, we use Dev_add_pack in Linux to add this type of protocol probe.

Thanks to David Buchan's webpage for reference code:

Http://www.pdbuchan.com/rawsock/rawsock.html


Use Pf_packet and Sock_raw to send yourself a defined type Ethernet packet

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.