/* * File: hellolib.c * * Compile: * gcc -Wall -fPIC -c hellolib.c && gcc -shared -Wl -o libhellolib.so hellolib.o * * Calling from lua: * * > hello_lib = package.loadlib("/home/geckos/programming/lua/libhellolib.so", "lua_open_hellolib")() * > * > * > hello_lib.hello_from_c() * Hello from C world to lua * > */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <lua.h> #include <lualib.h> #include <lauxlib.h> static int hello_from_c(lua_State *L) { puts("Hello from C world to lua"); return 0; } static const struct luaL_reg hello_lib[] = { { "hello_from_c", hello_from_c }, { NULL, NULL }, }; int lua_open_hellolib(lua_State *L) { luaL_openlib(L, "hello_lib", hello_lib, 0); return 1; }
quarta-feira, 25 de janeiro de 2012
Creating C libraries/extensions/binds to Lua
I'm training the C API of lua.. planning to create extensions to awesome window manager (the one I use) -> http://awesome.naquadah.org/. Here is a "Lua calling C" hello world.
quinta-feira, 5 de janeiro de 2012
TCP Flooder with pthreads
/** * This code creates N threads. Each threads does one GET to an address. The * GET, the address and the number of threads are passed as argument. An "\r\n" * is appended to the GET string. */ /* headers *//*{{{*/ #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <sys/types.h> #include <pthread.h> #include <netinet/in.h> #include <netinet/ip.h> #include <netdb.h>/*}}}*/ /* declarations and prototypes */ /*{{{*/ #define pexit(s) ({perror(s); exit(exit_failure);}) static struct cstats { int socket_errors; int send_errors; int recv_errors; int connect_errors; int avg_respt; /* average response time */ pthread_mutex_t mutex; } cstats; struct sockaddr_in addr; #define buflen 1024 static char buf[buflen]; static int buf_len; void *get_get_thread(void *);/*}}}*/ int main(int argc, char **argv) { /* main declarations *//*{{{*/ int i; int fail = 0; int ngets; int addr_len; int error; struct hostent *host; pthread_t *threadv; pthread_attr_t attr;/*}}}*/ /* error checking *//*{{{*/ if (argc <= 4) { printf("usage: %s address port number_of_gets get_string\n", argv[0]); exit(exit_failure); } ngets = atoi(argv[3]); if (ngets <= 0) { printf("number_of_gets\n"); errno = einval; exit(exit_failure); } /*}}}*/ bzero(&cstats, sizeof(struct cstats)); /* pthread initialization *//*{{{*/ pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, pthread_create_joinable); pthread_mutex_init(&cstats.mutex, null); threadv = malloc(sizeof(pthread_t) * ngets); if (!threadv) pexit("malloc");/*}}}*/ /* address initialization *//*{{{*/ strncpy(buf, argv[4], buflen); strncat(buf, "\r\n", buflen); host = gethostbyname(argv[1]); if (!host) pexit("gethostbyname"); memcpy(&addr.sin_addr.s_addr, host->h_addr_list[0], sizeof(struct sockaddr_in)); addr.sin_family = pf_inet; addr.sin_port = htons(atoi(argv[2])); /*}}}*/ /* creating threads *//*{{{*/ for (i = 0; i < ngets; i++) { error = pthread_create(&threadv[i], &attr, get_get_thread, null); if (error) fail++; }/*}}}*/ printf("%d thread created. Running...\n", ngets - fail); /* joing threads *//*{{{*/ for (i = 0; i < ngets; i++) { error = pthread_join(threadv[i], null); if (error) perror("pthread_join"); }/*}}}*/ /* output *//*{{{*/ printf("errors:\n" " socket() errors: %d\n" " connect() errors: %d\n" " send() errors: %d\n" " recv() errors: %d\n", cstats.socket_errors, cstats.connect_errors, cstats.send_errors, cstats.recv_errors);/*}}}*/ return 0; } void *get_get_thread(void *dummy)/*{{{*/ { int error; int nbytes; int sock; #define RBUF_LEN 1024 char rbuf[RBUF_LEN]; sock = socket(PF_INET, SOCK_STREAM, 0);/*{{{*/ if (sock < 0) { pthread_mutex_lock(&cstats.mutex); cstats.socket_errors++; pthread_mutex_unlock(&cstats.mutex); }/*}}}*/ error = connect(sock, (struct sockaddr *)&addr, sizeof addr);/*{{{*/ if (error) { pthread_mutex_lock(&cstats.mutex); cstats.connect_errors++; pthread_mutex_unlock(&cstats.mutex); }/*}}}*/ nbytes = send(sock, buf, strlen(buf) , 0);/*{{{*/ if (nbytes == -1) /* error */ { pthread_mutex_lock(&cstats.mutex); cstats.send_errors++; pthread_mutex_unlock(&cstats.mutex); }/*}}}*/ nbytes = recv(sock, rbuf, RBUF_LEN, 0);/*{{{*/ if (nbytes == -1) { pthread_mutex_lock(&cstats.mutex); cstats.recv_errors++; pthread_mutex_unlock(&cstats.mutex); }/*}}}*/ close(sock); return (void *)0; }/*}}}*/ /* vim: set fdm=marker: tw=80 : */
Collectd patch to collect cpu average on linux
I'm using collectd to collectd data at work -> http://www.collectd.org
The cpu plugin don't collectd average cpu usage, I have create a patch to work this around. Here it is
diff -Nurp collectd-5.0.1/src/cpu.c collectd-5.0.1-new/src/cpu.c --- collectd-5.0.1/src/cpu.c 2011-10-14 17:49:49.000000000 -0300 +++ collectd-5.0.1-new/src/cpu.c 2012-01-03 17:48:22.000000000 -0200 @@ -252,7 +252,11 @@ static void submit (int cpu_num, const c vl.values_len = 1; sstrncpy (vl.host, hostname_g, sizeof (vl.host)); sstrncpy (vl.plugin, "cpu", sizeof (vl.plugin)); - ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance), + if (cpu_num < 0) + ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance), + "avg"); + else + ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance), "%i", cpu_num); sstrncpy (vl.type, "cpu", sizeof (vl.type)); sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); @@ -359,6 +363,7 @@ static int cpu_read (void) char *fields[9]; int numfields; + int coren = sysconf(_SC_NPROCESSORS_ONLN); /* number of cores */ if ((fh = fopen ("/proc/stat", "r")) == NULL) { @@ -372,18 +377,24 @@ static int cpu_read (void) { if (strncmp (buf, "cpu", 3)) continue; - if ((buf[3] < '0') || (buf[3] > '9')) - continue; numfields = strsplit (buf, fields, 9); if (numfields < 5) continue; - cpu = atoi (fields[0] + 3); - user = atoll (fields[1]); - nice = atoll (fields[2]); - syst = atoll (fields[3]); - idle = atoll (fields[4]); + if (!isdigit(fields[0][3])) { + cpu = -1; + user = atoll (fields[1]) / coren; + nice = atoll (fields[2]) / coren; + syst = atoll (fields[3]) / coren; + idle = atoll (fields[4]) / coren; + } else { + cpu = atoi (fields[0] + 3); + user = atoll (fields[1]); + nice = atoll (fields[2]); + syst = atoll (fields[3]); + idle = atoll (fields[4]); + } submit (cpu, "user", user); submit (cpu, "nice", nice); @@ -392,9 +403,15 @@ static int cpu_read (void) if (numfields >= 8) { - wait = atoll (fields[5]); - intr = atoll (fields[6]); - sitr = atoll (fields[7]); + if (cpu < 0) { + wait = atoll (fields[5]) / coren; + intr = atoll (fields[6]) / coren; + sitr = atoll (fields[7]) / coren; + } else { + wait = atoll (fields[5]); + intr = atoll (fields[6]); + sitr = atoll (fields[7]); + } submit (cpu, "wait", wait); submit (cpu, "interrupt", intr);
Marcadores:
collectd,
collecting cpu average with collectd,
cpu plugin
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.
/* * 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); }
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
terça-feira, 29 de novembro de 2011
Stress test in C !?
This code will create N threads that take B bytes of memory each and spin forever. Call it whihout arguments to see the usage.
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #define pexit(s) ({perror(s); exit(EXIT_FAILURE);}) static unsigned int sleepi = 0; void *xmalloc(size_t); void *tfunction(void *); int main(int argc, char **argv) { int nthreads; int nbytes; int i; pthread_t *threadv; if (argc <= 2) { printf("Usage: %s NUMBER_OF_THREADS NUMBER_OF_BYTES_PER_THREAD " "[SLEEP_INTERVAL_IN_SECS]\n", argv[0]); exit(EXIT_FAILURE); } nthreads = atoi(argv[1]); nbytes = atoi(argv[2]); if (argc > 3) { sleepi = atoi(argv[3]); } threadv = xmalloc(sizeof(pthread_t) * nthreads); for (i = 0; i < nthreads; i++) { pthread_create(&threadv[i], NULL, tfunction, (void *)&nbytes); } while (1) sleep(~0lu); /* MAX LONG POSSIBLE */ return 0; } void *xmalloc(size_t siz) { void *n = malloc(siz); if (!n) pexit("malloc"); return n; } void *tfunction(void *num) { int i = *(int *)num; while (i--) malloc(1); if (sleepi) while (1) sleep(sleepi); else while (1); }
Assinar:
Postagens (Atom)