linux socket 发送ip报文,linux下socket收IP数据包

static int init_socket() { int raw_sockfd_l2 = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP)); struct sockaddr_ll sock_ip_pack; if (raw_sockfd_l2 0) { printf(%s:%d:%s create the l2 raw socket is fail,__FILE__,__LINE__,__func__); return ret;

static int init_socket()

{

int   raw_sockfd_l2 = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP));

struct sockaddr_ll sock_ip_pack;

if (raw_sockfd_l2 < 0)

{

printf("%s:%d:%s create the l2 raw socket is fail",__FILE__,__LINE__,__func__);

return ret;

}

sock_ip_pack.sll_family = AF_PACKET;

sock_ip_pack.sll_ifindex = get_interface_index(raw_sockfd_l2, "eth0");

sock_ip_pack.sll_protocol = htons(ETH_P_IP);

if (bind(raw_sockfd_l2, (struct sockaddr *)(&sock_ip_pack), sizeof(sock_ip_pack)) < 0)

{

CWDebugLog("%s:%d:%s bind is fail",__FILE__,__LINE__,__func__);

return ret;

}

}

static int get_interface_index(int fd, const char *dev_name)

{

struct ifreq ifr;

if (dev_name == NULL)

{

return -1;

}

memset(&ifr, 0, sizeof(ifr));

strcpy(ifr.ifr_name, dev_name);

if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0)

{

printf("get index of ethernet device is fail \n");

return -1;

}

return ifr.ifr_ifindex;

}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个使用 raw socket 发送数据包的示例代码,其中包括了构造 IP 和 TCP 、计算校验和等操作: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <netinet/in.h> #include <netinet/ip.h> #include <netinet/tcp.h> #include <arpa/inet.h> #include <unistd.h> #define SRC_IP "192.168.1.100" #define DST_IP "192.168.1.1" #define SRC_PORT 1234 #define DST_PORT 80 #define DATA "Hello, world!" struct pseudo_header { uint32_t src_addr; uint32_t dst_addr; uint8_t zero; uint8_t protocol; uint16_t len; }; uint16_t checksum(uint16_t *buf, int len) { uint32_t sum = 0; while (len > 1) { sum += *buf++; len -= 2; } if (len == 1) { sum += *(uint8_t *)buf; } sum = (sum >> 16) + (sum & 0xffff); sum += (sum >> 16); return ~sum; } int main() { int sockfd; struct sockaddr_in dst_addr; char packet[4096]; struct iphdr *ip_hdr; struct tcphdr *tcp_hdr; struct pseudo_header phdr; int packet_len; // 创建 raw socket sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_TCP); if (sockfd < 0) { perror("socket"); exit(1); } // 构造目的地址结构体 memset(&dst_addr, 0, sizeof(dst_addr)); dst_addr.sin_family = AF_INET; dst_addr.sin_port = htons(DST_PORT); dst_addr.sin_addr.s_addr = inet_addr(DST_IP); // 构造 TCP tcp_hdr = (struct tcphdr *)(packet + sizeof(struct iphdr)); memset(tcp_hdr, 0, sizeof(struct tcphdr)); tcp_hdr->source = htons(SRC_PORT); tcp_hdr->dest = htons(DST_PORT); tcp_hdr->seq = htonl(1); tcp_hdr->ack_seq = 0; tcp_hdr->doff = 5; tcp_hdr->syn = 1; tcp_hdr->window = htons(65535); tcp_hdr->check = 0; // 构造 IP ip_hdr = (struct iphdr *)packet; memset(ip_hdr, 0, sizeof(struct iphdr)); ip_hdr->version = 4; ip_hdr->ihl = 5; ip_hdr->tot_len = sizeof(struct iphdr) + sizeof(struct tcphdr); ip_hdr->id = htons(0x1234); ip_hdr->ttl = 255; ip_hdr->protocol = IPPROTO_TCP; ip_hdr->saddr = inet_addr(SRC_IP); ip_hdr->daddr = inet_addr(DST_IP); ip_hdr->check = 0; // 计算 TCP 校验和 phdr.src_addr = ip_hdr->saddr; phdr.dst_addr = ip_hdr->daddr; phdr.zero = 0; phdr.protocol = IPPROTO_TCP; phdr.len = htons(sizeof(struct tcphdr)); memcpy(&packet[sizeof(struct iphdr) + sizeof(struct tcphdr)], &phdr, sizeof(struct pseudo_header)); memcpy(&packet[sizeof(struct iphdr) + sizeof(struct tcphdr) + sizeof(struct pseudo_header)], tcp_hdr, sizeof(struct tcphdr)); tcp_hdr->check = checksum((uint16_t *)&packet[sizeof(struct iphdr) + sizeof(struct tcphdr)], sizeof(struct tcphdr) + sizeof(struct pseudo_header)); // 计算 IP 校验和 ip_hdr->check = checksum((uint16_t *)ip_hdr, sizeof(struct iphdr)); // 发送数据包 packet_len = sizeof(struct iphdr) + sizeof(struct tcphdr); if (sendto(sockfd, packet, packet_len, 0, (struct sockaddr *)&dst_addr, sizeof(dst_addr)) < 0) { perror("sendto"); exit(1); } close(sockfd); return 0; } ``` 需要注意的是,在实际使用中需要根据具体的情况修改源地址、目的地址、端口号、数据等字段,同时需要根据具体的操作系统和网络环境进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值