#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#define PACKET_LENGTH 8192
unsigned short csum(unsigned short *buf, int len)
{
unsigned long sum;
for(sum=0; len>0; len--){
sum += *buf++;
}
sum = (sum >> 16) + (sum &0xffff);
sum += (sum >> 16);
return (unsigned short)(~sum);
}
int main(int argc, char *argv[])
{
int sd;
char buffer[PACKET_LENGTH];
struct iphdr *ip = (struct iphdr *) buffer;
struct tcphdr *tcp = (struct tcphdr *) (buffer + sizeof(struct iphdr));
struct sockaddr_in sin, din;
int one = 1;
const int *val = &one;
memset(buffer, '*', PACKET_LENGTH);
if(argc != 5){
printf("- Invalid parameters!!!\n");
exit(-1);
}
sd = socket(PF_INET, SOCK_RAW, IPPROTO_TCP);
if(sd < 0){
perror("socket() error");
exit(-1);
}else{
printf("socket()-SOCK_RAW and tcp protocol is OK.\n");
}
sin.sin_family = AF_INET;
din.sin_family = AF_INET;
sin.sin_port = htons(atoi(argv[2]));
din.sin_port = htons(atoi(argv[4]));
sin.sin_addr.s_addr = inet_addr(argv[1]);
din.sin_addr.s_addr = inet_addr(argv[3]);
ip->ihl = 5;
ip->version = 4;
ip->tos = 16;
ip->tot_len = sizeof(struct iphdr) + sizeof(struct tcphdr)+200;
ip->id = htons(54321);
ip->frag_off = 0;
ip->ttl = 64;
ip->protocol = 6; // TCP
ip->check = 0; // Done by kernel
ip->saddr = inet_addr(argv[1]);
ip->daddr = inet_addr(argv[3]);
tcp->source = htons(atoi(argv[2]));
tcp->dest = htons(atoi(argv[4]));
tcp->seq = htonl(100);
tcp->ack_seq = 0;
tcp->syn = 0;
tcp->ack = 0;
tcp->window = htons(32767);
tcp->check = 0; // Done by kernel
tcp->urg_ptr = 0;
ip->check = csum((unsigned short *) buffer, (sizeof(struct iphdr) + sizeof(struct tcphdr)));
//告诉kernel packet中包含headers,常规编写客户端代码时,要使用connect函数,connect函数的作用就是实现与server端的三次握手,建立通信,所以在此处我们不调用connect
if(setsockopt(sd, IPPROTO_IP, IP_HDRINCL, val, sizeof(one)) < 0){
perror("setsockopt() error");
exit(-1);
}else{
printf("setsockopt() is OK\n");
}
printf("Using :Source IP: %s port: %u, Target IP: %s port: %u.\n", argv[1], atoi(argv[2]), argv[3], atoi(argv[4]));
unsigned int count;
while(1){
if(sendto(sd, buffer, ip->tot_len, 0, (struct sockaddr *)&sin, sizeof(sin)) < 0){
perror("sendto() error");
exit(-1);
}else{
printf("sendto() is OK\n");
}
sleep(2);
}
close(sd);
return 0;
}
=======================================================================================
./test 192.168.0.123 23 192.168.31.129 8008
============================================================================================================================================
接收端代码
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <linux/in.h>
#include <linux/if_ether.h>
#include <net/if.h>
#include <sys/ioctl.h>
int main(int argc, char **argv) {
int sock, n;
char buffer[2048];
unsigned char *iphead, *ethhead;
struct ifreq ethreq;
if ( (sock=socket(PF_PACKET, SOCK_RAW,
htons(ETH_P_IP)))<0) {
perror("socket");
exit(1);
}
#if 0
/* Set the network card in promiscuos mode */
strncpy(ethreq.ifr_name,"eth0",IFNAMSIZ);
if (ioctl(sock,SIOCGIFFLAGS,?req)==-1) {
perror("ioctl");
close(sock);
exit(1);
}
ethreq.ifr_flags|=IFF_PROMISC;
if (ioctl(sock,SIOCSIFFLAGS,?req)==-1) {
perror("ioctl");
close(sock);
exit(1);
}
#endif
while (1) {
printf("----------\n");
n = recvfrom(sock,buffer,2048,0,NULL,NULL);
printf("%d bytes read\n",n);
/* Check to see if the packet contains at least
* complete Ethernet (14), IP (20) and TCP/UDP
* (8) headers.
*/
if (n<42) {
perror("recvfrom():");
printf("Incomplete packet (errno is %d)\n",
errno);
close(sock);
exit(0);
}
ethhead = buffer;
printf("Source MAC address: "
"%02x:%02x:%02x:%02x:%02x:%02x\n",
ethhead[0],ethhead[1],ethhead[2],
ethhead[3],ethhead[4],ethhead[5]);
printf("Destination MAC address: "
"%02x:%02x:%02x:%02x:%02x:%02x\n",
ethhead[6],ethhead[7],ethhead[8],
ethhead[9],ethhead[10],ethhead[11]);
iphead = buffer+14; /* Skip Ethernet header */
if (*iphead==0x45) { /* Double check for IPv4
* and no options present */
printf("Source host %d.%d.%d.%d\n",
iphead[12],iphead[13],
iphead[14],iphead[15]);
printf("Dest host %d.%d.%d.%d\n",
iphead[16],iphead[17],
iphead[18],iphead[19]);
printf("Source,Dest ports %d,%d\n",
(iphead[20]<<8)+iphead[21],
(iphead[22]<<8)+iphead[23]);
printf("Layer-4 protocol %d\n",iphead[9]);
}
}
}
================================================================================
结果:
254 bytes read
Source MAC address: 00:0c:29:5d:22:49
Destination MAC address: 00:50:56:f5:14:fa
Source host 192.168.0.123
Dest host 192.168.31.129
Source,Dest ports 23,1234
Layer-4 protocol 6