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