一、sendto函数
sendto(sock_raw_fd, msg, msg_len, 0, (struct sockaddr*)&sll, sizeof(sll));
注意:
1、sock_raw_fd:原始套接字
2、msg:发送的消息(封装好的数字协议)
3、sll:本机网络接口,值发送的数据应该从本机的哪个网卡出去,而不是以前的目的地址
原始套接字:组帧数据报文—>设置从本机的哪块网卡sendto发出去
二、步骤
①本地接口结构体
头文件:#include <netpacket/packet.h>
存放地址的结构体:
只需要对sll.sll_ifindex赋值就可以了。
sll.sll_ifindex=本地接口; //关键就是本地接口如何获得
sendto(sock_raw_fd, msg, msg_len, 0, (struct sockaddr*)&sll, sizeof(sll));
②获取本地接口并发送
通过ioctl来获取网络接口地址
头文件:
#include <sys/ioctl.h>
struct ifreq的头文件:
#include <net/if.h>
IFNAMSIZ 16
函数:int ioctl (int fd, int request, void *);
fd:原始套接字
request:请求
void *:存放某个地址结构
ioctl获取接口示例:
struct ifreq ethreq; //网络接口地址
strncpy(ethreq.ifr_name, "eth0", IFNAMSIZ); //指定网卡名称
if( ioctl(sock_raw_fd, SIOCGIFINDEX,ðreq) == -1)
{
perror("ioctl");
close(sock_raw_fd);
exit(-1);
}
struct sockaddr_ll sll;
bzero(&sll, sizeof(sll));
sll.sll_ifindex = ethreq.ifr_ifindex; //给sll赋值
int len = sendto(sock_raw_fd, msg, sizeof(msg), 0, (struct sockaddr *)&sll, sizeof(sll));
ioctl参数对照表:
三、测试demo(ARP扫描当前局域网某一IP的MAC地址)
概述:扫描MAC地址
1、ARP概述
①是TCP/IP协议族中的一个
②主要用于查询IP所对应的MAC
③请求方使用广播来发送请求
④应答方使用单播来回送数据
⑤为了在发送数据的时候提高效率,在计算中会有一个ARP缓存表,用来暂时存放IP所对应的MAC,在LINUX中使用ARP即可查看,在xp中使用ARP -a
代码:
①扫描当前局域网某一IP的MAC地址
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/ether.h>
#include <pthread.h>
#include <arpa/inet.h>
#include <sys/ioctl.h> //ioctl头文件
#include <net/if.h> //struct ifreq头文件
#include <netpacket/packet.h> //struct sockaddr_ll头文件
#include <unistd.h> //_exit头文件
/*
参数说明:
sockfd:原始套接字
out:指定的网卡名称
msg:发送的消息(封装好的数字协议)
msg_len:长度
*/
void my_sendto(int sockfd, char *out, unsigned char *msg, int msg_len)
{
//通过ioctl得到网络接口
struct ifreq ethreq;
strncpy(ethreq.ifr_name, <