sdhcp

simple dhcp client
git clone git://git.2f30.org/sdhcp
Log | Files | Refs | LICENSE

commit 3e2bf1a43fc43b90a8d1bc2ffae62b83b765cb84
parent 45c39c4a1772a01d0d37a26f2a92e3fa2f5a750e
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date:   Fri, 25 Apr 2014 19:26:40 +0200

cleanup (WIP)

- code style, trailing whitespace and use tabs
- add some notes for further cleanup
- remove dbgprintf() code in sdhcp.c
- make exit(n), EXIT_SUCCESS or EXIT_FAILURE

Signed-off-by: Hiltjo Posthuma <hiltjo@codemadness.org>

Diffstat:
Msdhcp.c | 412++++++++++++++++++++++++++++++++++++++++++-------------------------------------
1 file changed, 220 insertions(+), 192 deletions(-)

diff --git a/sdhcp.c b/sdhcp.c @@ -1,97 +1,99 @@ -#include<sys/socket.h> -#include<sys/ioctl.h> -#include<netinet/in.h> -#include<net/if.h> -#include<net/route.h> -#include<signal.h> -#include<poll.h> -#include<errno.h> -#include<fcntl.h> -#include<stdio.h> -#include<stdlib.h> -#include<string.h> +#include <sys/socket.h> +#include <sys/ioctl.h> +#include <netinet/in.h> +#include <net/if.h> +#include <net/route.h> +#include <signal.h> +#include <poll.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> #define MIN(a,b) (((a)<(b))?(a):(b)) -typedef unsigned char uchar; -typedef struct Bootp Bootp; -struct Bootp { - uchar op [1]; - uchar htype [1]; - uchar hlen [1]; - uchar hops [1]; - uchar xid [4]; - uchar secs [2]; - uchar flags [2]; - uchar ciaddr [4]; - uchar yiaddr [4]; - uchar siaddr [4]; - uchar giaddr [4]; - uchar chaddr [16]; - uchar sname [64]; - uchar file [128]; - uchar magic [4]; - uchar optdata [312-4]; -}; -void bpdump(uchar *p, int n); -enum { - DHCPdiscover = 1, DHCPoffer, DHCPrequest, - DHCPdecline, DHCPack, DHCPnak, DHCPrelease, - DHCPinform, Timeout=200, +typedef struct bootp { + unsigned char op [1]; + unsigned char htype [1]; + unsigned char hlen [1]; + unsigned char hops [1]; + unsigned char xid [4]; + unsigned char secs [2]; + unsigned char flags [2]; + unsigned char ciaddr [4]; + unsigned char yiaddr [4]; + unsigned char siaddr [4]; + unsigned char giaddr [4]; + unsigned char chaddr [16]; + unsigned char sname [64]; + unsigned char file [128]; + unsigned char magic [4]; + unsigned char optdata [312-4]; +} Bootp; + +enum { + DHCPdiscover = 1, + DHCPoffer, + DHCPrequest, + DHCPdecline, + DHCPack, + DHCPnak, + DHCPrelease, + DHCPinform, + Timeout = 200, - Bootrequest= 1, - Bootreply= 2, + Bootrequest = 1, + Bootreply = 2, /* bootp flags */ - Fbroadcast= 1<<15, - - OBpad= 0, - OBmask= 1, - OBrouter= 3, - OBnameserver= 5, - OBdnsserver= 6, - OBbaddr= 28, - ODipaddr= 50, /* 0x32 */ - ODlease= 51, - ODoverload= 52, - ODtype= 53, /* 0x35 */ - ODserverid= 54, /* 0x36 */ - ODparams= 55, /* 0x37 */ - ODmessage= 56, - ODmaxmsg= 57, - ODrenewaltime= 58, - ODrebindingtime= 59, - ODvendorclass= 60, - ODclientid= 61, /* 0x3d */ - ODtftpserver= 66, - ODbootfile= 67, - OBend= 255, + Fbroadcast = 1<<15, + + OBpad = 0, + OBmask = 1, + OBrouter = 3, + OBnameserver = 5, + OBdnsserver = 6, + OBbaddr = 28, + ODipaddr = 50, /* 0x32 */ + ODlease = 51, + ODoverload = 52, + ODtype = 53, /* 0x35 */ + ODserverid = 54, /* 0x36 */ + ODparams = 55, /* 0x37 */ + ODmessage = 56, + ODmaxmsg = 57, + ODrenewaltime = 58, + ODrebindingtime = 59, + ODvendorclass = 60, + ODclientid = 61, /* 0x3d */ + ODtftpserver = 66, + ODbootfile = 67, + OBend = 255, }; -enum{ Broadcast, Unicast}; +enum { Broadcast, Unicast}; Bootp bp; -uchar magic[] = {99, 130, 83, 99}; - -//struct conf{ - uchar xid[sizeof bp.xid]; - uchar hwaddr[16]; - time_t starttime; - char *ifname = "eth0"; - char *cid = "vaio.12340"; - int sock; -//} var; -//struct sav{ - uchar server[4]; - uchar client[4]; - uchar mask[4]; - uchar router[4]; - uchar dns[4]; - unsigned long t1; - unsigned long t2; -//} sav; - -#define IP(...) (uchar[4]){__VA_ARGS__} +unsigned char magic[] = {99, 130, 83, 99}; + +/* conf */ +unsigned char xid[sizeof bp.xid]; +unsigned char hwaddr[16]; +time_t starttime; +char *ifname = "eth0"; +char *cid = "vaio.12340"; +int sock; +/* sav */ +unsigned char server[4]; +unsigned char client[4]; +unsigned char mask[4]; +unsigned char router[4]; +unsigned char dns[4]; +unsigned long t1; +unsigned long t2; + +#define IP(...) (unsigned char[4]){__VA_ARGS__} static void die(char *str) @@ -101,25 +103,27 @@ die(char *str) } static void -hnput(uchar *dst, unsigned long long src, int n) +hnput(unsigned char *dst, unsigned long long src, int n) { - int x; - for(x=0; n--; x++) - dst[x] = (src>>(n*8))&0xff; + int i; + + for(i = 0; n--; i++) /* TODO: --n ? */ + dst[i] = (src >> (n * 8)) & 0xff; } static struct sockaddr -iptoaddr(uchar ip[4], int port) +iptoaddr(unsigned char ip[4], int port) { struct sockaddr_in ifaddr; - ifaddr.sin_family=AF_INET; + + ifaddr.sin_family = AF_INET; ifaddr.sin_port = htons(port); memcpy(&ifaddr.sin_addr, ip, sizeof ifaddr.sin_addr); return *(struct sockaddr*)&ifaddr; } #define UDPWRAPPER(name, func, port, hack) \ -static int name(uchar ip[4], int fd, void *data, size_t n){\ +static int name(unsigned char ip[4], int fd, void *data, size_t n){\ struct sockaddr addr = iptoaddr(ip, port);\ int x, y = sizeof addr;\ if((x=func(fd, data, n, 0, &addr, hack y))==-1)\ @@ -130,19 +134,19 @@ UDPWRAPPER(udpsend, sendto, 67, ) UDPWRAPPER(udprecv, recvfrom, 68, &) static void -setip(uchar ip[4], uchar mask[4], uchar gateway[4]) +setip(unsigned char ip[4], unsigned char mask[4], unsigned char gateway[4]) { int fd, x; struct ifreq ifreq = {0,}; struct rtentry rtreq = {0,}; fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); - strcpy(ifreq.ifr_name, ifname); + strcpy(ifreq.ifr_name, ifname); /*TODO: strlcpy */ ifreq.ifr_addr = iptoaddr(ip, 0); ioctl(fd, SIOCSIFADDR , &ifreq); ifreq.ifr_netmask = iptoaddr(mask, 0); ioctl(fd, SIOCSIFNETMASK , &ifreq); - ifreq.ifr_flags=IFF_UP|IFF_RUNNING|IFF_BROADCAST|IFF_MULTICAST; + ifreq.ifr_flags = IFF_UP|IFF_RUNNING|IFF_BROADCAST|IFF_MULTICAST; ioctl(fd, SIOCSIFFLAGS , &ifreq); rtreq.rt_flags = (RTF_UP | RTF_GATEWAY); @@ -153,93 +157,106 @@ setip(uchar ip[4], uchar mask[4], uchar gateway[4]) close(fd); } -static void + +static void cat(int dfd, char *src) { - char buf[4096]; + char buf[4096]; /* TODO: use BUFSIZ ? */ int n, sfd = open(src, O_RDONLY); - while((n=read(sfd, buf, sizeof buf))>0) + + while((n = read(sfd, buf, sizeof buf))>0) write(dfd, buf, n); close(sfd); } -//use itoa not sprintf to make dietlibc happy. -char* itoa(char * str, int x) + +/* use itoa not sprintf to make dietlibc happy. */ +/* TODO: use snprintf(), fuck dietlibc */ +char * +itoa(char * str, int x) { - if(x==0){ + int k = 1; + char *ep = str; + + if(x == 0) { *str='0'; return str+1; } - int k = 1; - char *ep = str; - while(x/k > 0) - k*=10; - while((k/=10)>=1) - *ep++ = '0'+((x/k)%10); - *ep = '\0'; - return str+strlen(str); + while(x / k > 0) + k *= 10; + while((k /= 10) >= 1) + *ep++ = '0' + ((x / k) % 10); + *ep = '\0'; + return str + strlen(str); } + static void -setdns(uchar dns[4]) +setdns(unsigned char dns[4]) { char buf[128], *bp = buf; int fd = creat("/etc/resolv.conf", 0644); + cat(fd, "/etc/resolv.conf.head"); memcpy(buf, "\nnameserver ", 12), bp+=11; - *(bp=itoa(bp+1, dns[0])) = '.'; - *(bp=itoa(bp+1, dns[1])) = '.'; - *(bp=itoa(bp+1, dns[2])) = '.'; - *(bp=itoa(bp+1, dns[3])) = '\n'; + *(bp = itoa(bp+1, dns[0])) = '.'; + *(bp = itoa(bp+1, dns[1])) = '.'; + *(bp = itoa(bp+1, dns[2])) = '.'; + *(bp = itoa(bp+1, dns[3])) = '\n'; *++bp = '\0'; write(fd, buf, strlen(buf)); cat(fd, "/etc/resolv.conf.tail"); close(fd); } -static uchar * +static unsigned char * optget(Bootp *bp, void *data, int opt, int n) { - uchar *p = bp->optdata; - uchar *top = ((uchar*)bp)+sizeof *bp; - while(p<top){ - int code = *p++; - if(code==OBpad) + unsigned char *p = bp->optdata; + unsigned char *top = ((unsigned char *)bp) + sizeof *bp; + int code; + int len; + + while(p < top) { + code = *p++; + if(code == OBpad) continue; - if(code==OBend || p==top) + if(code == OBend || p == top) break; - int len = *p++; + len = *p++; if(len > top-p) break; - if(code==opt){ + if(code == opt) { memcpy(data, p, MIN(len, n)); return p; } - p+=len; + p += len; } } -static uchar * -optput(uchar *p, int opt, uchar *data, int len) +static unsigned char * +optput(unsigned char *p, int opt, unsigned char *data, int len) { *p++ = opt; - *p++ = (uchar)len; + *p++ = (unsigned char)len; memcpy(p, data, len); - return p+len; + return p + len; } -static uchar* -hnoptput(uchar *p, int opt, long long data, int len) + +static unsigned char * +hnoptput(unsigned char *p, int opt, long long data, int len) { - *p++=opt; - *p++ = (uchar)len; + *p++ = opt; + *p++ = (unsigned char)len; hnput(p, data, len); return p+len; } -#include "debug.c" static void dhcpsend(int type, int how) { - dbgprintf("\nSending "); + unsigned char *ip; + unsigned char *p; + memset(&bp, 0, sizeof bp); hnput(bp.op, Bootrequest, 1); hnput(bp.htype, 1, 1); @@ -249,15 +266,15 @@ dhcpsend(int type, int how) hnput(bp.secs, time(NULL)-starttime, sizeof bp.secs); memcpy(bp.magic, magic, sizeof bp.magic); memcpy(bp.chaddr, hwaddr, sizeof bp.chaddr); - uchar *p = bp.optdata; + p = bp.optdata; p = hnoptput(p, ODtype, type, 1); p = optput(p, ODclientid, cid, strlen(cid)); - switch(type){ + switch(type) { case DHCPdiscover: break; case DHCPrequest: -// memcpy(bp.ciaddr, client, sizeof bp.ciaddr); + /* memcpy(bp.ciaddr, client, sizeof bp.ciaddr); */ p = hnoptput(p, ODlease, t1, sizeof t1); p = optput(p, ODipaddr, client, sizeof client); p = optput(p, ODserverid, server, sizeof server); @@ -268,33 +285,37 @@ dhcpsend(int type, int how) p = optput(p, ODserverid, server, sizeof server); break; } - *p++=OBend; - bpdump((void*)&bp, p-(uchar*)&bp); - uchar *ip = (how==Broadcast)?IP(255,255,255,255):server; - udpsend(ip, sock, &bp, p-(uchar*)&bp); + *p++ = OBend; + /* debug */ + /*bpdump((void*)&bp, p - (unsigned char *)&bp);*/ + + ip = (how == Broadcast) ? IP(255,255,255,255) : server; + udpsend(ip, sock, &bp, p - (unsigned char *)&bp); } static int -dhcprecv() +dhcprecv(void) { - dbgprintf("\nReceiving "); + unsigned char type; + int x; + memset(&bp, 0, sizeof bp); - struct pollfd pfd = {sock, POLLIN}; - if(poll(&pfd, 1, -1)==-1){ - if(errno!=EINTR) + struct pollfd pfd = {sock, POLLIN}; /* TODO: not inline */ + if(poll(&pfd, 1, -1) == -1) { + if(errno != EINTR) die("poll"); else return Timeout; } - int x = udprecv(IP(255,255,255,255), sock, &bp, sizeof bp); - bpdump((void*)&bp, x); - uchar type; + x = udprecv(IP(255,255,255,255), sock, &bp, sizeof bp); + /* debug */ + /* bpdump((void*)&bp, x);*/ optget(&bp, &type, ODtype, sizeof type); return type; } static void -acceptlease() +acceptlease(void) { setip(client, mask, router); setdns(dns); @@ -302,37 +323,35 @@ acceptlease() } static void -run() +run(void) { #if 0 InitReboot: - //send DHCPrequest to old server + /* send DHCPrequest to old server */ dhcpsend(DHCPrequest, Broadcasr); goto Rebooting; Rebooting: - switch (dhcprecv()){ + switch (dhcprecv()) { case DHCPnak: goto Init; case DHCPack: acceptoffer(); - goto Bound; + goto Bound; } #endif Init: - dbgprintf("\n\n------- Init ------\n"); dhcpsend(DHCPdiscover, Broadcast); alarm(1); goto Selecting; Selecting: - dbgprintf("\n\n------- Selecting ------\n"); - switch(dhcprecv()){ + switch(dhcprecv()) { case DHCPoffer: alarm(0); memcpy(client, bp.yiaddr, sizeof client); optget(&bp, server, ODserverid, sizeof server); - optget(&bp, mask, OBmask, sizeof mask); - optget(&bp, router, OBrouter, sizeof router); - optget(&bp, dns, OBdnsserver, sizeof dns); + optget(&bp, mask, OBmask, sizeof mask); + optget(&bp, router, OBrouter, sizeof router); + optget(&bp, dns, OBdnsserver, sizeof dns); optget(&bp, &t1, ODlease, sizeof t1); t1 = ntohl(t1); dhcpsend(DHCPrequest, Broadcast); @@ -343,49 +362,47 @@ Selecting: goto Selecting; } Requesting: - dbgprintf("\n\n------- Requesting ------\n"); - switch(dhcprecv()){ + switch(dhcprecv()) { case DHCPoffer: - goto Requesting; //ignore other offers. -// case DHCPack: //(and you don't want it)? -// dhcpsend(DHCPdecline, Unicast); -// goto Init; + goto Requesting; /* ignore other offers. */ +#if 0 + case DHCPack: /* (and you don't want it) ? */ + dhcpsend(DHCPdecline, Unicast); + goto Init; +#endif case DHCPack: acceptlease(); goto Bound; } Bound: - dbgprintf("\n\n------- Bound ------\n"); - write(1, "Congrats! You should be on the 'net.\n", 37); + fputs("Congrats! You should be on the 'net.\n", stdout); if(fork()) - exit(0); - switch (dhcprecv()){ + exit(EXIT_SUCCESS); + switch (dhcprecv()) { case DHCPoffer: case DHCPack: case DHCPnak: - goto Bound; //discard offer, ack, or nak + goto Bound; /* discard offer, ack, or nak */ case Timeout: dhcpsend(DHCPrequest, Unicast); - goto Renewing; + goto Renewing; } Renewing: - dbgprintf("\n\n------- Renewing ------\n"); - switch(dhcprecv()){ + switch(dhcprecv()) { case DHCPack: acceptlease(); goto Bound; case DHCPnak: - //halt network; + /* halt network; */ goto Init; - case Timeout: //t2 expires: + case Timeout: /* t2 expires: */ dhcpsend(DHCPrequest, Broadcast); goto Rebinding; } Rebinding: - dbgprintf("\n\n------- Rebinding ------\n"); - switch(dhcprecv()){ - case DHCPnak: //lease expired - //halt network; + switch(dhcprecv()) { + case DHCPnak: /* lease expired */ + /* halt network; */ goto Init; case DHCPack: acceptlease(); @@ -393,19 +410,31 @@ Rebinding: } } -static void nop(int unused){ } -static void cleanexit(int unused){ +static void nop(int unused) { +} + +static void cleanexit(int unused) { dhcpsend(DHCPrelease, Unicast); - exit(0); + exit(EXIT_SUCCESS); +} + +static void +usage(void) { fputs("usage: sdhcp [interface]\n", stderr); + exit(EXIT_FAILURE); } int main(int argc, char *argv[]) { - if(argc>2){ - exit(EXIT_FAILURE); - }if(argc==2) + int bcast = 1; + struct ifreq ifreq = {0,}; + struct sockaddr addr; + int rnd; + + if(argc > 2) + usage(); + else if(argc == 2) ifname = argv[1]; signal(SIGALRM, nop); @@ -413,24 +442,23 @@ main(int argc, char *argv[]) if((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) die("socket"); - int bcast = 1; if(setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &bcast, sizeof bcast)==-1) die("setsockopt"); - struct ifreq ifreq = {0,}; - strcpy(ifreq.ifr_name, ifname); + + strcpy(ifreq.ifr_name, ifname); /* TODO: strlcpy */ ioctl(sock, SIOCGIFINDEX, &ifreq); if(setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, &ifreq, sizeof ifreq)==-1) die("setsockopt"); - struct sockaddr addr = iptoaddr(IP(255,255,255,255), 68); + addr = iptoaddr(IP(255,255,255,255), 68); if(bind(sock, (void*)&addr, sizeof addr)!=0) die("bind"); ioctl(sock, SIOCGIFHWADDR, &ifreq); memcpy(hwaddr, ifreq.ifr_hwaddr.sa_data, sizeof ifreq.ifr_hwaddr.sa_data); - int rnd = open("/dev/urandom", O_RDONLY); + rnd = open("/dev/urandom", O_RDONLY); read(rnd, xid, sizeof xid); close(rnd); - starttime = time(NULL); + starttime = time(NULL); run(); - return 0; + return EXIT_SUCCESS; }