/*
* ping.c
*
* An ping example. I have used some iputils code
* you can get the iputils source here: http://www.skbuff.net/iputils/
*
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netdb.h>
#include <netinet/ip_icmp.h>
#define pexit(s) ({perror(s); exit(EXIT_FAILURE);})
u_short in_cksum(const u_short *addr, register int len, u_short csum);
void print_icmphdr(struct icmphdr *);
void print_iphdr(struct iphdr *);
int main(int argc, char **argv)
{
int sock;
int len;
int bytes;
int count = -1;
u_short cksum;
u_int16_t seq;
struct sockaddr_in dst_addr;
struct sockaddr_in rcv_addr;
struct hostent *dst_host;
#define BUFLEN 1000000
char outpack[BUFLEN];
struct icmphdr *icp;
struct iphdr *ip;
if (argc <= 1) {
printf("Usage: %s HOST [COUNT]");
exit(EXIT_FAILURE);
}
sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if (sock == -1)
pexit("socket");
dst_host = gethostbyname(argv[1]);
if (!dst_host) {
errno = h_errno;
pexit("gethostbyname");
}
memcpy(&dst_addr.sin_addr.s_addr, dst_host->h_addr_list[0],
sizeof(dst_addr));
dst_addr.sin_family = PF_INET;
dst_addr.sin_port = 0;
if (argc > 2 )
count = atoi(argv[2]);
seq = 1;
while (count--) {
icp = (struct icmphdr *)outpack;
icp->type = ICMP_ECHO;
icp->code = 0;
icp->un.echo.sequence = seq;
icp->un.echo.id = getpid();
icp->checksum = 0;
icp->checksum = in_cksum((u_short *)icp,
sizeof(struct icmphdr), 0);
bytes = sendto(sock, outpack, sizeof(struct icmphdr),
MSG_DONTWAIT, (struct sockaddr *)&dst_addr,
sizeof(dst_addr));
if (bytes < 0)
pexit("sendto");
sleep(1);
len = sizeof(struct sockaddr_in);
bytes = recvfrom(sock, outpack, sizeof(struct iphdr) +
sizeof(struct icmphdr), MSG_DONTWAIT,
(struct sockaddr *)&rcv_addr, &len);
if (bytes < 0) /* I'm ignoring incoming errors */
continue;
ip = (struct iphdr *)outpack;
icp = (struct icmphdr *)&outpack[sizeof(struct iphdr)];
cksum = icp->checksum;
icp->checksum = 0;
icp->checksum = in_cksum((u_short *)icp,
sizeof(struct icmphdr), 0);
if (cksum != icp->checksum) /* and ignoring */
continue; /* corrupted packets */
switch(icp->type) {
case ICMP_ECHOREPLY: /* and repeateds */
if (icp->un.echo.sequence < seq)
continue;
print_iphdr(ip);
print_icmphdr(icp);
putchar('\n');
seq++;
break;
case ICMP_DEST_UNREACH:
printf("Destination unreachable\n");
break;
}
}
return 0;
}
/*
* Taken from iputils/ping.c, at http://www.skbuff.net/iputils/
*/
u_short in_cksum(const u_short *addr, register int len, u_short csum)
{
register int nleft = len;
const u_short *w = addr;
register u_short answer;
register int sum = csum;
/*
* Our algorithm is simple, using a 32 bit accumulator (sum),
* we add sequential 16 bit words to it, and at the end, fold
* back all the carry bits from the top 16 bits into the lower
* 16 bits.
*/
while (nleft > 1) {
sum += *w++;
nleft -= 2;
}
/* mop up an odd byte, if necessary */
if (nleft == 1)
sum += htons(*(u_char *)w << 8);
/*
* add back carry outs from top 16 bits to low 16 bits
*/
sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
sum += (sum >> 16); /* add carry */
answer = ~sum; /* truncate to 16 bits */
return (answer);
}
void print_iphdr(struct iphdr *ip)
{
printf("IP tos=%u id=%u ttl=%u saddr=%s daddr=%s ",
ip->tos, ip->id, ip->ttl, inet_ntoa(ip->saddr),
inet_ntoa(ip->daddr));
}
void print_icmphdr(struct icmphdr *icp)
{
printf("ICMP seq=%d ", icp->un.echo.sequence);
}
quarta-feira, 7 de dezembro de 2011
Ping/ICMP example
I have tried this on my archlinux i686 and works, on arch x86_64 segfaults and I don't no why, I need to work more on this.
Marcadores:
ICMP,
ICMP ECHO,
ICMP example,
Ping example,
ping example in C,
raw socket,
raw sockets,
sockets
terça-feira, 6 de dezembro de 2011
TCP Server Hello World example
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netdb.h>
#define pexit(s) ({perror(s); exit(EXIT_FAILURE);})
#define BUFLEN 0x400
static char buf[BUFLEN];
int main(int argc, char **argv)
{
int srv_sock;
int cli_sock;
int srv_addr_len;
int cli_addr_len;
int error;
int nbytes;
struct sockaddr_in srv_addr;
struct sockaddr_in cli_addr;
if (argc <= 1) {
printf("Usage: %s PORT\n", argv[0]);
exit(EXIT_FAILURE);
}
srv_sock = socket(PF_INET, SOCK_STREAM, 0);
if (srv_sock < 0)
pexit("socket");
srv_addr_len = sizeof(srv_addr);
bzero(&srv_addr, srv_addr_len);
srv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
srv_addr.sin_family = PF_INET;
srv_addr.sin_port = htons(atoi(argv[1]));
error = bind(srv_sock, (struct sockaddr *)&srv_addr, srv_addr_len);
if (error)
pexit("bind");
error = listen(srv_sock, 5);
if (error)
pexit("listen");
cli_addr_len = sizeof(cli_addr);
while ((cli_sock = accept(srv_sock, (struct sockaddr *)&cli_addr,
&cli_addr_len)) != -1)
{
printf("Received connection from %s\n",
inet_ntoa(cli_addr.sin_addr.s_addr));
nbytes = send(cli_sock, "Hello World\n", strlen("Hello World\n"), 0);
if (nbytes == -1)
perror("send");
close(cli_sock);
}
close(srv_sock);
return 0;
}
Marcadores:
AF_INET,
socket,
TCP,
TCP Hello World,
TCP Server,
TCP socket
segunda-feira, 5 de dezembro de 2011
UDP, Server and Client examples
/*
* udpserver.c
*
* UDP Server example
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define pexit(s) ({perror(s); exit(EXIT_FAILURE);})
int main(int argc, char **argv)
{
#define BUFLEN 1000
char buf[BUFLEN];
int sock, error, clilen, bytes;
struct sockaddr_in srv, cli;
if (argc < 2) {
printf("Usage: %s PORT\n", argv[0]);
exit(EXIT_FAILURE);
}
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock == -1)
pexit("socket");
memset(&srv, 0, sizeof(srv));
srv.sin_family = AF_INET;
srv.sin_port = htons(atoi(argv[1]));
srv.sin_addr.s_addr = htonl(INADDR_ANY);
error = bind(sock, (struct sockaddr *)&srv, sizeof(srv));
for (;;) {
clilen = sizeof(cli);
bytes = recvfrom(sock, buf, BUFLEN, 0, (struct sockaddr *)&cli,
&clilen);
if (bytes == -1)
pexit("recvfrom");
printf("received data from %s\n",
inet_ntoa(cli.sin_addr.s_addr));
buf[bytes] = '\0';
printf(">>%s<<\n", buf);
}
return 0;
}
/*
* udpclient.c
*
* UDP client example
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define pexit(s) ({perror(s); exit(EXIT_FAILURE);})
int main(int argc, char **argv)
{
int sock, error, srvlen, bytes;
struct sockaddr_in srv;
if (argc <= 2) {
printf("Usage: %s IP PORT\n", argv[0]);
exit(EXIT_FAILURE);
}
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock == -1)
pexit("socket");
memset(&srv, 0, sizeof(srv));
srv.sin_family = AF_INET;
srv.sin_port = htons(atoi(argv[2]));
srv.sin_addr.s_addr = inet_addr(argv[1]);
bytes = sendto(sock, "Hello World", strlen("Hello World"), 0,
(struct sockaddr *)&srv, sizeof(srv));
if (bytes == -1)
pexit("sendto");
close(sock);
return 0;
}
Marcadores:
c,
UDP,
udp client,
udp examples,
udp server
Assinar:
Comentários (Atom)