ipsopt.c revision 24583
1139778Simp/* 212115Sdyson * (C)opyright 1995 by Darren Reed. 312115Sdyson * 412115Sdyson * This code may be freely distributed as long as it retains this notice 512115Sdyson * and is not changed in any way. The author accepts no responsibility 612115Sdyson * for the use of this software. I hate legaleese, don't you ? 7139778Simp */ 812115Sdyson#if !defined(lint) && defined(LIBC_SCCS) 912115Sdysonstatic char sccsid[] = "@(#)ipsopt.c 1.2 1/11/96 (C)1995 Darren Reed"; 1031495Sphk#endif 1131495Sphk#include <stdio.h> 1231495Sphk#include <string.h> 1331495Sphk#include <sys/types.h> 1431495Sphk#include <sys/time.h> 1512115Sdyson#include <sys/socket.h> 1612115Sdyson#include <netinet/in.h> 1712115Sdyson#include <netinet/in_systm.h> 1812115Sdyson#include <netinet/ip.h> 1912115Sdyson#include "ip_compat.h" 2012115Sdyson 2112115Sdyson 2212115Sdyson#ifndef __P 2312115Sdyson# ifdef __STDC__ 2412115Sdyson# define __P(x) x 2512115Sdyson# else 2612115Sdyson# define __P(x) () 2712115Sdyson# endif 2812115Sdyson#endif 2912115Sdyson 3012115Sdyson 3112115Sdysonstruct ipopt_names { 3212115Sdyson int on_value; 3312115Sdyson int on_bit; 3412115Sdyson int on_siz; 3512115Sdyson char *on_name; 3612115Sdyson}; 3712115Sdyson 3812115Sdysonstruct ipopt_names ionames[] = { 3912115Sdyson { IPOPT_EOL, 0x01, 1, "eol" }, 4093015Sbde { IPOPT_NOP, 0x02, 1, "nop" }, 4131495Sphk { IPOPT_RR, 0x04, 7, "rr" }, /* 1 route */ 4253101Seivind { IPOPT_TS, 0x08, 8, "ts" }, /* 1 TS */ 4312115Sdyson { IPOPT_SECURITY, 0x08, 11, "sec-level" }, 4412115Sdyson { IPOPT_LSRR, 0x10, 7, "lsrr" }, /* 1 route */ 4531749Seivind { IPOPT_SATID, 0x20, 4, "satid" }, 4631398Sbde { IPOPT_SSRR, 0x40, 7, "ssrr" }, /* 1 route */ 4712115Sdyson { 0, 0, 0, NULL } /* must be last */ 4812115Sdyson}; 4912115Sdyson 5096749Siedowsestruct ipopt_names secnames[] = { 51252956Spfg { IPOPT_SECUR_UNCLASS, 0x0100, 0, "unclass" }, 5212115Sdyson { IPOPT_SECUR_CONFID, 0x0200, 0, "confid" }, 5360041Sphk { IPOPT_SECUR_EFTO, 0x0400, 0, "efto" }, 5412115Sdyson { IPOPT_SECUR_MMMM, 0x0800, 0, "mmmm" }, 55193377Sstas { IPOPT_SECUR_RESTR, 0x1000, 0, "restr" }, 56164033Srwatson { IPOPT_SECUR_SECRET, 0x2000, 0, "secret" }, 57271467Spfg { IPOPT_SECUR_TOPSECRET, 0x4000,0, "topsecret" }, 5812115Sdyson { 0, 0, 0, NULL } /* must be last */ 5996749Siedowse}; 6026641Sbde 6112115Sdyson 6231268Sphku_short seclevel __P((char *)); 6396749Siedowseu_long optname __P((char *, char *)); 6496749Siedowse 6596749Siedowse 6696749Siedowseu_short seclevel(slevel) 67322711Spfgchar *slevel; 6812115Sdyson{ 6912115Sdyson struct ipopt_names *so; 70271467Spfg 71271467Spfg for (so = secnames; so->on_name; so++) 72271467Spfg if (!strcasecmp(slevel, so->on_name)) 73228507Spfg break; 74271467Spfg 7533933Smsmith if (!so->on_name) { 7612115Sdyson fprintf(stderr, "no such security level: %s\n", slevel); 77228507Spfg return 0; 78228507Spfg } 7931268Sphk return so->on_value; 8012115Sdyson} 81221128Sjhb 82202283Slulf 83322711Spfgu_long optname(cp, op) 84202283Slulfchar *cp, *op; 85202283Slulf{ 86221128Sjhb struct ipopt_names *io; 87202283Slulf u_short lvl; 88221128Sjhb u_long msk = 0; 89322711Spfg char *s, *t; 9012115Sdyson int len = 0; 9192728Salfred 92202283Slulf for (s = strtok(cp, ","); s; s = strtok(NULL, ",")) { 93254260Spfg if ((t = strchr(s, '='))) 94254260Spfg *t++ = '\0'; 9531268Sphk for (io = ionames; io->on_name; io++) { 96138270Sphk if (strcasecmp(s, io->on_name) || (msk & io->on_bit)) 9796749Siedowse continue; 9896749Siedowse if ((len + io->on_siz) > 48) { 9996749Siedowse fprintf(stderr, "options too long\n"); 100138270Sphk return 0; 101138270Sphk } 102138270Sphk len += io->on_siz; 103138270Sphk *op++ = io->on_value; 104252956Spfg if (io->on_siz > 1) { 105138270Sphk *op++ = io->on_siz; 106138270Sphk *op++ = IPOPT_MINOFF; 107138270Sphk 108138270Sphk if (t && !strcasecmp(s, "sec-level")) { 109138270Sphk lvl = seclevel(t); 110138270Sphk bcopy(&lvl, op, sizeof(lvl)); 111138270Sphk } 112138270Sphk op += io->on_siz - 3; 113138270Sphk } 114138270Sphk msk |= io->on_bit; 115138270Sphk break; 116138270Sphk } 117138270Sphk if (!io->on_name) { 118138270Sphk fprintf(stderr, "unknown IP option name %s\n", s); 119138270Sphk return 0; 120322711Spfg } 121322711Spfg } 122322711Spfg *op++ = IPOPT_EOL; 123322711Spfg len++; 124166774Spjd return len; 125138270Sphk} 126138270Sphk