1 /* 2 * sock.c (C) 1995-1998 Darren Reed 3 * 4 * See the IPFILTER.LICENCE file for details on licencing. 5 * 6 */ 7 #if !defined(lint) 8 static const char sccsid[] = "@(#)sock.c 1.2 1/11/96 (C)1995 Darren Reed"; 9 static const char rcsid[] = "@(#)$Id$"; 10 #endif 11 #include <sys/param.h> 12 #include <sys/types.h> 13 #include <sys/time.h> 14 #include <sys/stat.h> 15 #if defined(__NetBSD__) && defined(__vax__) 16 /* 17 * XXX need to declare boolean_t for _KERNEL <sys/files.h> 18 * which ends up including <sys/device.h> for vax. See PR#32907 19 * for further details. 20 */ 21 typedef int boolean_t; 22 #endif 23 #include <fcntl.h> 24 # include <sys/dirent.h> 25 # ifdef __NetBSD__ 26 # include <machine/lock.h> 27 # endif 28 # ifdef __FreeBSD__ 29 # define _WANT_FILE 30 # else 31 # define _KERNEL 32 # define KERNEL 33 # endif 34 # include <sys/file.h> 35 # ifdef __FreeBSD__ 36 # undef _WANT_FILE 37 # else 38 # undef _KERNEL 39 # undef KERNEL 40 # endif 41 #include <nlist.h> 42 #include <sys/user.h> 43 #include <sys/socket.h> 44 #define _WANT_SOCKET 45 #include <sys/socketvar.h> 46 #include <sys/proc.h> 47 # include <kvm.h> 48 #ifdef sun 49 #include <sys/systm.h> 50 #include <sys/session.h> 51 #endif 52 #include <sys/sysctl.h> 53 #include <sys/filedesc.h> 54 #include <paths.h> 55 #include <math.h> 56 #include <netinet/in.h> 57 #include <netinet/in_systm.h> 58 #include <netinet/ip.h> 59 #include <netinet/tcp.h> 60 #include <net/if.h> 61 # include <net/route.h> 62 #include <netinet/ip_var.h> 63 #define _WANT_INPCB 64 #include <netinet/in_pcb.h> 65 #include <netinet/tcp_timer.h> 66 #define _WANT_TCPCB 67 #include <netinet/tcp_var.h> 68 #include <stdio.h> 69 #include <unistd.h> 70 #include <string.h> 71 #include <stdlib.h> 72 #include <stddef.h> 73 #include <pwd.h> 74 #include "ipsend.h" 75 76 77 int nproc; 78 struct proc *proc; 79 80 #ifndef KMEM 81 # ifdef _PATH_KMEM 82 # define KMEM _PATH_KMEM 83 # endif 84 #endif 85 #ifndef KERNEL 86 # ifdef _PATH_UNIX 87 # define KERNEL _PATH_UNIX 88 # endif 89 #endif 90 #ifndef KMEM 91 # define KMEM "/dev/kmem" 92 #endif 93 #ifndef KERNEL 94 # define KERNEL "/vmunix" 95 #endif 96 97 98 static struct kinfo_proc *getproc(void); 99 100 101 int 102 kmemcpy(char *buf, void *pos, int n) 103 { 104 static int kfd = -1; 105 off_t offset = (u_long)pos; 106 107 if (kfd == -1) 108 kfd = open(KMEM, O_RDONLY); 109 110 if (lseek(kfd, offset, SEEK_SET) == -1) 111 { 112 perror("lseek"); 113 return (-1); 114 } 115 if (read(kfd, buf, n) == -1) 116 { 117 perror("read"); 118 return (-1); 119 } 120 return (n); 121 } 122 123 struct nlist names[4] = { 124 { "_proc" }, 125 { "_nproc" }, 126 { NULL }, 127 { NULL } 128 }; 129 130 static struct 131 kinfo_proc *getproc(void) 132 { 133 static struct kinfo_proc kp; 134 pid_t pid = getpid(); 135 int mib[4]; 136 size_t n; 137 138 mib[0] = CTL_KERN; 139 mib[1] = KERN_PROC; 140 mib[2] = KERN_PROC_PID; 141 mib[3] = pid; 142 143 n = sizeof(kp); 144 if (sysctl(mib, 4, &kp, &n, NULL, 0) == -1) 145 { 146 perror("sysctl"); 147 return (NULL); 148 } 149 return (&kp); 150 } 151 152 153 struct tcpcb * 154 find_tcp(int tfd, struct tcpiphdr *ti) 155 { 156 struct tcpcb *t; 157 struct inpcb *i; 158 struct socket *s; 159 struct filedesc *fd; 160 struct kinfo_proc *p; 161 struct file *f, **o; 162 163 if (!(p = getproc())) 164 return (NULL); 165 166 fd = (struct filedesc *)malloc(sizeof(*fd)); 167 if (fd == NULL) 168 return (NULL); 169 #if defined( __FreeBSD__) 170 if (KMCPY(fd, p->ki_fd, sizeof(*fd)) == -1) 171 { 172 fprintf(stderr, "read(%#lx,%#lx) failed\n", 173 (u_long)p, (u_long)p->ki_fd); 174 free(fd); 175 return (NULL); 176 } 177 #else 178 if (KMCPY(fd, p->kp_proc.p_fd, sizeof(*fd)) == -1) 179 { 180 fprintf(stderr, "read(%#lx,%#lx) failed\n", 181 (u_long)p, (u_long)p->kp_proc.p_fd); 182 free(fd); 183 return (NULL); 184 } 185 #endif 186 187 o = NULL; 188 f = NULL; 189 s = NULL; 190 i = NULL; 191 t = NULL; 192 193 o = (struct file **)calloc(fd->fd_lastfile + 1, sizeof(*o)); 194 if (KMCPY(o, fd->fd_ofiles, (fd->fd_lastfile + 1) * sizeof(*o)) == -1) 195 { 196 fprintf(stderr, "read(%#lx,%#lx,%lu) - u_ofile - failed\n", 197 (u_long)fd->fd_ofiles, (u_long)o, (u_long)sizeof(*o)); 198 goto finderror; 199 } 200 f = (struct file *)calloc(1, sizeof(*f)); 201 if (KMCPY(f, o[tfd], sizeof(*f)) == -1) 202 { 203 fprintf(stderr, "read(%#lx,%#lx,%lu) - o[tfd] - failed\n", 204 (u_long)o[tfd], (u_long)f, (u_long)sizeof(*f)); 205 goto finderror; 206 } 207 208 s = (struct socket *)calloc(1, sizeof(*s)); 209 if (KMCPY(s, f->f_data, sizeof(*s)) == -1) 210 { 211 fprintf(stderr, "read(%#lx,%#lx,%lu) - f_data - failed\n", 212 (u_long)f->f_data, (u_long)s, (u_long)sizeof(*s)); 213 goto finderror; 214 } 215 216 i = (struct inpcb *)calloc(1, sizeof(*i)); 217 if (KMCPY(i, s->so_pcb, sizeof(*i)) == -1) 218 { 219 fprintf(stderr, "kvm_read(%#lx,%#lx,%lu) - so_pcb - failed\n", 220 (u_long)s->so_pcb, (u_long)i, (u_long)sizeof(*i)); 221 goto finderror; 222 } 223 224 t = (struct tcpcb *)calloc(1, sizeof(*t)); 225 if (KMCPY(t, i->inp_ppcb, sizeof(*t)) == -1) 226 { 227 fprintf(stderr, "read(%#lx,%#lx,%lu) - inp_ppcb - failed\n", 228 (u_long)i->inp_ppcb, (u_long)t, (u_long)sizeof(*t)); 229 goto finderror; 230 } 231 return (struct tcpcb *)i->inp_ppcb; 232 233 finderror: 234 if (o != NULL) 235 free(o); 236 if (f != NULL) 237 free(f); 238 if (s != NULL) 239 free(s); 240 if (i != NULL) 241 free(i); 242 if (t != NULL) 243 free(t); 244 return (NULL); 245 } 246 247 int 248 do_socket(char *dev, int mtu, struct tcpiphdr *ti, struct in_addr gwip) 249 { 250 struct sockaddr_in rsin, lsin; 251 struct tcpcb *t, tcb; 252 int fd, nfd; 253 socklen_t len; 254 255 printf("Dest. Port: %d\n", ti->ti_dport); 256 257 fd = socket(AF_INET, SOCK_STREAM, 0); 258 if (fd == -1) 259 { 260 perror("socket"); 261 return (-1); 262 } 263 264 if (fcntl(fd, F_SETFL, FNDELAY) == -1) 265 { 266 perror("fcntl"); 267 return (-1); 268 } 269 270 bzero((char *)&lsin, sizeof(lsin)); 271 lsin.sin_family = AF_INET; 272 bcopy((char *)&ti->ti_src, (char *)&lsin.sin_addr, 273 sizeof(struct in_addr)); 274 if (bind(fd, (struct sockaddr *)&lsin, sizeof(lsin)) == -1) 275 { 276 perror("bind"); 277 return (-1); 278 } 279 len = sizeof(lsin); 280 (void) getsockname(fd, (struct sockaddr *)&lsin, &len); 281 ti->ti_sport = lsin.sin_port; 282 printf("sport %d\n", ntohs(lsin.sin_port)); 283 284 nfd = initdevice(dev, 1); 285 if (nfd == -1) 286 return (-1); 287 288 if (!(t = find_tcp(fd, ti))) 289 return (-1); 290 291 bzero((char *)&rsin, sizeof(rsin)); 292 rsin.sin_family = AF_INET; 293 bcopy((char *)&ti->ti_dst, (char *)&rsin.sin_addr, 294 sizeof(struct in_addr)); 295 rsin.sin_port = ti->ti_dport; 296 if (connect(fd, (struct sockaddr *)&rsin, sizeof(rsin)) == -1 && 297 errno != EINPROGRESS) 298 { 299 perror("connect"); 300 return (-1); 301 } 302 KMCPY(&tcb, t, sizeof(tcb)); 303 ti->ti_win = tcb.rcv_adv; 304 ti->ti_seq = tcb.snd_nxt - 1; 305 ti->ti_ack = tcb.rcv_nxt; 306 307 if (send_tcp(nfd, mtu, (ip_t *)ti, gwip) == -1) 308 return (-1); 309 (void)write(fd, "Hello World\n", 12); 310 sleep(2); 311 close(fd); 312 return (0); 313 } 314