使用原始套接字发送udp数据包,从传输层封包到链路层(mac头+ip头+udp头)。udp数据包,从传输层封包到链路层(mac头+ip头+udp头)。

head.h文件如下:

#ifndef _HEAD_H
#define _HEAD_H    #define BUFFER_MAX 2048
#define PCKT_LEN 8492#pragma pack (1)
//ethernet head 14 bytes
struct ether
{char dmac[6];char smac[6];char eth_typ_len[2];
};//ip head 20 bytes
struct ipheader {unsigned char      iplv;//iph_ihl:5, iph_ver:4;unsigned char      iph_tos;unsigned short int iph_len;unsigned short int iph_ident;// unsigned uint8_t      iph_flag;unsigned short int iph_offset;//16bit include flag and offsetunsigned char      iph_ttl;unsigned char      iph_protocol;unsigned short int iph_chksum;unsigned int       iph_sourceip;unsigned int       iph_destip;};//udp head 8 bytes
struct udpheader {unsigned short int udph_srcport;unsigned short int udph_destport;unsigned short int udph_len;unsigned short int udph_chksum;};//tcp head 20bytes
struct tcphdr
{unsigned short int source;  unsigned short int dest;   unsigned int seq;  unsigned int ack_seq; unsigned short int tcp_len;
#if 0unsigned short int doff:4;unsigned short int res1:4;unsigned short int res2:2;unsigned short int urg:1;unsigned short int ack:1;unsigned short int psh:1;unsigned short int rst:1;unsigned short int syn:1;unsigned short int fin:1;
#endifunsigned short int window;  unsigned short int check;  unsigned short int urg_prt;
};#pragma pack ()#endif

raw_udp.c文件如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <linux/in.h>
#include "head.h"//caculate ip checksum
unsigned short int ip_csum (unsigned short int *addr, int len)
{int nleft = len;int sum = 0;unsigned short int *w = addr;unsigned short int answer = 0; while (nleft > 1) {sum += *w++;nleft -= sizeof (unsigned short int);}if (nleft == 1) {*(char *) (&answer) = *(char *) w;sum += answer;}sum = (sum >> 16) + (sum & 0xFFFF);sum += (sum >> 16);answer = ~sum;return (answer);
}#if 1
//caculate udp checksum (include payload)
unsigned short int udp_csum (struct ipheader iphdr, struct udpheader udphdr, unsigned char *payload, int payloadlen)
{char buf[65535];char *ptr;int chksumlen = 0;int i;ptr = &buf[0];  // ptr points to beginning of buffer buf/****************pseudo header  12byte*********************************/// Copy source IP address into buf (32 bits)memcpy (ptr, &iphdr.iph_sourceip, sizeof (iphdr.iph_sourceip));ptr += sizeof (iphdr.iph_sourceip);chksumlen += sizeof (iphdr.iph_sourceip);// Copy destination IP address into buf (32 bits)memcpy (ptr, &iphdr.iph_destip, sizeof (iphdr.iph_destip));ptr += sizeof (iphdr.iph_destip);chksumlen += sizeof (iphdr.iph_destip);// Copy zero field to buf (8 bits)*ptr = 0; ptr++;chksumlen += 1;// Copy transport layer protocol to buf (8 bits)memcpy (ptr, &iphdr.iph_protocol, sizeof (iphdr.iph_protocol));ptr += sizeof (iphdr.iph_protocol);chksumlen += sizeof (iphdr.iph_protocol);// Copy UDP length to buf (16 bits)memcpy (ptr, &udphdr.udph_len, sizeof (udphdr.udph_len));ptr += sizeof (udphdr.udph_len);chksumlen += sizeof (udphdr.udph_len);/*******************end pseudo header*************************/// Copy UDP source port to buf (16 bits)memcpy (ptr, &udphdr.udph_srcport, sizeof (udphdr.udph_srcport));ptr += sizeof (udphdr.udph_srcport);chksumlen += sizeof (udphdr.udph_srcport);// Copy UDP destination port to buf (16 bits)memcpy (ptr, &udphdr.udph_destport, sizeof (udphdr.udph_destport));ptr += sizeof (udphdr.udph_destport);chksumlen += sizeof (udphdr.udph_destport);// Copy UDP length again to buf (16 bits)memcpy (ptr, &udphdr.udph_len, sizeof (udphdr.udph_len));ptr += sizeof (udphdr.udph_len);chksumlen += sizeof (udphdr.udph_len);// Copy UDP checksum to buf (16 bits)// Zero, since we don't know it yet*ptr = 0; ptr++;*ptr = 0; ptr++;chksumlen += 2;// Copy payload to bufmemcpy (ptr, payload, payloadlen);ptr += payloadlen;chksumlen += payloadlen;// Pad to the next 16-bit boundaryfor (i=0; i<payloadlen%2; i++, ptr++) {*ptr = 0;ptr++;chksumlen++;}return ip_csum ((unsigned short int *) buf, chksumlen);
}
#endifint main(int argc, char *argv[])
{struct sockaddr_ll device;int sd;char buffer[1024] = {0};struct ether *eth = (struct ether *)malloc(sizeof(struct ether));struct ipheader *ip = (struct ipheader *)malloc(sizeof(struct ipheader));struct udpheader *udp = (struct udpheader *)malloc(sizeof(struct udpheader));//struct tcphdr   *tcph = (struct tcphdr *)malloc(sizeof(struct tcphdr)); if(argc != 5){printf("- Invalid parameters!!!\n");printf("- Usage %s<source hostname/IP> <source port> <target hostname/IP> <target port>\n", argv[0]);exit(-1);}/*****************fill udp header*********************************///udp payloadchar data[9] = {'1','2','3','4','5','6','7','8','9'};//udp headerudp->udph_srcport = htons(atoi(argv[2]));udp->udph_destport = htons(atoi(argv[4]));udp->udph_len = htons(sizeof(struct udpheader)+sizeof(data));udp->udph_chksum =udp_csum(*ip,*udp,data,sizeof(data));//options/*******************end fill udp header**************************/#if 0/********************fill tcp header*************************/tcph->source = htons(6666);tcph->dest = htons(6666);tcph->seq = random();tcph->ack_seq = 0;tcph->tcp_len = 0x0250;#if 0tcph->res1 = 0;tcph->res2 = 0;tcph->urg = 0;tcph->ack = 0;tcph->psh = 0;tcph->rst = 0;tcph->syn = 0;tcph->fin = 0;#endiftcph->window = htons(20480);tcph->check = 0;//caculate chksum and fill ittcph->urg_prt = 0;/*****************end fill tcp header**************************/
#endif  /********************fill ip header****************************///fill ip header (20 bytes)ip->iplv = 1<<6 | 5;//version v4 or v6 and head_len 5 //ip首部长度以32bit为单位计算ip->iph_tos = 0; // Low delayip->iph_len = htons(sizeof(struct ipheader) + sizeof(struct udpheader) +sizeof(data));ip->iph_ident = 0;//标示字段 唯一标示一个数据包ip->iph_offset = 0x0040;//16bit include offset and flagip->iph_ttl = 64; // time to liveip->iph_protocol = 17; // UDP// Source IP address, can use spoofed address here!!!ip->iph_sourceip = inet_addr(argv[1]);// The destination IP addressip->iph_destip = inet_addr(argv[3]);// Calculate the checksum for integrityip->iph_chksum = ip_csum((unsigned short int *)ip, (int)sizeof(struct ipheader));/******************end fill ip header**********************//********************fill eth header*********************///  Fill the eth header (14bytes)eth->smac[0] = 0x88;eth->smac[1] = 0x78;eth->smac[2] = 0x56;eth->smac[3] = 0x8c;eth->smac[4] = 0x58;eth->smac[5] = 0x0c;eth->dmac[0] = 0xFF;eth->dmac[1] = 0xFF;eth->dmac[2] = 0xFF;eth->dmac[3] = 0xFF;eth->dmac[4] = 0xFF;eth->dmac[5] = 0xFF;eth->eth_typ_len[0] = 0x08;eth->eth_typ_len[1] = 0x00;/***********************end fill eth header*****************/memcpy(buffer,eth,sizeof(struct ether));memcpy(buffer + sizeof(struct ether),ip,sizeof(struct ipheader));memcpy(buffer + sizeof(struct ether) + sizeof(struct ipheader),udp,sizeof(struct udpheader) );memcpy(buffer + sizeof(struct ether) + sizeof(struct ipheader) + sizeof(struct udpheader),data,sizeof(data));/*************************fill sockaddr_ll***********************//*利用原始套接字发送数据,那么发送的时候需要自己组织整个以太网数据帧.所有相关的地址使用struct sockaddr_ll 而不是struct sockaddr_in(因为协议簇是PF_PACKET不是AF_INET了),比如发送给某个机器,对方的地址需要使用struct sockaddr_ll.*/memset(&device,0,sizeof(device));if((device.sll_ifindex = if_nametoindex("eth0")) == 0){printf("if_nametoindex() failed to obtain interface index\n");exit(EXIT_FAILURE);}printf("index of interface eth0 is %i\n",device.sll_ifindex);device.sll_family = AF_PACKET;memcpy(device.sll_addr,eth->dmac,6);device.sll_halen = htons(6);/******************end fill sockaddr_ll***************************/// Create a raw socket with UDP protocolif((sd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0){printf("create SOCK_RAW socket error\n");exit(-1);}else{printf("create SOCK_RAW socket OK.\n");}while(1){//send udp packetif(sendto(sd, (void *)buffer,sizeof(struct ether)+sizeof(struct ipheader)+sizeof(struct udpheader)+sizeof(data), 0, (struct sockaddr *)&device, sizeof(device)) < 0){perror("sendto() error");exit(-1);}else{printf("sendto() is OK.\n");sleep(1);}}close(sd);return 0;
}
</pre><pre code_snippet_id="1587206" snippet_file_name="blog_20160224_4_7307801" name="code" class="cpp" style="font-size:18px;">
gcc raw_udp.c生成a.out文件,执行抓包如下:生成a.out文件,执行抓包如下:


原始套接字SOCK_RAW发送UDP数据包相关推荐

  1. linux原始套接字抓取网络数据包

    基于linux的抓包 一.获取数据     当我们在做网络安全或者数据探测等工作经常会用到抓包.熟悉的工具有tcpdump.wireshark等,这里我们介绍如何使用C程序原始套接字在linux系统上 ...

  2. 使用原始套接字Raw Socket实现数据包嗅探

    背景 网络上随时都流通了大量的数据包,我们要想实现抓包并分析,实现思路思路大概是:在合适的时候捕获数据包,保存到缓冲区,作为备用:然后,按照一定的结构和格式去读取缓冲区的内容.由于各种公开的网络协议是 ...

  3. 【Linux网络编程】原始套接字实例:发送 UDP 数据包

    以太网报文格式: 详细的说明,请看<MAC 头部报文分析>. IP 报文格式: 详细的说明,请看<IP 数据报格式详解>. UDP 报文格式: 详细的说明,请看<UDP ...

  4. linux串口编程实例_Linux 网络编程——原始套接字实例:发送 UDP 数据包

    以太网报文格式: IP 报文格式: UDP 报文格式: 校验和函数: /*******************************************************功能:校验和函数参 ...

  5. 原始套接字SOCK_RAW

    实际上,我们常用的网络编程都是在应用层的报文的收发操作,也就是大多数程序员接触到的流式套接字(SOCK_STREAM)和数据包式套接字(SOCK_DGRAM).而这些数据包都是由系统提供的协议栈实现, ...

  6. qt定时连续发送udp数据包_TCP和UDP

    首先强调一点,TCP/IP协议是一个协议簇.里面包括很多协议的,UDP只是其中的一个, 之所以命名为TCP/IP协议,因为TCP.IP协议是两个很重要的协议,就用他两命名了. 两个协议的区别实际使用时 ...

  7. linux send 失败_求助:sendto()发送UDP数据包失败:message too long该如何解决?

    求助:sendto()发送UDP数据包失败:message too long该如何解决? 发布时间:2012-03-24 23:17:25来源:红联作者:zhl2001xlh800 我想使用sendt ...

  8. 原始套接字-SOCK_RAW

    原始套接字 简介 套接口最常用的两种类型:SOCK_STREAM和SOCK_DGRAM. SOCK_STREAM: 流式套接口,传输的是字节流,每次传输的数据没有边界,它是面向连接的,底层使用TCP协 ...

  9. 数据包收发c语言程序,使用C在套接字编程中创建数据包以及发送和接收数据包的正确方法...

    指针pkt未在您的应用程序中定义.您有两种选择: 1)将pkt声明为正常变量 struct packet pkt; pkt.srcID = 01; .... send(sockfd, &pkt ...

最新文章

  1. linux top 看硬盘读写,linux iotop 安装使用教程(显示硬盘IO读写情况)
  2. 感知算法论文(六):LEDNet(2019)
  3. 大家都在说的分布式系统到底是什么
  4. 做po_requisitions_interface_all接口开发问题
  5. xshell怎么让程序后台运行_使程序在Linux下后台运行
  6. mysql alter更新_MySQL 操作命令梳理(2)-alter(update、insert)
  7. c语言做一个抽奖小程序,小程序插件使用- 抽奖助手
  8. Eclipse中自动提示的参数变成arg0,arg1...的解决方法
  9. try catch对异常进行输出到日志、_spring Boot手把手教学(7): 抛弃try-catch, 如何优雅统一处理异常(含404)...
  10. jquery的autocomplete在firefox下不支持中文输入法的bug
  11. POJ 1398 Complete the sequence! ★ (差分)
  12. nginx 内置变量大全
  13. endnotex9安装后使用方法_endnotex9使用教程
  14. luogu P3332 [ZJOI2013]K大数查询
  15. 清除HTML的超链接样式,Markdown导出HTML,删除超链接下划线和字体样式
  16. WORD之文字处理之页眉页脚的设置
  17. 玩转MAC OS!实测DIY兼容机装苹果系统
  18. 大面积无线网络覆盖5大方案,满足不同场所的实际需求
  19. IIR数字低通滤波器
  20. 奶茶妹妹章泽天加入微软Bing团队

热门文章

  1. C++深度解析 类中的函数重载 -- 全局函数,普通成员函数,静态成员函数(28)
  2. 关于 Android studio你的主机中的软件中止了一个已建立的连接 Gradle build failed with 1 error(s) in 3 s 487 ms
  3. 《汉字知多少》开发志(一)
  4. Pytorch框架之tensor的gpu状态查看以及设备号
  5. HxD(十六进制编码处理工具) 1.7中文版
  6. Python基础算法:排序、查找、二叉树
  7. Linux内存分配--实现FF、BF、WF分配算法
  8. NI Measurement Studio 2013中waveformPlot控件的使用
  9. Python修改镜像原命令
  10. 最新字节跳动面试题与答案: 无序数组的中位数 (快排思想O(N) 时间复杂度)