分类:
2008-10-15 16:40:51
经常的有人问原始套节口的问题。如何的checksum如何的发送接受,如何的支持tcp和udp等。
为了较少以后回答这个问题的频率。偶整理了一个完整的代码,包含tcp、udp和ip层如何操作。下面分别给出,希望对大家有所帮助。
rawsock_utils.h
[code:1:4fc8f1a596]
extern void tcp_gen(char *packet,unsigned short sport,
unsigned short dport,unsigned long seq,
unsigned long ack);
extern void udp_gen(char *packet,unsigned short sport,
unsigned short dport,unsigned short length);
extern void ip_gen(char *packet,unsigned char protocol,struct in_addr saddr,
struct in_addr daddr,unsigned short length);
extern unsigned short trans_check(unsigned char proto,
char *packet,
int length,
struct in_addr source_address,
struct in_addr dest_address);
[/code:1:4fc8f1a596]
checksum.h
[code:1:4fc8f1a596]
unsigned short in_cksum(unsigned short *addr,int len);
[/code:1:4fc8f1a596]
tcp.c
[code:1:4fc8f1a596]
#include
#include
#include
#include
#include
#include
#include
#if defined(LINUX)
#include
#include
#else
#include
#include
#endif
#include
#include
#include
#include
int main(int argc,char *argv[])
{
unsigned char packet[
#if !defined(LINUX)
sizeof(struct ip) +
#else /* LINUX */
sizeof(struct iphdr) +
#endif /* LINUX */
sizeof(struct tcphdr)];
struct sockaddr_in mysocket;
unsigned short sport, dport;
struct in_addr saddr, daddr;
struct tcphdr *tcp;
unsigned long seq, ack;
int sockd, on = 1;
if(argc < 5) {
fprintf(stderr,"usage: %s source_port source_address dest_port dest_address\n",
argv[0]);
exit(1);
}
sport = (unsigned short)atoi(argv[1]);
saddr.s_addr = inet_addr(argv[2]);
dport = (unsigned short)atoi(argv[3]);
daddr.s_addr = inet_addr(argv[4]);
if((sockd = socket(AF_INET,SOCK_RAW,IPPROTO_RAW)) < 0) {
perror("socket");
exit(1);
}
if(setsockopt(sockd,IPPROTO_IP,IP_HDRINCL,(char *)&on,sizeof(on)) < 0) {
perror("setsockopt");
exit(1);
}
/* Very bad random sequence number generator */
srand(getpid());
seq = rand()%time(NULL);
ack = rand()%time(NULL);
ip_gen(packet,IPPROTO_TCP,saddr,daddr,sizeof(packet));
#if !defined(LINUX)
tcp = (struct tcphdr *)(packet + sizeof(struct ip));
tcp_gen((char *)tcp,sport,dport,seq,ack);
#if !defined(SOLARIS_CKSUM_BUG)
tcp->th_sum = trans_check(IPPROTO_TCP,(char *)tcp,
sizeof(struct tcphdr),
saddr,
daddr);
#else /* SOLARIS_CKSUM_BUG */
tcp->th_sum = sizeof(struct tcphdr);
#endif /* SOLARIS_CKSUM_BUG */
#else /* LINUX */
tcp = (struct tcphdr *)(packet + sizeof(struct iphdr));
tcp_gen((char *)tcp,sport,dport,seq,ack);
#if !defined(SOLARIS_CKSUM_BUG)
tcp->check = trans_check(IPPROTO_TCP,(char *)tcp,
sizeof(struct tcphdr),
saddr,
daddr);
#else /* SOLARIS_CKSUM_BUG */
tcp->check = sizeof(struct tcphdr);
#endif /* SOLARIS_CKSUM_BUG */
#endif /* LINUX */
memset(&mysocket,'\0',sizeof(mysocket));
mysocket.sin_family = AF_INET;
mysocket.sin_port = htons(dport);
mysocket.sin_addr = daddr;
if(sendto(sockd,&packet,sizeof(packet),0x0,(struct sockaddr *)&mysocket,
sizeof(mysocket)) != sizeof(packet)) {
perror("sendto");
exit(1);
}
exit(0);
}
[/code:1:4fc8f1a596]
tcp_gen.c
[code:1:4fc8f1a596]
#include
#include
#include
#include
#include
#include
#include
#if defined(LINUX)
#include
#else
#include
#endif
#include
#include
#if defined(X2_OFF) /* SCO */
#define TH_OFFSET 0x50 /* TCP header offset */
#else
#define TH_OFFSET 5
#endif
#define TCP_WINDOW_SIZE 512 /* Just have it hardcoded. */
void tcp_gen(char *packet,unsigned short sport,
unsigned short dport,unsigned long seq,
unsigned long ack)
{
struct tcphdr *tcp;
tcp = (struct tcphdr *)packet;
memset((char *)tcp,'\0',sizeof(struct tcphdr));
[1]