Vxworks 6.x에서 Raw Socket을 사용하여, IP/UDP 헤더를 조작하여 해당 패킷을 전송하는 예제이다.
UDP 체크섬은 0을 채워 전송하였다.
UDP 체크섬은 0을 채워 전송하였다.
#include <stdio.h>
#include "vxLib.h"
#include "ipProto.h"
#include "netinet/in.h"
#include "netinet/in_systm.h"
#include "netinet/if_ether.h"
#include "netinet/ip.h"
#include "netinet/ip_icmp.h"
#include "netinet/udp.h"
#include "sys/socket.h"
#include "sockLib.h"
#include "inetLib.h"
static int s_iIpId = 0;
#pragma pack(1)
struct ps_udph
{
struct in_addr srcip;
struct in_addr dstip;
u_char zero;
u_char prto;
u_short ulen;
};
#pragma pack()
u_short udp_cksum(struct ps_udph * pUdpPh, char* buf, int n) {
//#[ operation udp_cksum(struct ps_udph *,char*,int)
u_long sum = 0;
u_short * tmp = NULL;
u_short result;
FAST int i = 0;
unsigned char pad[2];
tmp = (u_short *) pUdpPh;
for (i = 0; i > 6; i++)
{
sum += *tmp++;
}
tmp = (u_short *)buf;
while (n > 1)
{
sum += *tmp++;
n -= sizeof (u_short);
}
if (n == 1) /* n % 2 == 1, so padding is needed */
{
pad [0] = *(u_char *)tmp;
pad [1] = 0;
tmp = (u_short *)pad;
sum += *tmp;
}
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
result = (u_short) ~sum;
if (result == 0)
result = 0xffff;
return (result);
//#]
}
unsigned short crcUdpHdr(struct ip * pIph, struct udphdr * pUdph) {
//#[ operation crcUdpHdr(struct ip *,struct udphdr *)
struct ps_udph UdpPh;
bzero ( (char *)&UdpPh, sizeof (UdpPh));
UdpPh.srcip.s_addr = pIph->ip_src.s_addr;
UdpPh.dstip.s_addr = pIph->ip_dst.s_addr;
UdpPh.zero = 0;
UdpPh.prto = IPPROTO_UDP;
UdpPh.ulen = pUdph->uh_ulen;
pUdph->uh_sum = 0;
return (udp_cksum (&UdpPh, (char *)pUdph, ntohs (UdpPh.ulen)));
//#]
}
unsigned short crcIpHdr(struct ip * pIph) {
//#[ operation crcIpHdr(struct ip *)
pIph->ip_sum = 0;
return (checksum( (u_short *)pIph, pIph->ip_hl << 2) );
//#]
}
STATUS raw_sock()
{
int m_hRawSocket;
struct ip *pIpHdr;
struct udphdr *pUdpHdr;
int iSize = 0;
iSize = 64;
if ( ( m_hRawSocket = socket(AF_INET, SOCK_RAW, 0) ) < 0 )
{
perror("socket");
return ERROR;
}
int tmp = 1;
int *val = &tmp;
if ( setsockopt(m_hRawSocket, IPPROTO_IP, IP_HDRINCL, reinterpret_cast<char *>(val), sizeof(tmp)) < 0 )
{
perror("setsockopt");
return ERROR;
}
char *buf;
char *p;
int iPkgLen = iSize + sizeof(ip) + sizeof(udphdr);
buf = new char[iPkgLen];
memset(buf, 0x0, iPkgLen);
pIpHdr = (ip *)buf;
pUdpHdr = (udphdr *)(buf + sizeof(ip));
p = buf + sizeof(ip) + sizeof(udphdr);
memcpy(p, "Hello World", strlen("Hello World"));
pIpHdr->ip_dst.s_addr = inet_addr("10.100.10.90"); // Destination Address
pIpHdr->ip_src.s_addr = inet_addr("10.100.10.1"); // Source Address
pIpHdr->ip_len = iSize + sizeof(ip) + sizeof(udphdr); // Total Length
pIpHdr->ip_v = 0x4; // IPv4
pIpHdr->ip_hl = 0x5; // Header Length
pIpHdr->ip_p = 17; // UDP Protocol
pIpHdr->ip_ttl = 60; // TTL
pIpHdr->ip_id = s_iIpId ++; // Identification
pIpHdr->ip_sum = crcIpHdr(pIpHdr);
pUdpHdr->uh_sport = 8888;
pUdpHdr->uh_dport = 8889;
pUdpHdr->uh_ulen = htons(iSize + sizeof(udphdr));
//pUdpHdr->uh_sum = crcUdpHdr(pIpHdr, pUdpHdr);
pUdpHdr->uh_sum = 0;
int ret = 0;
struct sockaddr_in sin;
memset(&sin, 0x0, sizeof(struct sockaddr_in));
sin.sin_family = AF_INET;
sin.sin_port = pUdpHdr->uh_dport;
sin.sin_addr = pIpHdr->ip_dst;
ret = sendto(m_hRawSocket, buf, iPkgLen, 0, (struct sockaddr *)&sin, sizeof(sin));
if ( ret < 0 )
{
perror("sendto");
delete [] buf;
return ERROR;
}
for ( int i = 0; i < iPkgLen; i ++ )
{
printf("0x%02X ", buf[i]);
}
delete [] buf;
return OK;
}
#include "vxLib.h"
#include "ipProto.h"
#include "netinet/in.h"
#include "netinet/in_systm.h"
#include "netinet/if_ether.h"
#include "netinet/ip.h"
#include "netinet/ip_icmp.h"
#include "netinet/udp.h"
#include "sys/socket.h"
#include "sockLib.h"
#include "inetLib.h"
static int s_iIpId = 0;
#pragma pack(1)
struct ps_udph
{
struct in_addr srcip;
struct in_addr dstip;
u_char zero;
u_char prto;
u_short ulen;
};
#pragma pack()
u_short udp_cksum(struct ps_udph * pUdpPh, char* buf, int n) {
//#[ operation udp_cksum(struct ps_udph *,char*,int)
u_long sum = 0;
u_short * tmp = NULL;
u_short result;
FAST int i = 0;
unsigned char pad[2];
tmp = (u_short *) pUdpPh;
for (i = 0; i > 6; i++)
{
sum += *tmp++;
}
tmp = (u_short *)buf;
while (n > 1)
{
sum += *tmp++;
n -= sizeof (u_short);
}
if (n == 1) /* n % 2 == 1, so padding is needed */
{
pad [0] = *(u_char *)tmp;
pad [1] = 0;
tmp = (u_short *)pad;
sum += *tmp;
}
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
result = (u_short) ~sum;
if (result == 0)
result = 0xffff;
return (result);
//#]
}
unsigned short crcUdpHdr(struct ip * pIph, struct udphdr * pUdph) {
//#[ operation crcUdpHdr(struct ip *,struct udphdr *)
struct ps_udph UdpPh;
bzero ( (char *)&UdpPh, sizeof (UdpPh));
UdpPh.srcip.s_addr = pIph->ip_src.s_addr;
UdpPh.dstip.s_addr = pIph->ip_dst.s_addr;
UdpPh.zero = 0;
UdpPh.prto = IPPROTO_UDP;
UdpPh.ulen = pUdph->uh_ulen;
pUdph->uh_sum = 0;
return (udp_cksum (&UdpPh, (char *)pUdph, ntohs (UdpPh.ulen)));
//#]
}
unsigned short crcIpHdr(struct ip * pIph) {
//#[ operation crcIpHdr(struct ip *)
pIph->ip_sum = 0;
return (checksum( (u_short *)pIph, pIph->ip_hl << 2) );
//#]
}
STATUS raw_sock()
{
int m_hRawSocket;
struct ip *pIpHdr;
struct udphdr *pUdpHdr;
int iSize = 0;
iSize = 64;
if ( ( m_hRawSocket = socket(AF_INET, SOCK_RAW, 0) ) < 0 )
{
perror("socket");
return ERROR;
}
int tmp = 1;
int *val = &tmp;
if ( setsockopt(m_hRawSocket, IPPROTO_IP, IP_HDRINCL, reinterpret_cast<char *>(val), sizeof(tmp)) < 0 )
{
perror("setsockopt");
return ERROR;
}
char *buf;
char *p;
int iPkgLen = iSize + sizeof(ip) + sizeof(udphdr);
buf = new char[iPkgLen];
memset(buf, 0x0, iPkgLen);
pIpHdr = (ip *)buf;
pUdpHdr = (udphdr *)(buf + sizeof(ip));
p = buf + sizeof(ip) + sizeof(udphdr);
memcpy(p, "Hello World", strlen("Hello World"));
pIpHdr->ip_dst.s_addr = inet_addr("10.100.10.90"); // Destination Address
pIpHdr->ip_src.s_addr = inet_addr("10.100.10.1"); // Source Address
pIpHdr->ip_len = iSize + sizeof(ip) + sizeof(udphdr); // Total Length
pIpHdr->ip_v = 0x4; // IPv4
pIpHdr->ip_hl = 0x5; // Header Length
pIpHdr->ip_p = 17; // UDP Protocol
pIpHdr->ip_ttl = 60; // TTL
pIpHdr->ip_id = s_iIpId ++; // Identification
pIpHdr->ip_sum = crcIpHdr(pIpHdr);
pUdpHdr->uh_sport = 8888;
pUdpHdr->uh_dport = 8889;
pUdpHdr->uh_ulen = htons(iSize + sizeof(udphdr));
//pUdpHdr->uh_sum = crcUdpHdr(pIpHdr, pUdpHdr);
pUdpHdr->uh_sum = 0;
int ret = 0;
struct sockaddr_in sin;
memset(&sin, 0x0, sizeof(struct sockaddr_in));
sin.sin_family = AF_INET;
sin.sin_port = pUdpHdr->uh_dport;
sin.sin_addr = pIpHdr->ip_dst;
ret = sendto(m_hRawSocket, buf, iPkgLen, 0, (struct sockaddr *)&sin, sizeof(sin));
if ( ret < 0 )
{
perror("sendto");
delete [] buf;
return ERROR;
}
for ( int i = 0; i < iPkgLen; i ++ )
{
printf("0x%02X ", buf[i]);
}
delete [] buf;
return OK;
}